summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vauth/krb5_gssapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/vauth/krb5_gssapi.c')
-rw-r--r--libs/libcurl/src/vauth/krb5_gssapi.c76
1 files changed, 27 insertions, 49 deletions
diff --git a/libs/libcurl/src/vauth/krb5_gssapi.c b/libs/libcurl/src/vauth/krb5_gssapi.c
index fee24ee470..67d43bd567 100644
--- a/libs/libcurl/src/vauth/krb5_gssapi.c
+++ b/libs/libcurl/src/vauth/krb5_gssapi.c
@@ -170,6 +170,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
* Parameters:
*
* data [in] - The session handle.
+ * authzid [in] - The authorization identity if some.
* chlg [in] - Optional challenge message.
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
* out [out] - The result storage.
@@ -177,6 +178,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
* Returns CURLE_OK on success.
*/
CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
+ const char *authzid,
const struct bufref *chlg,
struct kerberos5data *krb5,
struct bufref *out)
@@ -189,13 +191,10 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
OM_uint32 unused_status;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
- unsigned int indata = 0;
- unsigned int outdata = 0;
+ unsigned char *indata;
gss_qop_t qop = GSS_C_QOP_DEFAULT;
unsigned int sec_layer = 0;
unsigned int max_size = 0;
- gss_name_t username = GSS_C_NO_NAME;
- gss_buffer_desc username_token;
/* Ensure we have a valid challenge message */
if(!Curl_bufref_len(chlg)) {
@@ -203,25 +202,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
return CURLE_BAD_CONTENT_ENCODING;
}
- /* Get the fully qualified username back from the context */
- major_status = gss_inquire_context(&minor_status, krb5->context,
- &username, NULL, NULL, NULL, NULL,
- NULL, NULL);
- if(GSS_ERROR(major_status)) {
- Curl_gss_log_error(data, "gss_inquire_context() failed: ",
- major_status, minor_status);
- return CURLE_AUTH_ERROR;
- }
-
- /* Convert the username from internal format to a displayable token */
- major_status = gss_display_name(&minor_status, username,
- &username_token, NULL);
- if(GSS_ERROR(major_status)) {
- Curl_gss_log_error(data, "gss_display_name() failed: ",
- major_status, minor_status);
- return CURLE_AUTH_ERROR;
- }
-
/* Setup the challenge "input" security buffer */
input_token.value = (void *) Curl_bufref_ptr(chlg);
input_token.length = Curl_bufref_len(chlg);
@@ -232,32 +212,32 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
if(GSS_ERROR(major_status)) {
Curl_gss_log_error(data, "gss_unwrap() failed: ",
major_status, minor_status);
- gss_release_buffer(&unused_status, &username_token);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
if(output_token.length != 4) {
infof(data, "GSSAPI handshake failure (invalid security data)");
- gss_release_buffer(&unused_status, &username_token);
return CURLE_BAD_CONTENT_ENCODING;
}
- /* Copy the data out and free the challenge as it is not required anymore */
- memcpy(&indata, output_token.value, 4);
+ /* Extract the security layer and the maximum message size */
+ indata = output_token.value;
+ sec_layer = indata[0];
+ max_size = (indata[1] << 16) | (indata[2] << 8) | indata[3];
+
+ /* Free the challenge as it is not required anymore */
gss_release_buffer(&unused_status, &output_token);
- /* Extract the security layer */
- sec_layer = indata & 0x000000FF;
+ /* Process the security layer */
if(!(sec_layer & GSSAUTH_P_NONE)) {
infof(data, "GSSAPI handshake failure (invalid security layer)");
- gss_release_buffer(&unused_status, &username_token);
return CURLE_BAD_CONTENT_ENCODING;
}
+ sec_layer &= GSSAUTH_P_NONE; /* We do not support a security layer */
- /* Extract the maximum message size the server can receive */
- max_size = ntohl(indata & 0xFFFFFF00);
+ /* Process the maximum message size the server can receive */
if(max_size > 0) {
/* The server has told us it supports a maximum receive buffer, however, as
we don't require one unless we are encrypting data, we tell the server
@@ -266,26 +246,24 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
}
/* Allocate our message */
- messagelen = sizeof(outdata) + username_token.length + 1;
+ messagelen = 4;
+ if(authzid)
+ messagelen += strlen(authzid);
message = malloc(messagelen);
- if(!message) {
- gss_release_buffer(&unused_status, &username_token);
+ if(!message)
return CURLE_OUT_OF_MEMORY;
- }
- /* Populate the message with the security layer, client supported receive
- message size and authorization identity including the 0x00 based
- terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization
- identity is not terminated with the zero-valued (%x00) octet." it seems
- necessary to include it. */
- outdata = htonl(max_size) | sec_layer;
- memcpy(message, &outdata, sizeof(outdata));
- memcpy(message + sizeof(outdata), username_token.value,
- username_token.length);
- message[messagelen - 1] = '\0';
-
- /* Free the username token as it is not required anymore */
- gss_release_buffer(&unused_status, &username_token);
+ /* Populate the message with the security layer and client supported receive
+ message size. */
+ message[0] = sec_layer & 0xFF;
+ message[1] = (max_size >> 16) & 0xFF;
+ message[2] = (max_size >> 8) & 0xFF;
+ message[3] = max_size & 0xFF;
+
+ /* If given, append the authorization identity. */
+
+ if(authzid && *authzid)
+ memcpy(message + 4, authzid, messagelen - 4);
/* Setup the "authentication data" security buffer */
input_token.value = message;