diff options
author | Patrick Monnerat <patrick@monnerat.net> | 2021-08-16 08:35:22 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-08-16 08:36:06 +0200 |
commit | 396a2d7fe3b9d10acfd69656490efd0dbbefc7b0 (patch) | |
tree | c3568f86aadd444008b1637fc1845cc12cf45085 /lib | |
parent | 0a1c85e39b0fcbfd67a185af63133de485560ee0 (diff) | |
download | curl-396a2d7fe3b9d10acfd69656490efd0dbbefc7b0.tar.gz |
auth: use sasl authzid option in kerberos
... instead of deriving it from active ticket.
Closes #7008
Diffstat (limited to 'lib')
-rw-r--r-- | lib/curl_sasl.c | 8 | ||||
-rw-r--r-- | lib/vauth/krb5_gssapi.c | 52 | ||||
-rw-r--r-- | lib/vauth/krb5_sspi.c | 47 | ||||
-rw-r--r-- | lib/vauth/vauth.h | 1 |
4 files changed, 38 insertions, 70 deletions
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index f5ac99a68..4a2488720 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -630,7 +630,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, } else /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, &serverdata, + result = Curl_auth_create_gssapi_security_message(data, + conn->sasl_authzid, + &serverdata, &conn->krb5, &resp); } @@ -639,7 +641,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, /* Decode the security challenge and create the response message */ result = get_server_message(sasl, data, &serverdata); if(!result) - result = Curl_auth_create_gssapi_security_message(data, &serverdata, + result = Curl_auth_create_gssapi_security_message(data, + conn->sasl_authzid, + &serverdata, &conn->krb5, &resp); break; diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c index ea4995c72..5c126eb59 100644 --- a/lib/vauth/krb5_gssapi.c +++ b/lib/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) @@ -193,8 +195,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, 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)) { @@ -202,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); @@ -231,14 +212,12 @@ 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; } @@ -254,7 +233,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, 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 */ @@ -268,27 +246,27 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, } /* Allocate our message */ - messagelen = 4 + username_token.length + 1; + messagelen = 4; + if(authzid && *authzid) + messagelen += strlen(authzid) + 1; 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. */ + /* 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; - memcpy(message + 4, 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); + /* If given, append the 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. */ + + if(authzid && *authzid) + strcpy((char *) message + 4, authzid); /* Setup the "authentication data" security buffer */ input_token.value = message; diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c index 08644d79c..2e6368871 100644 --- a/lib/vauth/krb5_sspi.c +++ b/lib/vauth/krb5_sspi.c @@ -238,13 +238,15 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, * Parameters: * * data [in] - The session handle. - * chlg [in] - The optional challenge message. + * authzid [in] - The authorization identity if some. + * chlg [in] - The optional challenge message. * krb5 [in/out] - The Kerberos 5 data struct being used and modified. * out [out] - The result storage. * * 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) @@ -265,9 +267,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, unsigned long sec_layer = 0; unsigned long max_size = 0; SecPkgContext_Sizes sizes; - SecPkgCredentials_Names names; SECURITY_STATUS status; - char *user_name; #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; @@ -290,17 +290,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(status != SEC_E_OK) return CURLE_AUTH_ERROR; - /* Get the fully qualified username back from the context */ - status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials, - SECPKG_CRED_ATTR_NAMES, - &names); - - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; - - if(status != SEC_E_OK) - return CURLE_AUTH_ERROR; - /* Setup the "input" security buffer */ input_desc.ulVersion = SECBUFFER_VERSION; input_desc.cBuffers = 2; @@ -353,35 +342,31 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(!trailer) return CURLE_OUT_OF_MEMORY; - /* Convert the user name to UTF8 when operating with Unicode */ - user_name = curlx_convert_tchar_to_UTF8(names.sUserName); - if(!user_name) { - free(trailer); - - return CURLE_OUT_OF_MEMORY; - } - /* Allocate our message */ - messagelen = 4 + strlen(user_name) + 1; + messagelen = 4; + if(authzid && *authzid) + messagelen += strlen(authzid) + 1; message = malloc(messagelen); if(!message) { free(trailer); - curlx_unicodefree(user_name); 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. */ + /* 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; - strcpy((char *) message + 4, user_name); - curlx_unicodefree(user_name); + + /* If given, append the 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. */ + + if(authzid && *authzid) + strcpy((char *) message + 4, authzid); /* Allocate the padding */ padding = malloc(sizes.cbBlockSize); diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h index ec5b0007f..47a7c0bc8 100644 --- a/lib/vauth/vauth.h +++ b/lib/vauth/vauth.h @@ -194,6 +194,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, /* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security token message */ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, + const char *authzid, const struct bufref *chlg, struct kerberos5data *krb5, struct bufref *out); |