/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** Licensed under the Apache License, Version 2.0 (the "License"); you may not ** use this file except in compliance with the License. You may obtain a copy ** of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ #include "httpcommon.h" #include #include #include #include #ifdef CONFIG_POSIX # include # include #endif static int _Base64DecCallback( const void* data, size_t size, void* callbackData) { char** str = (char**)callbackData; size_t i; for (i = 0; i < size; i++) { **str = ((unsigned char*)data)[i]; (*str)++; } return 0; } MI_Boolean _DecodeBasicAuth( _In_ HttpHeaders* recvHeaders, _In_z_ const char * src, _Out_writes_z_(tgtSize) _Null_terminated_ char * tgt, _In_ size_t tgtSize) { char* startBuffer = tgt; MI_UNREFERENCED_PARAMETER(tgtSize); /* skip spaces in value */ while (src[0] == ' ' || src[0] == '\t') src++; /* Decode the password */ if (Base64Dec(src, strlen(src), _Base64DecCallback, &tgt) == -1) { trace_Base64Dec_Failed(); return MI_FALSE; } #ifdef _PREFAST_ #pragma prefast (push) #pragma prefast (disable: 26015) #pragma prefast (disable: 26018) #endif *tgt = 0; #ifdef _PREFAST_ #pragma prefast (pop) #endif /* decoded string has format: [:] */ recvHeaders->username = startBuffer; startBuffer = strchr(startBuffer, ':'); if ( startBuffer ) { *startBuffer = 0; recvHeaders->password = startBuffer + 1; MemoryLock((void*)recvHeaders->password, strlen(recvHeaders->password)); } return MI_TRUE; } MI_Boolean ParseAuthorization( _Inout_ HttpHeaders* recvHeaders, _In_ CharPtr value ) { if (Strncasecmp(value, AUTHENTICATION_BASIC, AUTHENTICATION_BASIC_LENGTH) == 0) { /* since decoded string is smaller, performing decoding * inplace; for source skip 'Basic ' part (6 chars) */ char * authvalue = value; size_t i; /* Set authorization value in the header. We need to do that because in wsman layer an http 401 error will be thrown if the authentication is not supported */ recvHeaders->authorization = AUTHENTICATION_BASIC; for (i = 0; i < 6; ++i) { if (*authvalue == 0) { trace_Base64_DecodeErrorInBasic(scs(value)); return MI_FALSE; } authvalue++; } if (!_DecodeBasicAuth(recvHeaders, authvalue, value, strlen(value))) { trace_Base64_DecodeErrorInBasic(scs(value)); return MI_FALSE; } } else /* unknown authorization type */ { recvHeaders->authorization = value; } return MI_TRUE; } void ParseContentType( _Inout_ HttpHeaders* recvHeaders, _In_ CharPtr value ) { recvHeaders->contentType = value; /* find attribute list */ while (value[0] != 0 && value[0] != ';') value++; /* Check if attribute list was provided */ if (value[0] == 0) return; /* terminate type/subtype; move to attributes list */ value[0] = 0; value++; /* skip spaces in value */ while (value[0] == ' ' || value[0] == '\t') value++; /* find charset attribute (if present) */ if (Strncasecmp(value,"charset=",8) != 0) return; /* skip 8 chars */ { size_t i; for(i = 0; *value != 0 && i < 8; i++) { value++; } } recvHeaders->charset = value; /* can be enclosed in quotes */ if (value[0] == '"') { /* skip '"' */ recvHeaders->charset++; value++; value = strchr(value, '"'); if (value) *value = 0; else recvHeaders->charset = 0; } else { /*skip trialing spaces */ while (value[0] != 0 && value[0] != ' ' && value[0] != '\t') value++; *value = 0; } } #ifdef CONFIG_POSIX char* GetSslErrorString( _Out_ char* buf, _In_ size_t bufLength) { unsigned long error = ERR_peek_last_error(); ERR_error_string_n(error, buf, bufLength); return buf; } #endif