* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
+ * Copyright (C) 2014 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2014, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
#include "urldata.h"
#include "curl_base64.h"
#include "warnless.h"
-#include "curl_memory.h"
#include "curl_multibyte.h"
#include "sendf.h"
#include "strdup.h"
+#include "curl_printf.h"
+#include "rawstr.h"
-#define _MPRINTF_REPLACE /* use our functions only */
-#include <curl/mprintf.h>
-
-/* The last #include file should be: */
+/* The last #include files should be: */
+#include "curl_memory.h"
#include "memdebug.h"
/*
/* Allocate our TCHAR based SPN */
tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
if(!tchar_spn) {
- Curl_safefree(utf8_spn);
+ free(utf8_spn);
return NULL;
}
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
&SecurityPackage);
if(status != SEC_E_OK) {
- Curl_safefree(input_token);
+ free(input_token);
return CURLE_NOT_BUILT_IN;
}
/* Allocate our response buffer */
output_token = malloc(token_max);
if(!output_token) {
- Curl_safefree(input_token);
+ free(input_token);
return CURLE_OUT_OF_MEMORY;
}
/* Generate our SPN */
spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
if(!spn) {
- Curl_safefree(output_token);
- Curl_safefree(input_token);
+ free(output_token);
+ free(input_token);
return CURLE_OUT_OF_MEMORY;
}
/* Populate our identity structure */
result = Curl_create_sspi_identity(userp, passwdp, &identity);
if(result) {
- Curl_safefree(spn);
- Curl_safefree(output_token);
- Curl_safefree(input_token);
+ free(spn);
+ free(output_token);
+ free(input_token);
return result;
}
if(status != SEC_E_OK) {
Curl_sspi_free_identity(p_identity);
- Curl_safefree(spn);
- Curl_safefree(output_token);
- Curl_safefree(input_token);
+ free(spn);
+ free(output_token);
+ free(input_token);
return CURLE_LOGIN_DENIED;
}
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
s_pSecFn->FreeCredentialsHandle(&credentials);
Curl_sspi_free_identity(p_identity);
- Curl_safefree(spn);
- Curl_safefree(output_token);
- Curl_safefree(input_token);
+ free(spn);
+ free(output_token);
+ free(input_token);
return CURLE_RECV_ERROR;
}
Curl_sspi_free_identity(p_identity);
/* Free the SPN */
- Curl_safefree(spn);
+ free(spn);
/* Free the response buffer */
- Curl_safefree(output_token);
+ free(output_token);
/* Free the decoded challenge message */
- Curl_safefree(input_token);
+ free(input_token);
return result;
}
/*
+* Curl_override_sspi_http_realm()
+*
+* This is used to populate the domain in a SSPI identity structure
+* The realm is extracted from the challenge message and used as the
+* domain if it is not already explicitly set.
+*
+* Parameters:
+*
+* chlg [in] - The challenge message.
+* identity [in/out] - The identity structure.
+*
+* Returns CURLE_OK on success.
+*/
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+ SEC_WINNT_AUTH_IDENTITY *identity)
+{
+ xcharp_u domain, dup_domain;
+
+ /* If domain is blank or unset, check challenge message for realm */
+ if(!identity->Domain || !identity->DomainLength) {
+ for(;;) {
+ char value[DIGEST_MAX_VALUE_LENGTH];
+ char content[DIGEST_MAX_CONTENT_LENGTH];
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Extract a value=content pair */
+ if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
+ if(Curl_raw_equal(value, "realm")) {
+
+ /* Setup identity's domain and length */
+ domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
+ if(!domain.tchar_ptr)
+ return CURLE_OUT_OF_MEMORY;
+ dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
+ if(!dup_domain.tchar_ptr) {
+ Curl_unicodefree(domain.tchar_ptr);
+ return CURLE_OUT_OF_MEMORY;
+ }
+ identity->Domain = dup_domain.tbyte_ptr;
+ identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
+ dup_domain.tchar_ptr = NULL;
+
+ Curl_unicodefree(domain.tchar_ptr);
+ }
+ else {
+ /* unknown specifier, ignore it! */
+ }
+ }
+ else
+ break; /* we're done here */
+
+ /* Pass all additional spaces here */
+ while(*chlg && ISSPACE(*chlg))
+ chlg++;
+
+ /* Allow the list to be comma-separated */
+ if(',' == *chlg)
+ chlg++;
+ }
+ }
+
+ return CURLE_OK;
+}
+
+/*
* Curl_sasl_decode_digest_http_message()
*
* This is used to decode a HTTP DIGEST challenge message into the seperate
if(Curl_create_sspi_identity(userp, passwdp, &identity))
return CURLE_OUT_OF_MEMORY;
+ /* Populate our identity domain */
+ if(Curl_override_sspi_http_realm((const char*)digest->input_token,
+ &identity))
+ return CURLE_OUT_OF_MEMORY;
+
/* Allow proper cleanup of the identity structure */
p_identity = &identity;
}
p_identity, NULL, NULL,
&credentials, &expiry);
if(status != SEC_E_OK) {
- Curl_safefree(output_token);
+ free(output_token);
return CURLE_LOGIN_DENIED;
}
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
s_pSecFn->FreeCredentialsHandle(&credentials);
- Curl_safefree(output_token);
+ free(output_token);
return CURLE_OUT_OF_MEMORY;
}
s_pSecFn->DeleteSecurityContext(&context);
s_pSecFn->FreeCredentialsHandle(&credentials);
- Curl_safefree(output_token);
+ free(output_token);
return CURLE_OUT_OF_MEMORY;
}
Curl_sspi_free_identity(p_identity);
/* Free the response buffer */
- Curl_safefree(output_token);
+ free(output_token);
return CURLE_OK;
}
&expiry);
if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
- Curl_safefree(chlg);
+ free(chlg);
return CURLE_RECV_ERROR;
}
}
/* Free the decoded challenge */
- Curl_safefree(chlg);
+ free(chlg);
return result;
}
SECPKG_ATTR_SIZES,
&sizes);
if(status != SEC_E_OK) {
- Curl_safefree(chlg);
+ free(chlg);
return CURLE_OUT_OF_MEMORY;
}
SECPKG_CRED_ATTR_NAMES,
&names);
if(status != SEC_E_OK) {
- Curl_safefree(chlg);
+ free(chlg);
return CURLE_RECV_ERROR;
}
if(status != SEC_E_OK) {
infof(data, "GSSAPI handshake failure (empty security message)\n");
- Curl_safefree(chlg);
+ free(chlg);
return CURLE_BAD_CONTENT_ENCODING;
}
if(input_buf[1].cbBuffer != 4) {
infof(data, "GSSAPI handshake failure (invalid security data)\n");
- Curl_safefree(chlg);
+ free(chlg);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Copy the data out and free the challenge as it is not required anymore */
memcpy(&indata, input_buf[1].pvBuffer, 4);
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
- Curl_safefree(chlg);
+ free(chlg);
/* Extract the security layer */
sec_layer = indata & 0x000000FF;
/* Convert the user name to UTF8 when operating with Unicode */
user_name = Curl_convert_tchar_to_UTF8(names.sUserName);
if(!user_name) {
- Curl_safefree(trailer);
+ free(trailer);
return CURLE_OUT_OF_MEMORY;
}
messagelen = sizeof(outdata) + strlen(user_name) + 1;
message = malloc(messagelen);
if(!message) {
- Curl_safefree(trailer);
+ free(trailer);
Curl_unicodefree(user_name);
return CURLE_OUT_OF_MEMORY;
/* Allocate the padding */
padding = malloc(sizes.cbBlockSize);
if(!padding) {
- Curl_safefree(message);
- Curl_safefree(trailer);
+ free(message);
+ free(trailer);
return CURLE_OUT_OF_MEMORY;
}
status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
&wrap_desc, 0);
if(status != SEC_E_OK) {
- Curl_safefree(padding);
- Curl_safefree(message);
- Curl_safefree(trailer);
+ free(padding);
+ free(message);
+ free(trailer);
return CURLE_OUT_OF_MEMORY;
}
wrap_buf[2].cbBuffer;
appdata = malloc(appdatalen);
if(!appdata) {
- Curl_safefree(padding);
- Curl_safefree(message);
- Curl_safefree(trailer);
+ free(padding);
+ free(message);
+ free(trailer);
return CURLE_OUT_OF_MEMORY;
}
outlen);
/* Free all of our local buffers */
- Curl_safefree(appdata);
- Curl_safefree(padding);
- Curl_safefree(message);
- Curl_safefree(trailer);
+ free(appdata);
+ free(padding);
+ free(message);
+ free(trailer);
return result;
}