Browse code

uac: convert to memory logging helper

Henning Westerholt authored on 13/02/2020 21:45:36
Showing 1 changed files
... ...
@@ -340,7 +340,7 @@ str* build_authorization_hdr(int code, str *uri,
340 340
 	_uac_auth_hdr.s = (char*)pkg_malloc( len + 1);
341 341
 	if (_uac_auth_hdr.s==0)
342 342
 	{
343
-		LM_ERR("no more pkg mem\n");
343
+		PKG_MEM_ERROR;
344 344
 		goto error;
345 345
 	}
346 346
 
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -29,9 +29,9 @@
29 29
 #include "string.h"
30 30
 #include "ctype.h"
31 31
 
32
-#include "../../dprint.h"
33
-#include "../../str.h"
34
-#include "../../mem/mem.h"
32
+#include "../../core/dprint.h"
33
+#include "../../core/str.h"
34
+#include "../../core/mem/mem.h"
35 35
 
36 36
 #include "auth_hdr.h"
37 37
 #include "auth.h"
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,415 @@
1
+/*
2
+ * Copyright (C) 2005 Voice Sistem SRL
3
+ *
4
+ * This file is part of Kamailio, a free SIP server.
5
+ *
6
+ * Kamailio is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU General Public License
8
+ * as published by the Free Software Foundation; either version 2
9
+ * of the License, or (at your option) any later version.
10
+ *
11
+ * Kamailio is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
+ */
20
+
21
+/*!
22
+ * \file
23
+ * \brief Kamailio uac :: Authentication headers
24
+ * \ingroup uac
25
+ * Module: \ref uac
26
+ */
27
+
28
+
29
+#include "string.h"
30
+#include "ctype.h"
31
+
32
+#include "../../dprint.h"
33
+#include "../../str.h"
34
+#include "../../mem/mem.h"
35
+
36
+#include "auth_hdr.h"
37
+#include "auth.h"
38
+
39
+
40
+#define AUTHENTICATE_MD5         (1<<0)
41
+#define AUTHENTICATE_MD5SESS     (1<<1)
42
+#define AUTHENTICATE_STALE       (1<<2)
43
+
44
+#define AUTHENTICATE_DIGEST_S    "Digest"
45
+#define AUTHENTICATE_DIGEST_LEN  (sizeof(AUTHENTICATE_DIGEST_S)-1)
46
+
47
+#define LOWER1B(_n) \
48
+	((_n)|0x20)
49
+#define LOWER4B(_n) \
50
+	((_n)|0x20202020)
51
+#define GET4B(_p) \
52
+	((*(_p)<<24) + (*(_p+1)<<16) + (*(_p+2)<<8) + *(_p+3))
53
+#define GET3B(_p) \
54
+	((*(_p)<<24) + (*(_p+1)<<16) + (*(_p+2)<<8) + 0xff)
55
+
56
+#define CASE_5B(_hex4,_c5, _new_state, _quoted) \
57
+	case _hex4: \
58
+		if (p+5<end && LOWER1B(*(p+4))==_c5 ) \
59
+		{ \
60
+			p+=5; \
61
+			state = _new_state; \
62
+			quoted_val = _quoted; \
63
+		} else { \
64
+			p+=4; \
65
+		} \
66
+		break;
67
+
68
+#define CASE_6B(_hex4,_c5,_c6, _new_state, _quoted) \
69
+	case _hex4: \
70
+		if (p+6<end && LOWER1B(*(p+4))==_c5 && LOWER1B(*(p+5))==_c6) \
71
+		{ \
72
+			p+=6; \
73
+			state = _new_state; \
74
+			quoted_val = _quoted; \
75
+		} else { \
76
+			p+=4; \
77
+		} \
78
+		break;
79
+
80
+#define OTHER_STATE      0
81
+#define QOP_STATE        1
82
+#define REALM_STATE      2
83
+#define NONCE_STATE      3
84
+#define STALE_STATE      4
85
+#define DOMAIN_STATE     5
86
+#define OPAQUE_STATE     6
87
+#define ALGORITHM_STATE  7
88
+
89
+
90
+
91
+int parse_authenticate_body( str *body, struct authenticate_body *auth)
92
+{
93
+	char *p;
94
+	char *end;
95
+	int  n;
96
+	int state;
97
+	str name;
98
+	str val;
99
+	int quoted_val;
100
+
101
+	if (body->s==0 || *body->s==0 )
102
+	{
103
+		LM_ERR("empty body\n");
104
+		goto error;
105
+	}
106
+
107
+	memset( auth, 0, sizeof(struct authenticate_body));
108
+	p = body->s;
109
+	end = body->s + body->len;
110
+
111
+	/* parse the "digest" */
112
+	while (p<end && isspace((int)*p)) p++;
113
+	if (p+AUTHENTICATE_DIGEST_LEN>=end )
114
+		goto parse_error;
115
+	if (strncasecmp(p,AUTHENTICATE_DIGEST_S,AUTHENTICATE_DIGEST_LEN)!=0)
116
+		goto parse_error;
117
+	p += AUTHENTICATE_DIGEST_LEN;
118
+	if (!isspace((int)*p))
119
+		goto parse_error;
120
+	p++;
121
+	while (p<end && isspace((int)*p)) p++;
122
+	if (p==end)
123
+		goto parse_error;
124
+
125
+	while (p<end)
126
+	{
127
+		state = OTHER_STATE;
128
+		quoted_val = 0;
129
+		/* get name */
130
+		name.s = p;
131
+		if (p+4<end)
132
+		{
133
+			n = LOWER4B( GET4B(p) );
134
+			switch(n)
135
+			{
136
+				CASE_5B( 0x7265616c, 'm', REALM_STATE, 1); /*realm*/
137
+				CASE_5B( 0x6e6f6e63, 'e', NONCE_STATE, 1); /*nonce*/
138
+				CASE_5B( 0x7374616c, 'e', STALE_STATE, 0); /*stale*/
139
+				CASE_6B( 0x646f6d62, 'i', 'n', DOMAIN_STATE, 1); /*domain*/
140
+				CASE_6B( 0x6f706171, 'u', 'e', OPAQUE_STATE, 1); /*opaque*/
141
+				case 0x616c676f: /*algo*/
142
+					if (p+9<end && LOWER4B(GET4B(p+4))==0x72697468
143
+						&& LOWER1B(*(p+8))=='m' )
144
+					{
145
+						p+=9;
146
+						state = ALGORITHM_STATE;
147
+					} else {
148
+						p+=4;
149
+					}
150
+					break;
151
+				default:
152
+					if ((n|0xff)==0x716f70ff) /*qop*/
153
+					{
154
+						state = QOP_STATE;
155
+						p+=3;
156
+					}
157
+			}
158
+		} else if (p+3<end) {
159
+			n = LOWER4B( GET3B(p) );
160
+			if (n==0x716f70ff) /*qop*/
161
+			{
162
+				p+=3;
163
+				state = QOP_STATE;
164
+			}
165
+		}
166
+
167
+		/* parse to the "=" */
168
+		for( n=0 ; p<end&&!isspace((int)*p)&&*p!='=' ; n++,p++  );
169
+		if (p==end)
170
+			goto parse_error;
171
+		if (n!=0)
172
+			state = OTHER_STATE;
173
+		name.len = p-name.s;
174
+		/* get the '=' */
175
+		while (p<end && isspace((int)*p)) p++;
176
+		if (p==end || *p!='=')
177
+			goto parse_error;
178
+		p++;
179
+		/* get the value (quoted or not) */
180
+		while (p<end && isspace((int)*p)) p++;
181
+		if (p+1>=end || (quoted_val && *p!='\"'))
182
+			goto parse_error;
183
+		if (!quoted_val && *p=='\"')
184
+			quoted_val = 1;
185
+		if (quoted_val)
186
+		{
187
+			val.s = ++p;
188
+			while (p<end && *p!='\"')
189
+				p++;
190
+			if (p==end)
191
+				goto error;
192
+		} else {
193
+			val.s = p;
194
+			while (p<end && !isspace((int)*p) && *p!=',')
195
+				p++;
196
+		}
197
+		val.len = p - val.s;
198
+		if (val.len==0)
199
+			val.s = 0;
200
+		/* consume the closing '"' if quoted */
201
+		p += quoted_val;
202
+		while (p<end && isspace((int)*p)) p++;
203
+		if (p<end && *p==',')
204
+		{
205
+			p++;
206
+			while (p<end && isspace((int)*p)) p++;
207
+		}
208
+
209
+		LM_DBG("<%.*s>=\"%.*s\" state=%d\n",
210
+			name.len,name.s,val.len,val.s,state);
211
+
212
+		/* process the AVP */
213
+		switch (state)
214
+		{
215
+			case QOP_STATE:
216
+				auth->qop = val;
217
+				if(val.len>=4 && !strncmp(val.s, "auth", 4))
218
+					auth->flags |= QOP_AUTH;
219
+				break;
220
+			case REALM_STATE:
221
+				auth->realm = val;
222
+				break;
223
+			case NONCE_STATE:
224
+				auth->nonce = val;
225
+				break;
226
+			case DOMAIN_STATE:
227
+				auth->domain = val;
228
+				break;
229
+			case OPAQUE_STATE:
230
+				auth->opaque = val;
231
+				break;
232
+			case ALGORITHM_STATE:
233
+				if (val.len==3)
234
+				{
235
+					if ( LOWER4B(GET3B(val.s))==0x6d6435ff) /*MD5*/
236
+						auth->flags |= AUTHENTICATE_MD5;
237
+				} else {
238
+					LM_ERR("unsupported algorithm \"%.*s\"\n",val.len,val.s);
239
+					goto error;
240
+				}
241
+				break;
242
+			case STALE_STATE:
243
+				if (val.len==4 && LOWER4B(GET4B(val.s))==0x74727565) /*true*/
244
+				{
245
+						auth->flags |= AUTHENTICATE_STALE;
246
+				} else if ( !(val.len==5 && LOWER1B(val.s[4])=='e' && 
247
+					LOWER4B(GET4B(val.s))==0x66616c73) )
248
+				{
249
+					LM_ERR("unsupported stale value \"%.*s\"\n",val.len,val.s);
250
+					goto error;
251
+				}
252
+				break;
253
+			default:
254
+				break;
255
+		}
256
+	}
257
+
258
+	/* some checkings */
259
+	if (auth->nonce.s==0 || auth->realm.s==0)
260
+	{
261
+		LM_ERR("realm or nonce missing\n");
262
+		goto error;
263
+	}
264
+
265
+	return 0;
266
+parse_error:
267
+		LM_ERR("parse error in <%.*s> around %ld\n", body->len, body->s, (long)(p-body->s));
268
+error:
269
+	return -1;
270
+}
271
+
272
+
273
+#define AUTHORIZATION_HDR_START       "Authorization: Digest "
274
+#define AUTHORIZATION_HDR_START_LEN   (sizeof(AUTHORIZATION_HDR_START)-1)
275
+
276
+#define PROXY_AUTHORIZATION_HDR_START      "Proxy-Authorization: Digest "
277
+#define PROXY_AUTHORIZATION_HDR_START_LEN  \
278
+	(sizeof(PROXY_AUTHORIZATION_HDR_START)-1)
279
+
280
+#define USERNAME_FIELD_S         "username=\""
281
+#define USERNAME_FIELD_LEN       (sizeof(USERNAME_FIELD_S)-1)
282
+#define REALM_FIELD_S            "realm=\""
283
+#define REALM_FIELD_LEN          (sizeof(REALM_FIELD_S)-1)
284
+#define NONCE_FIELD_S            "nonce=\""
285
+#define NONCE_FIELD_LEN          (sizeof(NONCE_FIELD_S)-1)
286
+#define URI_FIELD_S              "uri=\""
287
+#define URI_FIELD_LEN            (sizeof(URI_FIELD_S)-1)
288
+#define OPAQUE_FIELD_S           "opaque=\""
289
+#define OPAQUE_FIELD_LEN         (sizeof(OPAQUE_FIELD_S)-1)
290
+#define RESPONSE_FIELD_S         "response=\""
291
+#define RESPONSE_FIELD_LEN       (sizeof(RESPONSE_FIELD_S)-1)
292
+#define ALGORITHM_FIELD_S        "algorithm=MD5"
293
+#define ALGORITHM_FIELD_LEN       (sizeof(ALGORITHM_FIELD_S)-1)
294
+#define FIELD_SEPARATOR_S        "\", "
295
+#define FIELD_SEPARATOR_LEN      (sizeof(FIELD_SEPARATOR_S)-1)
296
+#define FIELD_SEPARATOR_UQ_S     ", "
297
+#define FIELD_SEPARATOR_UQ_LEN   (sizeof(FIELD_SEPARATOR_UQ_S)-1)
298
+
299
+#define QOP_FIELD_S              "qop="
300
+#define QOP_FIELD_LEN            (sizeof(QOP_FIELD_S)-1)
301
+#define NC_FIELD_S               "nc="
302
+#define NC_FIELD_LEN             (sizeof(NC_FIELD_S)-1)
303
+#define CNONCE_FIELD_S           "cnonce=\""
304
+#define CNONCE_FIELD_LEN         (sizeof(CNONCE_FIELD_S)-1)
305
+
306
+#define add_string( _p, _s, _l) \
307
+	do {\
308
+		memcpy( _p, _s, _l);\
309
+		_p += _l; \
310
+	}while(0)
311
+
312
+
313
+str* build_authorization_hdr(int code, str *uri, 
314
+		struct uac_credential *crd, struct authenticate_body *auth,
315
+		char *response)
316
+{
317
+	static str _uac_auth_hdr;
318
+	char *p;
319
+	int len;
320
+	int response_len;
321
+
322
+	response_len = strlen(response);
323
+
324
+	/* compile then len */
325
+	len = (code==401?
326
+		AUTHORIZATION_HDR_START_LEN:PROXY_AUTHORIZATION_HDR_START_LEN) +
327
+		USERNAME_FIELD_LEN + crd->user.len + FIELD_SEPARATOR_LEN +
328
+		REALM_FIELD_LEN + crd->realm.len + FIELD_SEPARATOR_LEN +
329
+		NONCE_FIELD_LEN + auth->nonce.len + FIELD_SEPARATOR_LEN +
330
+		URI_FIELD_LEN + uri->len + FIELD_SEPARATOR_LEN +
331
+		(auth->opaque.len?
332
+			(OPAQUE_FIELD_LEN + auth->opaque.len + FIELD_SEPARATOR_LEN):0) +
333
+		RESPONSE_FIELD_LEN + response_len + FIELD_SEPARATOR_LEN +
334
+		ALGORITHM_FIELD_LEN + CRLF_LEN;
335
+	if((auth->flags&QOP_AUTH) || (auth->flags&QOP_AUTH_INT))
336
+		len += QOP_FIELD_LEN + 4 /*auth*/ + FIELD_SEPARATOR_UQ_LEN +
337
+				NC_FIELD_LEN + auth->nc->len + FIELD_SEPARATOR_UQ_LEN +
338
+				CNONCE_FIELD_LEN + auth->cnonce->len + FIELD_SEPARATOR_LEN;
339
+
340
+	_uac_auth_hdr.s = (char*)pkg_malloc( len + 1);
341
+	if (_uac_auth_hdr.s==0)
342
+	{
343
+		LM_ERR("no more pkg mem\n");
344
+		goto error;
345
+	}
346
+
347
+	p = _uac_auth_hdr.s;
348
+	/* header start */
349
+	if (code==401)
350
+	{
351
+		add_string( p, AUTHORIZATION_HDR_START USERNAME_FIELD_S,
352
+			AUTHORIZATION_HDR_START_LEN+USERNAME_FIELD_LEN);
353
+	} else {
354
+		add_string( p, PROXY_AUTHORIZATION_HDR_START USERNAME_FIELD_S,
355
+			PROXY_AUTHORIZATION_HDR_START_LEN+USERNAME_FIELD_LEN);
356
+	}
357
+	/* username */
358
+	add_string( p, crd->user.s, crd->user.len);
359
+	/* REALM */
360
+	add_string( p, FIELD_SEPARATOR_S REALM_FIELD_S,
361
+		FIELD_SEPARATOR_LEN+REALM_FIELD_LEN);
362
+	add_string( p, crd->realm.s, crd->realm.len);
363
+	/* NONCE */
364
+	add_string( p, FIELD_SEPARATOR_S NONCE_FIELD_S, 
365
+		FIELD_SEPARATOR_LEN+NONCE_FIELD_LEN);
366
+	add_string( p, auth->nonce.s, auth->nonce.len);
367
+	/* URI */
368
+	add_string( p, FIELD_SEPARATOR_S URI_FIELD_S,
369
+		FIELD_SEPARATOR_LEN+URI_FIELD_LEN);
370
+	add_string( p, uri->s, uri->len);
371
+	/* OPAQUE */
372
+	if (auth->opaque.len )
373
+	{
374
+		add_string( p, FIELD_SEPARATOR_S OPAQUE_FIELD_S, 
375
+			FIELD_SEPARATOR_LEN+OPAQUE_FIELD_LEN);
376
+		add_string( p, auth->opaque.s, auth->opaque.len);
377
+	}
378
+	if((auth->flags&QOP_AUTH) || (auth->flags&QOP_AUTH_INT))
379
+	{
380
+		add_string( p, FIELD_SEPARATOR_S QOP_FIELD_S, 
381
+			FIELD_SEPARATOR_LEN+QOP_FIELD_LEN);
382
+		add_string( p, "auth", 4);
383
+		add_string( p, FIELD_SEPARATOR_UQ_S NC_FIELD_S, 
384
+			FIELD_SEPARATOR_UQ_LEN+NC_FIELD_LEN);
385
+		add_string( p, auth->nc->s, auth->nc->len);
386
+		add_string( p, FIELD_SEPARATOR_UQ_S CNONCE_FIELD_S, 
387
+			FIELD_SEPARATOR_UQ_LEN+CNONCE_FIELD_LEN);
388
+		add_string( p, auth->cnonce->s, auth->cnonce->len);
389
+	}
390
+	/* RESPONSE */
391
+	add_string( p, FIELD_SEPARATOR_S RESPONSE_FIELD_S,
392
+		FIELD_SEPARATOR_LEN+RESPONSE_FIELD_LEN);
393
+	add_string( p, response, response_len);
394
+	/* ALGORITHM */
395
+	add_string( p, FIELD_SEPARATOR_S ALGORITHM_FIELD_S CRLF,
396
+		FIELD_SEPARATOR_LEN+ALGORITHM_FIELD_LEN+CRLF_LEN);
397
+
398
+	_uac_auth_hdr.len = p - _uac_auth_hdr.s;
399
+
400
+	if (_uac_auth_hdr.len!=len)
401
+	{
402
+		LM_CRIT("BUG: bad buffer computation "
403
+			"(%d<>%d)\n",len,_uac_auth_hdr.len);
404
+		pkg_free( _uac_auth_hdr.s );
405
+		goto error;
406
+	}
407
+
408
+	LM_DBG("hdr is <%.*s>\n",
409
+		_uac_auth_hdr.len,_uac_auth_hdr.s);
410
+
411
+	return &_uac_auth_hdr;
412
+error:
413
+	return 0;
414
+}
415
+