auth: properly handle byte order in kerberos security message

Closes #7008
This commit is contained in:
Patrick Monnerat 2021-08-16 08:35:22 +02:00 committed by Daniel Stenberg
parent 5f3ca7f773
commit 3f9b1d0c9d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 30 additions and 25 deletions

View File

@ -189,8 +189,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
OM_uint32 unused_status; OM_uint32 unused_status;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
unsigned int indata = 0; unsigned char *indata;
unsigned int outdata = 0;
gss_qop_t qop = GSS_C_QOP_DEFAULT; gss_qop_t qop = GSS_C_QOP_DEFAULT;
unsigned int sec_layer = 0; unsigned int sec_layer = 0;
unsigned int max_size = 0; unsigned int max_size = 0;
@ -243,12 +242,15 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
return CURLE_BAD_CONTENT_ENCODING; return CURLE_BAD_CONTENT_ENCODING;
} }
/* Copy the data out and free the challenge as it is not required anymore */ /* Extract the security layer and the maximum message size */
memcpy(&indata, output_token.value, 4); 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); gss_release_buffer(&unused_status, &output_token);
/* Extract the security layer */ /* Process the security layer */
sec_layer = indata & 0x000000FF;
if(!(sec_layer & GSSAUTH_P_NONE)) { if(!(sec_layer & GSSAUTH_P_NONE)) {
infof(data, "GSSAPI handshake failure (invalid security layer)"); infof(data, "GSSAPI handshake failure (invalid security layer)");
@ -256,8 +258,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
return CURLE_BAD_CONTENT_ENCODING; return CURLE_BAD_CONTENT_ENCODING;
} }
/* Extract the maximum message size the server can receive */ /* Process the maximum message size the server can receive */
max_size = ntohl(indata & 0xFFFFFF00);
if(max_size > 0) { if(max_size > 0) {
/* The server has told us it supports a maximum receive buffer, however, as /* 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 we don't require one unless we are encrypting data, we tell the server
@ -266,7 +267,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
} }
/* Allocate our message */ /* Allocate our message */
messagelen = sizeof(outdata) + username_token.length + 1; messagelen = 4 + username_token.length + 1;
message = malloc(messagelen); message = malloc(messagelen);
if(!message) { if(!message) {
gss_release_buffer(&unused_status, &username_token); gss_release_buffer(&unused_status, &username_token);
@ -278,10 +279,11 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization
identity is not terminated with the zero-valued (%x00) octet." it seems identity is not terminated with the zero-valued (%x00) octet." it seems
necessary to include it. */ necessary to include it. */
outdata = htonl(max_size) | sec_layer; message[0] = sec_layer & 0xFF;
memcpy(message, &outdata, sizeof(outdata)); message[1] = (max_size >> 16) & 0xFF;
memcpy(message + sizeof(outdata), username_token.value, message[2] = (max_size >> 8) & 0xFF;
username_token.length); message[3] = max_size & 0xFF;
memcpy(message + 4, username_token.value, username_token.length);
message[messagelen - 1] = '\0'; message[messagelen - 1] = '\0';
/* Free the username token as it is not required anymore */ /* Free the username token as it is not required anymore */

View File

@ -260,8 +260,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
SecBuffer wrap_buf[3]; SecBuffer wrap_buf[3];
SecBufferDesc input_desc; SecBufferDesc input_desc;
SecBufferDesc wrap_desc; SecBufferDesc wrap_desc;
unsigned long indata = 0; unsigned char *indata;
unsigned long outdata = 0;
unsigned long qop = 0; unsigned long qop = 0;
unsigned long sec_layer = 0; unsigned long sec_layer = 0;
unsigned long max_size = 0; unsigned long max_size = 0;
@ -326,19 +325,21 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
return CURLE_BAD_CONTENT_ENCODING; return CURLE_BAD_CONTENT_ENCODING;
} }
/* Copy the data out and free the challenge as it is not required anymore */ /* Extract the security layer and the maximum message size */
memcpy(&indata, input_buf[1].pvBuffer, 4); indata = input_buf[1].pvBuffer;
sec_layer = indata[0];
max_size = (indata[1] << 16) | (indata[2] << 8) | indata[3];
/* Free the challenge as it is not required anymore */
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
/* Extract the security layer */ /* Process the security layer */
sec_layer = indata & 0x000000FF;
if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
infof(data, "GSSAPI handshake failure (invalid security layer)"); infof(data, "GSSAPI handshake failure (invalid security layer)");
return CURLE_BAD_CONTENT_ENCODING; return CURLE_BAD_CONTENT_ENCODING;
} }
/* Extract the maximum message size the server can receive */ /* Process the maximum message size the server can receive */
max_size = ntohl(indata & 0xFFFFFF00);
if(max_size > 0) { if(max_size > 0) {
/* The server has told us it supports a maximum receive buffer, however, as /* 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 we don't require one unless we are encrypting data, we tell the server
@ -360,7 +361,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
} }
/* Allocate our message */ /* Allocate our message */
messagelen = sizeof(outdata) + strlen(user_name) + 1; messagelen = 4 + strlen(user_name) + 1;
message = malloc(messagelen); message = malloc(messagelen);
if(!message) { if(!message) {
free(trailer); free(trailer);
@ -374,9 +375,11 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization
identity is not terminated with the zero-valued (%x00) octet." it seems identity is not terminated with the zero-valued (%x00) octet." it seems
necessary to include it. */ necessary to include it. */
outdata = htonl(max_size) | sec_layer; message[0] = sec_layer & 0xFF;
memcpy(message, &outdata, sizeof(outdata)); message[1] = (max_size >> 16) & 0xFF;
strcpy((char *) message + sizeof(outdata), user_name); message[2] = (max_size >> 8) & 0xFF;
message[3] = max_size & 0xFF;
strcpy((char *) message + 4, user_name);
curlx_unicodefree(user_name); curlx_unicodefree(user_name);
/* Allocate the padding */ /* Allocate the padding */