1 krisbash 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 krisbash 1.1 **==============================================================================
23 */
24
25 #include "httpcommon.h"
26 #include <base/base64.h>
27 #include <base/log.h>
28 #include <base/memman.h>
29 #include <pal/format.h>
30 #ifdef CONFIG_POSIX
31 # include <openssl/ssl.h>
32 # include <openssl/err.h>
33 #endif
34
35 static int _Base64DecCallback(
36 const void* data,
37 size_t size,
38 void* callbackData)
39 {
40 char** str = (char**)callbackData;
41 size_t i;
42
43 krisbash 1.1 for (i = 0; i < size; i++)
44 {
45 **str = ((unsigned char*)data)[i];
46 (*str)++;
47 }
48
49 return 0;
50 }
51
52 MI_Boolean _DecodeBasicAuth(
53 _In_ HttpHeaders* recvHeaders,
54 _In_z_ const char * src,
55 _Out_writes_z_(tgtSize) _Null_terminated_ char * tgt,
56 _In_ size_t tgtSize)
57 {
58 char* startBuffer = tgt;
59 MI_UNREFERENCED_PARAMETER(tgtSize);
60 /* skip spaces in value */
61
62 while (src[0] == ' ' || src[0] == '\t')
63 src++;
64 krisbash 1.1
65 /* Decode the password */
66
67 if (Base64Dec(src, strlen(src), _Base64DecCallback, &tgt) == -1)
68 {
69 trace_Base64Dec_Failed();
70 return MI_FALSE;
71 }
72 #ifdef _PREFAST_
73 #pragma prefast (push)
74 #pragma prefast (disable: 26015)
75 #pragma prefast (disable: 26018)
76 #endif
77 *tgt = 0;
78 #ifdef _PREFAST_
79 #pragma prefast (pop)
80 #endif
81 /* decoded string has format: <uersname>[:<password>] */
82 recvHeaders->username = startBuffer;
83 startBuffer = strchr(startBuffer, ':');
84
85 krisbash 1.1 if ( startBuffer )
86 {
87 *startBuffer = 0;
88 recvHeaders->password = startBuffer + 1;
89 MemoryLock((void*)recvHeaders->password, strlen(recvHeaders->password));
90 }
91
92 return MI_TRUE;
93 }
94
95 MI_Boolean ParseAuthorization(
96 _Inout_ HttpHeaders* recvHeaders,
97 _In_ CharPtr value )
98 {
99 if (Strncasecmp(value, AUTHENTICATION_BASIC, AUTHENTICATION_BASIC_LENGTH) == 0)
100 {
101 /* since decoded string is smaller, performing decoding
102 * inplace; for source skip 'Basic ' part (6 chars)
103 */
104
105 char * authvalue = value;
106 krisbash 1.1 size_t i;
107
108 /*
109 Set authorization value in the header.
110 We need to do that because in wsman layer an http 401 error will be thrown
111 if the authentication is not supported
112 */
113 recvHeaders->authorization = AUTHENTICATION_BASIC;
114
115 for (i = 0; i < 6; ++i)
116 {
117 if (*authvalue == 0)
118 {
119 trace_Base64_DecodeErrorInBasic(scs(value));
120 return MI_FALSE;
121 }
122 authvalue++;
123 }
124
125 if (!_DecodeBasicAuth(recvHeaders, authvalue, value, strlen(value)))
126 {
127 krisbash 1.1 trace_Base64_DecodeErrorInBasic(scs(value));
128 return MI_FALSE;
129 }
130 }
131 else /* unknown authorization type */
132 {
133 recvHeaders->authorization = value;
134 }
135
136 return MI_TRUE;
137 }
138
139 void ParseContentType(
140 _Inout_ HttpHeaders* recvHeaders,
141 _In_ CharPtr value )
142 {
143 recvHeaders->contentType = value;
144
145 /* find attribute list */
146 while (value[0] != 0 && value[0] != ';')
147 value++;
148 krisbash 1.1
149 /* Check if attribute list was provided */
150 if (value[0] == 0)
151 return;
152
153 /* terminate type/subtype; move to attributes list */
154 value[0] = 0;
155 value++;
156
157 /* skip spaces in value */
158 while (value[0] == ' ' || value[0] == '\t')
159 value++;
160
161 /* find charset attribute (if present) */
162 if (Strncasecmp(value,"charset=",8) != 0)
163 return;
164
165 /* skip 8 chars */
166 {
167 size_t i;
168 for(i = 0; *value != 0 && i < 8; i++)
169 krisbash 1.1 {
170 value++;
171 }
172 }
173
174 recvHeaders->charset = value;
175
176 /* can be enclosed in quotes */
177 if (value[0] == '"')
178 {
179 /* skip '"' */
180 recvHeaders->charset++;
181 value++;
182 value = strchr(value, '"');
183 if (value)
184 *value = 0;
185 else
186 recvHeaders->charset = 0;
187 }
188 else
189 {
190 krisbash 1.1 /*skip trialing spaces */
191 while (value[0] != 0 && value[0] != ' ' && value[0] != '\t')
192 value++;
193
194 *value = 0;
195 }
196 }
197
198 #ifdef CONFIG_POSIX
199
200 char* GetSslErrorString(
201 _Out_ char* buf,
202 _In_ size_t bufLength)
203 {
204 unsigned long error = ERR_peek_last_error();
205
206 ERR_error_string_n(error, buf, bufLength);
207 return buf;
208 }
209
210 #endif
|