auth: use sasl authzid option in kerberos
... instead of deriving it from active ticket. Closes #7008
This commit is contained in:
Родитель
0a1c85e39b
Коммит
396a2d7fe3
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче