Browse code

auth(s): module moved to modules/auth

Daniel-Constantin Mierla authored on 25/07/2010 18:26:38
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,669 +0,0 @@
1
-/*
2
- * $Id$
3
- *
4
- * Digest Authentication Module
5
- *
6
- * Copyright (C) 2001-2003 FhG Fokus
7
- *
8
- * This file is part of ser, a free SIP server.
9
- *
10
- * ser is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License as published by
12
- * the Free Software Foundation; either version 2 of the License, or
13
- * (at your option) any later version
14
- *
15
- * For a license to use the ser software under conditions
16
- * other than those described here, or to purchase support for this
17
- * software, please contact iptel.org by e-mail at the following addresses:
18
- *    info@iptel.org
19
- *
20
- * ser is distributed in the hope that it will be useful,
21
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
- * GNU General Public License for more details.
24
- *
25
- * You should have received a copy of the GNU General Public License
26
- * along with this program; if not, write to the Free Software
27
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
- *
29
- * History:
30
- * --------
31
- * 2003-02-26 checks and group moved to separate modules (janakj)
32
- * 2003-03-10 New module interface (janakj)
33
- * 2003-03-16 flags export parameter added (janakj)
34
- * 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
35
- * 2003-04-28 rpid contributed by Juha Heinanen added (janakj)
36
- * 2007-10-19 auth extra checks: longer nonces that include selected message
37
- *            parts to protect against various reply attacks without keeping
38
- *            state (andrei)
39
- */
40
-
41
-
42
-#include <stdio.h>
43
-#include <stdlib.h>
44
-#include <time.h>
45
-#include "../../sr_module.h"
46
-#include "../../dprint.h"
47
-#include "../../mem/mem.h"
48
-#include "../../parser/digest/digest.h"
49
-#include "../../data_lump.h"
50
-#include "../../data_lump_rpl.h"
51
-#include "../../error.h"
52
-#include "../../ut.h"
53
-#include "../../modules/sl/sl.h"
54
-#include "auth_mod.h"
55
-#include "challenge.h"
56
-#include "api.h"
57
-#include "nid.h"
58
-#include "nc.h"
59
-#include "ot_nonce.h"
60
-#include "rfc2617.h"
61
-
62
-MODULE_VERSION
63
-
64
-#define RAND_SECRET_LEN 32
65
-
66
-
67
-/*
68
- * Module destroy function prototype
69
- */
70
-static void destroy(void);
71
-
72
-/*
73
- * Module initialization function prototype
74
- */
75
-static int mod_init(void);
76
-
77
-/*
78
- * Remove used credentials from a SIP message header
79
- */
80
-int consume_credentials(struct sip_msg* msg, char* s1, char* s2);
81
-
82
-static int pv_proxy_authenticate(struct sip_msg* msg, char* realm,
83
-		char *passwd, char *flags);
84
-static int pv_www_authenticate(struct sip_msg* msg, char* realm,
85
-		char *passwd, char *flags);
86
-static int fixup_pv_auth(void **param, int param_no);
87
-
88
-static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags);
89
-static int www_challenge(struct sip_msg *msg, char* realm, char *flags);
90
-static int fixup_auth_challenge(void **param, int param_no);
91
-
92
-
93
-/*
94
- * Module parameter variables
95
- */
96
-char* sec_param    = 0;     /* If the parameter was not used, the secret phrase will be auto-generated */
97
-int   nonce_expire = 300;   /* Nonce lifetime */
98
-/*int   auth_extra_checks = 0;  -- in nonce.c */
99
-int   protect_contacts = 0; /* Do not include contacts in nonce by default */
100
-
101
-str secret1;
102
-str secret2;
103
-char* sec_rand1 = 0;
104
-char* sec_rand2 = 0;
105
-
106
-str challenge_attr = STR_STATIC_INIT("$digest_challenge");
107
-avp_ident_t challenge_avpid;
108
-
109
-str proxy_challenge_header = STR_STATIC_INIT("Proxy-Authenticate");
110
-str www_challenge_header = STR_STATIC_INIT("WWW-Authenticate");
111
-
112
-struct qp auth_qop = {
113
-    STR_STATIC_INIT("auth"),
114
-    QOP_AUTH
115
-};
116
-
117
-static struct qp auth_qauth = {
118
-    STR_STATIC_INIT("auth"),
119
-    QOP_AUTH
120
-};
121
-
122
-static struct qp auth_qauthint = {
123
-    STR_STATIC_INIT("auth-int"),
124
-    QOP_AUTHINT
125
-};
126
-
127
-/*! SL API structure */
128
-sl_api_t slb;
129
-
130
-/*
131
- * Exported functions
132
- */
133
-static cmd_export_t cmds[] = {
134
-    {"consume_credentials",    consume_credentials,                  0,
135
-			0, REQUEST_ROUTE},
136
-    {"www_challenge",          (cmd_function)www_challenge,          2,
137
-			fixup_auth_challenge, REQUEST_ROUTE},
138
-    {"proxy_challenge",        (cmd_function)proxy_challenge,        2,
139
-			fixup_auth_challenge, REQUEST_ROUTE},
140
-    {"pv_www_authorize",       (cmd_function)pv_www_authenticate,    3,
141
-			fixup_pv_auth, REQUEST_ROUTE},
142
-    {"pv_www_authenticate",    (cmd_function)pv_www_authenticate,    3,
143
-			fixup_pv_auth, REQUEST_ROUTE},
144
-    {"pv_proxy_authorize",     (cmd_function)pv_proxy_authenticate,  3,
145
-			fixup_pv_auth, REQUEST_ROUTE},
146
-    {"pv_proxy_authenticate",  (cmd_function)pv_proxy_authenticate,  3,
147
-			fixup_pv_auth, REQUEST_ROUTE},
148
-    {"bind_auth_s",           (cmd_function)bind_auth_s, 0, 0, 0        },
149
-    {0, 0, 0, 0, 0}
150
-};
151
-
152
-
153
-/*
154
- * Exported parameters
155
- */
156
-static param_export_t params[] = {
157
-    {"secret",                 PARAM_STRING, &sec_param             },
158
-    {"nonce_expire",           PARAM_INT,    &nonce_expire          },
159
-	{"nonce_auth_max_drift",   PARAM_INT,    &nonce_auth_max_drift  },
160
-    {"protect_contacts",       PARAM_INT,    &protect_contacts      },
161
-    {"challenge_attr",         PARAM_STR,    &challenge_attr        },
162
-    {"proxy_challenge_header", PARAM_STR,    &proxy_challenge_header},
163
-    {"www_challenge_header",   PARAM_STR,    &www_challenge_header  },
164
-    {"qop",                    PARAM_STR,    &auth_qop.qop_str      },
165
-	{"auth_checks_register",   PARAM_INT,    &auth_checks_reg       },
166
-	{"auth_checks_no_dlg",     PARAM_INT,    &auth_checks_ood       },
167
-	{"auth_checks_in_dlg",     PARAM_INT,    &auth_checks_ind       },
168
-	{"nonce_count"  ,          PARAM_INT,    &nc_enabled            },
169
-	{"nc_array_size",          PARAM_INT,    &nc_array_size         },
170
-	{"nc_array_order",         PARAM_INT,    &nc_array_k            },
171
-	{"one_time_nonce"  ,       PARAM_INT,    &otn_enabled           },
172
-	{"otn_in_flight_no",       PARAM_INT,    &otn_in_flight_no      },
173
-	{"otn_in_flight_order",    PARAM_INT,    &otn_in_flight_k       },
174
-	{"nid_pool_no",            PARAM_INT,    &nid_pool_no            },
175
-    {0, 0, 0}
176
-};
177
-
178
-
179
-/*
180
- * Module interface
181
- */
182
-struct module_exports exports = {
183
-    "auth",
184
-    cmds,
185
-    0,          /* RPC methods */
186
-    params,
187
-    mod_init,   /* module initialization function */
188
-    0,          /* response function */
189
-    destroy,    /* destroy function */
190
-    0,          /* oncancel function */
191
-    0           /* child initialization function */
192
-};
193
-
194
-
195
-/*
196
- * Secret parameter was not used so we generate
197
- * a random value here
198
- */
199
-static inline int generate_random_secret(void)
200
-{
201
-    int i;
202
-    
203
-    sec_rand1 = (char*)pkg_malloc(RAND_SECRET_LEN);
204
-    sec_rand2 = (char*)pkg_malloc(RAND_SECRET_LEN);
205
-    if (!sec_rand1 || !sec_rand2) {
206
-	LOG(L_ERR, "auth:generate_random_secret: No memory left\n");
207
-	if (sec_rand1){
208
-		pkg_free(sec_rand1);
209
-		sec_rand1=0;
210
-	}
211
-	return -1;
212
-    }
213
-    
214
-    /* srandom(time(0));  -- seeded by core */
215
-    
216
-    for(i = 0; i < RAND_SECRET_LEN; i++) {
217
-	sec_rand1[i] = 32 + (int)(95.0 * rand() / (RAND_MAX + 1.0));
218
-    }
219
-    
220
-    secret1.s = sec_rand1;
221
-    secret1.len = RAND_SECRET_LEN;
222
-	
223
-    for(i = 0; i < RAND_SECRET_LEN; i++) {
224
-	sec_rand2[i] = 32 + (int)(95.0 * rand() / (RAND_MAX + 1.0));
225
-    }
226
-    
227
-    secret2.s = sec_rand2;
228
-    secret2.len = RAND_SECRET_LEN;
229
-    
230
-	 /* DBG("Generated secret: '%.*s'\n", secret.len, secret.s); */
231
-    
232
-    return 0;
233
-}
234
-
235
-
236
-static int mod_init(void)
237
-{
238
-    str attr;
239
-    
240
-    DBG("auth module - initializing\n");
241
-    
242
-	/* bind the SL API */
243
-	if (sl_load_api(&slb)!=0) {
244
-		LM_ERR("cannot bind to SL API\n");
245
-		return -1;
246
-	}
247
-
248
-	/* If the parameter was not used */
249
-    if (sec_param == 0) {
250
-		/* Generate secret using random generator */
251
-		if (generate_random_secret() < 0) {
252
-			LOG(L_ERR, "auth:mod_init: Error while generating random secret\n");
253
-			return -3;
254
-		}
255
-    } else {
256
-		/* Otherwise use the parameter's value */
257
-		secret1.s = sec_param;
258
-		secret1.len = strlen(secret1.s);
259
-		
260
-		if (auth_checks_reg || auth_checks_ind || auth_checks_ood) {
261
-			/* divide the secret in half: one half for secret1 and one half for
262
-			 *  secret2 */
263
-			secret2.len = secret1.len/2;
264
-			secret1.len -= secret2.len;
265
-			secret2.s = secret1.s + secret1.len;
266
-			if (secret2.len < 16) {
267
-				WARN("auth: consider a longer secret when extra auth checks are"
268
-					 " enabled (the config secret is divided in 2!)\n");
269
-			}
270
-		}
271
-    }
272
-    
273
-    if ((!challenge_attr.s || challenge_attr.len == 0) ||
274
-		challenge_attr.s[0] != '$') {
275
-		ERR("auth: Invalid value of challenge_attr module parameter\n");
276
-		return -1;
277
-    }
278
-    
279
-    attr.s = challenge_attr.s + 1;
280
-    attr.len = challenge_attr.len - 1;
281
-    
282
-    if (parse_avp_ident(&attr, &challenge_avpid) < 0) {
283
-		ERR("auth: Error while parsing value of challenge_attr module"
284
-				" parameter\n");
285
-		return -1;
286
-    }
287
-	
288
-    parse_qop(&auth_qop);
289
-	switch(auth_qop.qop_parsed){
290
-		case QOP_OTHER:
291
-			ERR("auth: Unsupported qop parameter value\n");
292
-			return -1;
293
-		case QOP_AUTH:
294
-		case QOP_AUTHINT:
295
-			if (nc_enabled){
296
-#ifndef USE_NC
297
-				WARN("auth: nounce count support enabled from config, but"
298
-					" disabled at compile time (recompile with -DUSE_NC)\n");
299
-				nc_enabled=0;
300
-#else
301
-				if (nid_crt==0)
302
-					init_nonce_id();
303
-				if (init_nonce_count()!=0)
304
-					return -1;
305
-#endif
306
-			}
307
-#ifdef USE_NC
308
-			else{
309
-				INFO("auth: qop set, but nonce-count (nc_enabled) support"
310
-						" disabled\n");
311
-			}
312
-#endif
313
-			break;
314
-		default:
315
-			if (nc_enabled){
316
-				WARN("auth: nonce-count support enabled, but qop not set\n");
317
-				nc_enabled=0;
318
-			}
319
-			break;
320
-	}
321
-	if (otn_enabled){
322
-#ifdef USE_OT_NONCE
323
-		if (nid_crt==0) init_nonce_id();
324
-		if (init_ot_nonce()!=0) 
325
-			return -1;
326
-#else
327
-		WARN("auth: one-time-nonce support enabled from config, but "
328
-				"disabled at compile time (recompile with -DUSE_OT_NONCE)\n");
329
-		otn_enabled=0;
330
-#endif /* USE_OT_NONCE */
331
-	}
332
-
333
-    return 0;
334
-}
335
-
336
-
337
-static void destroy(void)
338
-{
339
-    if (sec_rand1) pkg_free(sec_rand1);
340
-    if (sec_rand2) pkg_free(sec_rand2);
341
-#ifdef USE_NC
342
-	destroy_nonce_count();
343
-#endif
344
-#ifdef USE_OT_NONCE
345
-	destroy_ot_nonce();
346
-#endif
347
-#if defined USE_NC || defined USE_OT_NONCE
348
-	destroy_nonce_id();
349
-#endif
350
-}
351
-
352
-
353
-/*
354
- * Remove used credentials from a SIP message header
355
- */
356
-int consume_credentials(struct sip_msg* msg, char* s1, char* s2)
357
-{
358
-    struct hdr_field* h;
359
-    int len;
360
-    
361
-    get_authorized_cred(msg->authorization, &h);
362
-    if (!h) {
363
-		get_authorized_cred(msg->proxy_auth, &h);
364
-		if (!h) { 
365
-			if (msg->REQ_METHOD != METHOD_ACK 
366
-				&& msg->REQ_METHOD != METHOD_CANCEL) {
367
-				LOG(L_ERR, "auth:consume_credentials: No authorized "
368
-					"credentials found (error in scripts)\n");
369
-			}
370
-			return -1;
371
-		}
372
-    }
373
-    
374
-    len = h->len;
375
-    
376
-    if (del_lump(msg, h->name.s - msg->buf, len, 0) == 0) {
377
-		LOG(L_ERR, "auth:consume_credentials: Can't remove credentials\n");
378
-		return -1;
379
-    }
380
-    
381
-    return 1;
382
-}
383
-
384
-/**
385
- * @brief do WWW-Digest authentication with password taken from cfg var
386
- */
387
-static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
388
-		char *p3, int hftype)
389
-{
390
-    int flags = 0;
391
-    str realm  = {0, 0};
392
-    str passwd = {0, 0};
393
-	struct hdr_field* h;
394
-	auth_body_t* cred;
395
-	int ret;
396
-    str hf = {0, 0};
397
-    avp_value_t val;
398
-	static char ha1[256];
399
-	struct qp *qop = NULL;
400
-
401
-	cred = 0;
402
-	ret = AUTH_ERROR;
403
-
404
-	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
405
-		LM_ERR("failed to get realm value\n");
406
-		goto error;
407
-	}
408
-
409
-	if(realm.len==0) {
410
-		LM_ERR("invalid realm value - empty content\n");
411
-		goto error;
412
-	}
413
-
414
-	if (get_str_fparam(&passwd, msg, (fparam_t*)p2) < 0) {
415
-		LM_ERR("failed to get passwd value\n");
416
-		goto error;
417
-	}
418
-
419
-	if(passwd.len==0) {
420
-		LM_ERR("invalid password value - empty content\n");
421
-		goto error;
422
-	}
423
-
424
-	if (get_int_fparam(&flags, msg, (fparam_t*)p3) < 0) {
425
-		LM_ERR("invalid flags value\n");
426
-		goto error;
427
-	}
428
-
429
-	switch(pre_auth(msg, &realm, hftype, &h, NULL)) {
430
-		case ERROR:
431
-		case BAD_CREDENTIALS:
432
-			LM_DBG("error or bad credentials\n");
433
-			ret = AUTH_ERROR;
434
-			goto end;
435
-		case CREATE_CHALLENGE:
436
-			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
437
-			ret = AUTH_ERROR;
438
-			goto end;
439
-		case DO_RESYNCHRONIZATION:
440
-			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
441
-			ret = AUTH_ERROR;
442
-			goto end;
443
-		case NOT_AUTHENTICATED:
444
-			LM_DBG("not authenticated\n");
445
-			ret = AUTH_ERROR;
446
-			goto end;
447
-		case DO_AUTHENTICATION:
448
-			break;
449
-		case AUTHENTICATED:
450
-			ret = AUTH_OK;
451
-			goto end;
452
-	}
453
-
454
-	cred = (auth_body_t*)h->parsed;
455
-
456
-	/* compute HA1 if needed */
457
-	if ((flags&1)==0) {
458
-		/* Plaintext password is stored in PV, calculate HA1 */
459
-		calc_HA1(HA_MD5, &cred->digest.username.whole, &realm,
460
-				&passwd, 0, 0, ha1);
461
-		LM_DBG("HA1 string calculated: %s\n", ha1);
462
-	} else {
463
-		memcpy(ha1, passwd.s, passwd.len);
464
-		ha1[passwd.len] = '\0';
465
-	}
466
-
467
-	/* Recalculate response, it must be same to authorize successfully */
468
-	ret = auth_check_response(&(cred->digest),
469
-				&msg->first_line.u.request.method, ha1);
470
-	if(ret==AUTHENTICATED) {
471
-		ret = AUTH_OK;
472
-		switch(post_auth(msg, h)) {
473
-			case AUTHENTICATED:
474
-				break;
475
-			default:
476
-				ret = AUTH_ERROR;
477
-				break;
478
-		}
479
-	} else {
480
-		if(ret==NOT_AUTHENTICATED)
481
-			ret = AUTH_INVALID_PASSWORD;
482
-		else
483
-			ret = AUTH_ERROR;
484
-	}
485
-
486
-end:
487
-	if (ret < 0) {
488
-		/* check if required to add challenge header as avp */
489
-		if(!(flags&14))
490
-			return ret;
491
-		if(flags&8) {
492
-			qop = &auth_qauthint;
493
-		} else if(flags&4) {
494
-			qop = &auth_qauth;
495
-		}
496
-		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
497
-				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
498
-			ERR("Error while creating challenge\n");
499
-			ret = AUTH_ERROR;
500
-		} else {
501
-			val.s = hf;
502
-			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
503
-							challenge_avpid.name, val) < 0) {
504
-				LM_ERR("Error while creating attribute with challenge\n");
505
-				ret = AUTH_ERROR;
506
-			}
507
-			pkg_free(hf.s);
508
-		}
509
-	}
510
-
511
-error:
512
-	return ret;
513
-
514
-}
515
-
516
-/**
517
- *
518
- */
519
-static int pv_proxy_authenticate(struct sip_msg *msg, char* realm,
520
-		char *passwd, char *flags)
521
-{
522
-	return pv_authenticate(msg, realm, passwd, flags, HDR_PROXYAUTH_T);
523
-}
524
-
525
-/**
526
- *
527
- */
528
-static int pv_www_authenticate(struct sip_msg *msg, char* realm,
529
-		char *passwd, char *flags)
530
-{
531
-	return pv_authenticate(msg, realm, passwd, flags, HDR_AUTHORIZATION_T);
532
-}
533
-
534
-/**
535
- * @brief fixup function for pv_{www,proxy}_authenticate
536
- */
537
-static int fixup_pv_auth(void **param, int param_no)
538
-{
539
-	if(strlen((char*)*param)<=0) {
540
-		LM_ERR("empty parameter %d not allowed\n", param_no);
541
-		return -1;
542
-	}
543
-
544
-	switch(param_no) {
545
-		case 1:
546
-		case 2:
547
-			return fixup_var_str_12(param, 1);
548
-		case 3:
549
-			return fixup_var_int_12(param, 1);
550
-	}
551
-	return 0;
552
-}
553
-
554
-
555
-/**
556
- *
557
- */
558
-static int auth_send_reply(struct sip_msg *msg, int code, char *reason,
559
-					char *hdr, int hdr_len)
560
-{
561
-	/* Add new headers if there are any */
562
-	if ((hdr!=NULL) && (hdr_len>0)) {
563
-		if (add_lump_rpl(msg, hdr, hdr_len, LUMP_RPL_HDR)==0) {
564
-			LM_ERR("failed to append hdr to reply\n");
565
-			return -1;
566
-		}
567
-	}
568
-
569
-	return slb.zreply(msg, code, reason);
570
-}
571
-
572
-/**
573
- *
574
- */
575
-static int auth_challenge(struct sip_msg *msg, char *p1, char *p2, int hftype)
576
-{
577
-    int flags = 0;
578
-    str realm  = {0, 0};
579
-	int ret;
580
-    str hf = {0, 0};
581
-	struct qp *qop = NULL;
582
-
583
-	ret = -1;
584
-
585
-	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
586
-		LM_ERR("failed to get realm value\n");
587
-		goto error;
588
-	}
589
-
590
-	if(realm.len==0) {
591
-		LM_ERR("invalid realm value - empty content\n");
592
-		goto error;
593
-	}
594
-
595
-	if (get_int_fparam(&flags, msg, (fparam_t*)p2) < 0) {
596
-		LM_ERR("invalid flags value\n");
597
-		goto error;
598
-	}
599
-	
600
-	if(flags&2) {
601
-		qop = &auth_qauthint;
602
-	} else if(flags&1) {
603
-		qop = &auth_qauth;
604
-	}
605
-	if (get_challenge_hf(msg, 0, &realm, NULL, NULL, qop, hftype, &hf) < 0) {
606
-		ERR("Error while creating challenge\n");
607
-		ret = -2;
608
-		goto error;
609
-	}
610
-	
611
-	ret = 1;
612
-	switch(hftype) {
613
-		case HDR_AUTHORIZATION_T:
614
-			if(auth_send_reply(msg, 401, "Unauthorized",
615
-						hf.s, hf.len) <0 )
616
-				ret = -3;
617
-		break;
618
-		case HDR_PROXYAUTH_T:
619
-			if(auth_send_reply(msg, 407, "Proxy Authentication Required",
620
-						hf.s, hf.len) <0 )
621
-				ret = -3;
622
-		break;
623
-	}
624
-	if(hf.s) pkg_free(hf.s);
625
-	return ret;
626
-
627
-error:
628
-	if(hf.s) pkg_free(hf.s);
629
-	if(!(flags&4)) {
630
-		if(auth_send_reply(msg, 500, "Internal Server Error", 0, 0) <0 )
631
-			ret = -4;
632
-	}
633
-	return ret;
634
-}
635
-
636
-/**
637
- *
638
- */
639
-static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags)
640
-{
641
-	return auth_challenge(msg, realm, flags, HDR_PROXYAUTH_T);
642
-}
643
-
644
-/**
645
- *
646
- */
647
-static int www_challenge(struct sip_msg *msg, char* realm, char *flags)
648
-{
649
-	return auth_challenge(msg, realm, flags, HDR_AUTHORIZATION_T);
650
-}
651
-
652
-/**
653
- * @brief fixup function for {www,proxy}_challenge
654
- */
655
-static int fixup_auth_challenge(void **param, int param_no)
656
-{
657
-	if(strlen((char*)*param)<=0) {
658
-		LM_ERR("empty parameter %d not allowed\n", param_no);
659
-		return -1;
660
-	}
661
-
662
-	switch(param_no) {
663
-		case 1:
664
-			return fixup_var_str_12(param, 1);
665
-		case 2:
666
-			return fixup_var_int_12(param, 1);
667
-	}
668
-	return 0;
669
-}
Browse code

auth(s): added enum for cfg return codes

- useful to detect if user does not exists or password is wrong
- pv_{www,proxy}_authenticate() functions updated to use them

Daniel-Constantin Mierla authored on 25/07/2010 12:45:32
Showing 1 changed files
... ...
@@ -399,7 +399,7 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
399 399
 	struct qp *qop = NULL;
400 400
 
401 401
 	cred = 0;
402
-	ret = -1;
402
+	ret = AUTH_ERROR;
403 403
 
404 404
 	if (get_str_fparam(&realm, msg, (fparam_t*)p1) < 0) {
405 405
 		LM_ERR("failed to get realm value\n");
... ...
@@ -430,24 +430,24 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
430 430
 		case ERROR:
431 431
 		case BAD_CREDENTIALS:
432 432
 			LM_DBG("error or bad credentials\n");
433
-			ret = -3;
433
+			ret = AUTH_ERROR;
434 434
 			goto end;
435 435
 		case CREATE_CHALLENGE:
436 436
 			LM_ERR("CREATE_CHALLENGE is not a valid state\n");
437
-			ret = -2;
437
+			ret = AUTH_ERROR;
438 438
 			goto end;
439 439
 		case DO_RESYNCHRONIZATION:
440 440
 			LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n");
441
-			ret = -2;
441
+			ret = AUTH_ERROR;
442 442
 			goto end;
443 443
 		case NOT_AUTHENTICATED:
444 444
 			LM_DBG("not authenticated\n");
445
-			ret = -1;
445
+			ret = AUTH_ERROR;
446 446
 			goto end;
447 447
 		case DO_AUTHENTICATION:
448 448
 			break;
449 449
 		case AUTHENTICATED:
450
-			ret = 1;
450
+			ret = AUTH_OK;
451 451
 			goto end;
452 452
 	}
453 453
 
... ...
@@ -465,28 +465,25 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
465 465
 	}
466 466
 
467 467
 	/* Recalculate response, it must be same to authorize successfully */
468
-	if (!auth_check_response(&(cred->digest),
469
-				&msg->first_line.u.request.method, ha1)) {
468
+	ret = auth_check_response(&(cred->digest),
469
+				&msg->first_line.u.request.method, ha1);
470
+	if(ret==AUTHENTICATED) {
471
+		ret = AUTH_OK;
470 472
 		switch(post_auth(msg, h)) {
471
-			case ERROR:
472
-			case BAD_CREDENTIALS:
473
-				ret = -2;
474
-				break;
475
-			case NOT_AUTHENTICATED:
476
-				ret = -1;
477
-				break;
478 473
 			case AUTHENTICATED:
479
-				ret = 1;
480 474
 				break;
481 475
 			default:
482
-				ret = -1;
476
+				ret = AUTH_ERROR;
483 477
 				break;
484 478
 		}
485 479
 	} else {
486
-		ret = -1;
480
+		if(ret==NOT_AUTHENTICATED)
481
+			ret = AUTH_INVALID_PASSWORD;
482
+		else
483
+			ret = AUTH_ERROR;
487 484
 	}
488 485
 
489
- end:
486
+end:
490 487
 	if (ret < 0) {
491 488
 		/* check if required to add challenge header as avp */
492 489
 		if(!(flags&14))
... ...
@@ -499,21 +496,21 @@ static int pv_authenticate(struct sip_msg *msg, char *p1, char *p2,
499 496
 		if (get_challenge_hf(msg, (cred ? cred->stale : 0),
500 497
 				&realm, NULL, NULL, qop, hftype, &hf) < 0) {
501 498
 			ERR("Error while creating challenge\n");
502
-			ret = -2;
499
+			ret = AUTH_ERROR;
503 500
 		} else {
504 501
 			val.s = hf;
505 502
 			if(add_avp(challenge_avpid.flags | AVP_VAL_STR,
506 503
 							challenge_avpid.name, val) < 0) {
507 504
 				LM_ERR("Error while creating attribute with challenge\n");
508
-				ret = -2;
505
+				ret = AUTH_ERROR;
509 506
 			}
510 507
 			pkg_free(hf.s);
511 508
 		}
512 509
 	}
513
-	return ret;
514 510
 
515 511
 error:
516
-	return -1;
512
+	return ret;
513
+
517 514
 }
518 515
 
519 516
 /**
... ...
@@ -539,6 +536,11 @@ static int pv_www_authenticate(struct sip_msg *msg, char* realm,
539 536
  */
540 537
 static int fixup_pv_auth(void **param, int param_no)
541 538
 {
539
+	if(strlen((char*)*param)<=0) {
540
+		LM_ERR("empty parameter %d not allowed\n", param_no);
541
+		return -1;
542
+	}
543
+
542 544
 	switch(param_no) {
543 545
 		case 1:
544 546
 		case 2:
... ...
@@ -652,6 +654,11 @@ static int www_challenge(struct sip_msg *msg, char* realm, char *flags)
652 654
  */
653 655
 static int fixup_auth_challenge(void **param, int param_no)
654 656
 {
657
+	if(strlen((char*)*param)<=0) {
658
+		LM_ERR("empty parameter %d not allowed\n", param_no);
659
+		return -1;
660
+	}
661
+
655 662
 	switch(param_no) {
656 663
 		case 1:
657 664
 			return fixup_var_str_12(param, 1);
Browse code

auth(s): new cfg functions

- pv_www_authenticate(real, passwd, flags)
- pv_proxy_authenticate(real, passwd, flags)
- perform Digest authentication taking password from a parameter
(can be cfg var)
- username is taken from Auth header
- realm and passwd must have values
- $td (To URI domain) can be used for REGISTER
- $fd (From URI domain) can be used for other SIP requests
- flags - bitmask of
- 1 - the content of password param is HA1/HA1b
- 2 - build challenge header (no qop) and add it in an avp
- 4 - build challenge header (qop=auth) and add it in an avp
- 8 - build challenge header (qop=auth-int) and add it in an avp
- when challenge header is built, append_to_reply() and sl reply
functions can be used to send appropriate SIP reply to challenge
for authentication
- www_challenge(realm, flags)
- proxy_challenge(realm, flags)
- send Digest authentication challenge (401 or 407 replies)
- realm must have value
- $td (To URI domain) can be used for REGISTER
- $fd (From URI domain) can be used for other SIP requests
- flags - bitmask of
- 1 - build challenge header (qop=auth) and add it in an avp
- 2 - build challenge header (qop=auth-int) and add it in an avp
- 4 - do not send '500 Internal Server Error' reply
automatically in failure cases (error code is returned to config)

Daniel-Constantin Mierla authored on 25/07/2010 10:47:25
Showing 1 changed files
... ...
@@ -47,6 +47,7 @@
47 47
 #include "../../mem/mem.h"
48 48
 #include "../../parser/digest/digest.h"
49 49
 #include "../../data_lump.h"
50
+#include "../../data_lump_rpl.h"
50 51
 #include "../../error.h"
51 52
 #include "../../ut.h"
52 53
 #include "../../modules/sl/sl.h"
... ...
@@ -56,6 +57,7 @@
56 57
 #include "nid.h"
57 58
 #include "nc.h"
58 59
 #include "ot_nonce.h"
60
+#include "rfc2617.h"
59 61
 
60 62
 MODULE_VERSION
61 63
 
... ...
@@ -77,6 +79,16 @@ static int mod_init(void);
77 79
  */
78 80
 int consume_credentials(struct sip_msg* msg, char* s1, char* s2);
79 81
 
82
+static int pv_proxy_authenticate(struct sip_msg* msg, char* realm,
83
+		char *passwd, char *flags);
84
+static int pv_www_authenticate(struct sip_msg* msg, char* realm,
85
+		char *passwd, char *flags);
86
+static int fixup_pv_auth(void **param, int param_no);
87
+
88
+static int proxy_challenge(struct sip_msg *msg, char* realm, char *flags);
89
+static int www_challenge(struct sip_msg *msg, char* realm, char *flags);
90
+static int fixup_auth_challenge(void **param, int param_no);
91
+
80 92
 
81 93
 /*
82 94
  * Module parameter variables
... ...
@@ -97,17 +109,42 @@ avp_ident_t challenge_avpid;
97 109
 str proxy_challenge_header = STR_STATIC_INIT("Proxy-Authenticate");
98 110
 str www_challenge_header = STR_STATIC_INIT("WWW-Authenticate");
99 111
 
100
-struct qp qop = {
112
+struct qp auth_qop = {
101 113
     STR_STATIC_INIT("auth"),
102 114
     QOP_AUTH
103 115
 };
104 116
 
117
+static struct qp auth_qauth = {
118
+    STR_STATIC_INIT("auth"),
119
+    QOP_AUTH
120
+};
121
+
122
+static struct qp auth_qauthint = {
123
+    STR_STATIC_INIT("auth-int"),
124
+    QOP_AUTHINT
125
+};
126
+
127
+/*! SL API structure */
128
+sl_api_t slb;
105 129
 
106 130
 /*
107 131
  * Exported functions
108 132
  */
109 133
 static cmd_export_t cmds[] = {
110
-    {"consume_credentials", consume_credentials,     0, 0, REQUEST_ROUTE},
134
+    {"consume_credentials",    consume_credentials,                  0,
135
+			0, REQUEST_ROUTE},
136
+    {"www_challenge",          (cmd_function)www_challenge,          2,
137
+			fixup_auth_challenge, REQUEST_ROUTE},
138
+    {"proxy_challenge",        (cmd_function)proxy_challenge,        2,
139
+			fixup_auth_challenge, REQUEST_ROUTE},
140
+    {"pv_www_authorize",       (cmd_function)pv_www_authenticate,    3,
141
+			fixup_pv_auth, REQUEST_ROUTE},
142
+    {"pv_www_authenticate",    (cmd_function)pv_www_authenticate,    3,
143
+			fixup_pv_auth, REQUEST_ROUTE},
144
+    {"pv_proxy_authorize",     (cmd_function)pv_proxy_authenticate,  3,
145
+			fixup_pv_auth, REQUEST_ROUTE},
146
+    {"pv_proxy_authenticate",  (cmd_function)pv_proxy_authenticate,  3,
147
+			fixup_pv_auth, REQUEST_ROUTE},
111 148
     {"bind_auth_s",           (cmd_function)bind_auth_s, 0, 0, 0        },
112 149
     {0, 0, 0, 0, 0}
113 150
 };
... ...
@@ -124,7 +161,7 @@ static param_export_t params[] = {
124 161
     {"challenge_attr",         PARAM_STR,    &challenge_attr        },
125 162
     {"proxy_challenge_header", PARAM_STR,    &proxy_challenge_header},
126 163
     {"www_challenge_header",   PARAM_STR,    &www_challenge_header  },
127
-    {"qop",                    PARAM_STR,    &qop.qop_str           },
164
+    {"qop",                    PARAM_STR,    &auth_qop.qop_str      },
128 165
 	{"auth_checks_register",   PARAM_INT,    &auth_checks_reg       },
129 166
 	{"auth_checks_no_dlg",     PARAM_INT,    &auth_checks_ood       },
130 167
 	{"auth_checks_in_dlg",     PARAM_INT,    &auth_checks_ind       },
... ...
@@ -202,6 +239,12 @@ static int mod_init(void)
202 239
     
203 240
     DBG("auth module - initializing\n");
204 241
     
242
+	/* bind the SL API */
243
+	if (sl_load_api(&slb)!=0) {
244
+		LM_ERR("cannot bind to SL API\n");
245
+		return -1;
246
+	}
247
+
205 248
 	/* If the parameter was not used */
206 249
     if (sec_param == 0) {
207 250
 		/* Generate secret using random generator */
... ...
@@ -237,12 +280,13 @@ static int mod_init(void)
237 280
     attr.len = challenge_attr.len - 1;
238 281
     
239 282
     if (parse_avp_ident(&attr, &challenge_avpid) < 0) {
240
-		ERR("auth: Error while parsing value of challenge_attr module parameter\n");
283
+		ERR("auth: Error while parsing value of challenge_attr module"
284
+				" parameter\n");
241 285
 		return -1;
242 286
     }
243