Merge pull request #1803 from hardening/www_authenticate_fix

Www authenticate fix
This commit is contained in:
Marc-André Moreau 2014-04-21 12:15:35 -04:00
commit a21aed8896
3 changed files with 73 additions and 62 deletions

View File

@ -345,51 +345,38 @@ BOOL http_response_parse_header_field(HttpResponse* http_response, char* name, c
{
http_response->ContentLength = atoi(value);
}
else if (_stricmp(name, "Authorization") == 0)
{
char* separator;
http_response->Authorization = _strdup(value);
if (!http_response->Authorization)
return FALSE;
separator = strchr(value, ' ');
if (separator != NULL)
{
*separator = '\0';
http_response->AuthScheme = _strdup(value);
http_response->AuthParam = _strdup(separator + 1);
if (!http_response->AuthScheme || !http_response->AuthParam)
return FALSE;
*separator = ' ';
}
}
else if (_stricmp(name, "WWW-Authenticate") == 0)
{
char* separator;
separator = strstr(value, "=\"");
if (separator != NULL)
{
/* WWW-Authenticate: parameter with spaces="value" */
return FALSE;
}
char *authScheme, *authValue;
separator = strchr(value, ' ');
if (separator != NULL)
{
/* WWW-Authenticate: NTLM base64token */
/* WWW-Authenticate: Basic realm=""
* WWW-Authenticate: NTLM base64token
* WWW-Authenticate: Digest realm="testrealm@host.com", qop="auth, auth-int",
* nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
* opaque="5ccc069c403ebaf9f0171e9517f40e41"
*/
*separator = '\0';
http_response->AuthScheme = _strdup(value);
http_response->AuthParam = _strdup(separator + 1);
*separator = ' ';
return TRUE;
authScheme = _strdup(value);
authValue = _strdup(separator + 1);
if (!authScheme || !authValue)
return FALSE;
*separator = ' ';
}
else
{
authScheme = _strdup(value);
if (!authScheme)
return FALSE;
authValue = NULL;
}
return ListDictionary_Add(http_response->Authenticates, authScheme, authValue);
}
return TRUE;
}
@ -594,31 +581,53 @@ out_free:
return NULL;
}
static BOOL strings_equals_nocase(void *obj1, void *obj2)
{
if (!obj1 || !obj2)
return FALSE;
return _stricmp(obj1, obj2) == 0;
}
static void string_free(void *obj1)
{
if (!obj1)
return;
free(obj1);
}
HttpResponse* http_response_new()
{
return (HttpResponse *)calloc(1, sizeof(HttpResponse));
HttpResponse *ret = (HttpResponse *)calloc(1, sizeof(HttpResponse));
if (!ret)
return NULL;
ret->Authenticates = ListDictionary_New(FALSE);
ListDictionary_KeyObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
ListDictionary_KeyObject(ret->Authenticates)->fnObjectFree = string_free;
ListDictionary_ValueObject(ret->Authenticates)->fnObjectEquals = strings_equals_nocase;
ListDictionary_ValueObject(ret->Authenticates)->fnObjectFree = string_free;
return ret;
}
void http_response_free(HttpResponse* http_response)
{
int i;
if (http_response != NULL)
{
for (i = 0; i < http_response->count; i++)
free(http_response->lines[i]);
if (!http_response)
return;
free(http_response->lines);
for (i = 0; i < http_response->count; i++)
free(http_response->lines[i]);
free(http_response->ReasonPhrase);
free(http_response->lines);
free(http_response->AuthParam);
free(http_response->AuthScheme);
free(http_response->Authorization);
free(http_response->ReasonPhrase);
if (http_response->ContentLength > 0)
free(http_response->Content);
ListDictionary_Free(http_response->Authenticates);
free(http_response);
}
if (http_response->ContentLength > 0)
free(http_response->Content);
free(http_response);
}

View File

@ -82,9 +82,7 @@ struct _http_response
int StatusCode;
char* ReasonPhrase;
char* AuthScheme;
char* AuthParam;
char* Authorization;
wListDictionary *Authenticates;
int ContentLength;
char* Content;
};

View File

@ -92,23 +92,27 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc)
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc)
{
int ntlm_token_length;
BYTE* ntlm_token_data;
int ntlm_token_length = 0;
BYTE* ntlm_token_data = NULL;
HttpResponse* http_response;
rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm;
http_response = http_response_recv(rpc->TlsIn);
if (http_response->AuthParam)
if (ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{
ntlm_token_data = NULL;
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
if (!token64)
goto out;
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
ntlm_token_data = NULL;
crypto_base64_decode((BYTE*) token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
}
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;
ntlm->inputBuffer[0].cbBuffer = ntlm_token_length;
out:
http_response_free(http_response);
return 0;
@ -231,10 +235,10 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc)
http_response = http_response_recv(rpc->TlsOut);
ntlm_token_data = NULL;
if (http_response && http_response->AuthParam)
if (http_response && ListDictionary_Contains(http_response->Authenticates, "NTLM"))
{
crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam),
&ntlm_token_data, &ntlm_token_length);
char *token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM");
crypto_base64_decode((BYTE*) token64, strlen(token64), &ntlm_token_data, &ntlm_token_length);
}
ntlm->inputBuffer[0].pvBuffer = ntlm_token_data;