sasl_gssapi: Added body to Curl_sasl_create_gssapi_security_message()

This commit is contained in:
Steve Holme 2014-12-05 00:04:42 +00:00
parent 576ac00eb3
commit 7b29c2803f
1 changed files with 122 additions and 6 deletions

View File

@ -31,6 +31,10 @@
#define NCOMPAT 1
#endif
#define GSSAUTH_P_NONE 1
#define GSSAUTH_P_INTEGRITY 2
#define GSSAUTH_P_PRIVACY 4
#include <curl/curl.h>
#include "curl_sasl.h"
@ -207,13 +211,125 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
char **outptr,
size_t *outlen)
{
(void) data;
(void) chlg64;
(void) krb5;
(void) outptr;
(void) outlen;
CURLcode result = CURLE_OK;
size_t chlglen = 0;
size_t messagelen = 0;
unsigned char *chlg = NULL;
unsigned char *message = NULL;
OM_uint32 gss_status;
OM_uint32 gss_major_status;
OM_uint32 gss_minor_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;
gss_qop_t qop = GSS_C_QOP_DEFAULT;
unsigned int sec_layer = 0;
unsigned int max_size = 0;
char user_name[] = "dummy.user"; /* FIX: Use real user name */
return CURLE_NOT_BUILT_IN;
/* Decode the base-64 encoded input message */
if(strlen(chlg64) && *chlg64 != '=') {
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
if(result)
return result;
}
/* Ensure we have a valid challenge message */
if(!chlg) {
infof(data, "GSSAPI handshake failure (empty security message)\n");
return CURLE_BAD_CONTENT_ENCODING;
}
/* Setup the challenge "input" security buffer */
input_token.value = chlg;
input_token.length = chlglen;
/* Decrypt the inbound challenge and obtain the qop */
gss_major_status = gss_unwrap(&gss_minor_status, krb5->context, &input_token,
&output_token, NULL, &qop);
if(GSS_ERROR(gss_major_status)) {
Curl_gss_log_error(data, gss_minor_status, "gss_unwrap() failed: ");
Curl_safefree(chlg);
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)\n");
Curl_safefree(chlg);
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);
gss_release_buffer(&gss_status, &output_token);
Curl_safefree(chlg);
/* Extract the security layer */
sec_layer = indata & 0x000000FF;
if(!(sec_layer & GSSAUTH_P_NONE)) {
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
return CURLE_BAD_CONTENT_ENCODING;
}
/* Extract the maximum message size the server can receive */
max_size = ntohl(indata & 0xFFFFFF00);
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
our receive buffer is zero. */
max_size = 0;
}
/* Allocate our message */
messagelen = sizeof(outdata) + strlen(user_name) + 1;
message = malloc(messagelen);
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: Dispite 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));
strcpy((char *) message + sizeof(outdata), user_name);
/* Setup the "authentication data" security buffer */
input_token.value = message;
input_token.length = messagelen;
/* Encrypt the data */
gss_major_status = gss_wrap(&gss_minor_status, krb5->context, 0,
GSS_C_QOP_DEFAULT, &input_token, NULL,
&output_token);
if(GSS_ERROR(gss_major_status)) {
Curl_gss_log_error(data, gss_minor_status, "gss_wrap() failed: ");
Curl_safefree(message);
return CURLE_OUT_OF_MEMORY;
}
/* Base64 encode the response */
result = Curl_base64_encode(data, (char *) output_token.value,
output_token.length, outptr, outlen);
/* Free the output buffer */
gss_release_buffer(&gss_status, &output_token);
/* Free the message buffer */
Curl_safefree(message);
return result;
}
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)