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
... ...
@@ -21,11 +21,11 @@
21 21
  *
22 22
  */
23 23
 
24
-#include "../../data_lump.h"
25
-#include "../../mem/mem.h"
26
-#include "../../parser/digest/digest.h"
27
-#include "../../usr_avp.h"
28
-#include "../../ut.h"
24
+#include "../../core/data_lump.h"
25
+#include "../../core/mem/mem.h"
26
+#include "../../core/parser/digest/digest.h"
27
+#include "../../core/usr_avp.h"
28
+#include "../../core/ut.h"
29 29
 #include "auth_mod.h"
30 30
 #include "challenge.h"
31 31
 #include "nonce.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,314 @@
1
+/*
2
+ * Digest Authentication Module
3
+ *
4
+ * Copyright (C) 2001-2003 FhG Fokus
5
+ *
6
+ * This file is part of Kamailio, a free SIP server.
7
+ *
8
+ * Kamailio is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * Kamailio is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
+ *
22
+ */
23
+
24
+#include "../../data_lump.h"
25
+#include "../../mem/mem.h"
26
+#include "../../parser/digest/digest.h"
27
+#include "../../usr_avp.h"
28
+#include "../../ut.h"
29
+#include "auth_mod.h"
30
+#include "challenge.h"
31
+#include "nonce.h"
32
+#include "api.h"
33
+#include "nc.h"
34
+#include "ot_nonce.h"
35
+
36
+#define QOP_PARAM_START   ", qop=\""
37
+#define QOP_PARAM_START_LEN (sizeof(QOP_PARAM_START)-1)
38
+#define QOP_PARAM_END     "\""
39
+#define QOP_PARAM_END_LEN (sizeof(QOP_PARAM_END)-1)
40
+#define STALE_PARAM	  ", stale=true"
41
+#define STALE_PARAM_LEN	  (sizeof(STALE_PARAM)-1)
42
+#define DIGEST_REALM	  ": Digest realm=\""
43
+#define DIGEST_REALM_LEN  (sizeof(DIGEST_REALM)-1)
44
+#define DIGEST_NONCE	  "\", nonce=\""
45
+#define DIGEST_NONCE_LEN  (sizeof(DIGEST_NONCE)-1)
46
+#define DIGEST_MD5	  ", algorithm=MD5"
47
+#define DIGEST_MD5_LEN	  (sizeof(DIGEST_MD5)-1)
48
+#define DIGEST_ALGORITHM     ", algorithm="
49
+#define DIGEST_ALGORITHM_LEN (sizeof(DIGEST_ALGORITHM)-1)
50
+
51
+
52
+extern str auth_realm_prefix;
53
+/**
54
+ * @brief Strip the beginning of a realm string
55
+ *
56
+ * Strip the beginning of a realm string, depending on the length of
57
+ * the realm_prefix.
58
+ * @param _realm realm string
59
+ */
60
+void strip_realm(str* _realm)
61
+{
62
+	/* no param defined -- return */
63
+	if (!auth_realm_prefix.len) return;
64
+
65
+	/* prefix longer than realm -- return */
66
+	if (auth_realm_prefix.len > _realm->len) return;
67
+
68
+	/* match ? -- if so, shorten realm -*/
69
+	if (memcmp(auth_realm_prefix.s, _realm->s, auth_realm_prefix.len) == 0) {
70
+		_realm->s += auth_realm_prefix.len;
71
+		_realm->len -= auth_realm_prefix.len;
72
+	}
73
+	return;
74
+}
75
+
76
+/**
77
+ * Calculate a new nonce.
78
+ * @param nonce  Pointer to a buffer of *nonce_len. It must have enough
79
+ *               space to hold the nonce. MAX_NONCE_LEN should be always
80
+ *               safe.
81
+ * @param nonce_len A value/result parameter. Initially it contains the
82
+ *                  nonce buffer length. If the length is too small, it
83
+ *                  will be set to the needed length and the function will
84
+ *                  return error immediately. After a succesfull call it will
85
+ *                  contain the size of nonce written into the buffer,
86
+ *                  without the terminating 0.
87
+ * @param cfg This is the value of one of the three module parameters that
88
+ *            control which optional checks are enabled/disabled and which
89
+ *            parts of the message will be included in the nonce string.
90
+ * @param msg     The message for which the nonce is computed. If
91
+ *                auth_extra_checks is set, the MD5 of some fields of the
92
+ *                message will be included in the  generated nonce.
93
+ * @return 0 on success and -1 on error
94
+ */
95
+int calc_new_nonce(char* nonce, int *nonce_len, int cfg, struct sip_msg* msg)
96
+{
97
+	int t;
98
+#if defined USE_NC || defined USE_OT_NONCE
99
+	unsigned int n_id;
100
+	unsigned char pool;
101
+	unsigned char pool_flags;
102
+#endif
103
+
104
+	t=time(0);
105
+#if defined USE_NC || defined USE_OT_NONCE
106
+	if (nc_enabled || otn_enabled){
107
+		pool=nid_get_pool();
108
+		n_id=nid_inc(pool);
109
+		pool_flags=0;
110
+#ifdef USE_NC
111
+		if (nc_enabled){
112
+			nc_new(n_id, pool);
113
+			pool_flags|=  NF_VALID_NC_ID;
114
+		}
115
+#endif
116
+#ifdef USE_OT_NONCE
117
+		if (otn_enabled){
118
+			otn_new(n_id, pool);
119
+			pool_flags|= NF_VALID_OT_ID;
120
+		}
121
+#endif
122
+	}else{
123
+		pool=0;
124
+		pool_flags=0;
125
+		n_id=0;
126
+	}
127
+	return calc_nonce(nonce, nonce_len, cfg, t, t + nonce_expire, n_id,
128
+				pool | pool_flags,
129
+				&secret1, &secret2, msg);
130
+#else  /* USE_NC || USE_OT_NONCE*/
131
+	return calc_nonce(nonce, nonce_len, cfg, t, t + nonce_expire,
132
+				&secret1, &secret2, msg);
133
+#endif /* USE_NC || USE_OT_NONCE */
134
+}
135
+
136
+
137
+/**
138
+ * Create and return {WWW,Proxy}-Authenticate header field
139
+ * @param nonce nonce value
140
+ * @param algorithm algorithm value
141
+ * @param qop qop value
142
+ * @return -1 on error, 0 on success
143
+ *
144
+ * The result is stored in param ahf.
145
+ * If nonce is not null that it is used, instead of call calc_nonce.
146
+ * If algorithm is not null that it is used irrespective of _PRINT_MD5
147
+ *
148
+ * Major usage of nonce and algorithm params is AKA authentication.
149
+ */
150
+int get_challenge_hf(struct sip_msg* msg, int stale, str* realm,
151
+		str* nonce, str* algorithm, struct qp* qop, int hftype, str *ahf)
152
+{
153
+	char *p;
154
+	str* hfn, hf;
155
+	int nonce_len, l, cfg;
156
+
157
+	if(!ahf)
158
+	{
159
+		LM_ERR("invalid output parameter\n");
160
+		return -1;
161
+	}
162
+
163
+	strip_realm(realm);
164
+	if (realm) {
165
+		LM_DBG("realm='%.*s'\n", realm->len, realm->s);
166
+	}
167
+	if (nonce) {
168
+		LM_DBG("nonce='%.*s'\n", nonce->len, nonce->s);
169
+	}
170
+	if (algorithm) {
171
+		LM_DBG("algorithm='%.*s'\n", algorithm->len, algorithm->s);
172
+	}
173
+	if (qop && qop->qop_parsed != QOP_UNSPEC) {
174
+		LM_DBG("qop='%.*s'\n", qop->qop_str.len, qop->qop_str.s);
175
+	}
176
+
177
+	if (hftype == HDR_PROXYAUTH_T) {
178
+		hfn = &proxy_challenge_header;
179
+	} else {
180
+		hfn = &www_challenge_header;
181
+	}
182
+
183
+	cfg = get_auth_checks(msg);
184
+
185
+	nonce_len = get_nonce_len(cfg, nc_enabled || otn_enabled);
186
+
187
+	hf.len = hfn->len;
188
+	if (realm) {
189
+		hf.len += DIGEST_REALM_LEN
190
+			+ realm->len;
191
+	}
192
+
193
+	hf.len += DIGEST_NONCE_LEN;
194
+
195
+	if (nonce) {
196
+		hf.len += nonce->len
197
+			+ 1; /* '"' */
198
+	}
199
+	else {
200
+		hf.len += nonce_len
201
+			+ 1; /* '"' */
202
+	}
203
+	hf.len += ((stale) ? STALE_PARAM_LEN : 0);
204
+	if (algorithm) {
205
+		hf.len += DIGEST_ALGORITHM_LEN + algorithm->len;
206
+	}
207
+	else {
208
+		hf.len += 0
209
+#ifdef _PRINT_MD5
210
+			+DIGEST_MD5_LEN
211
+#endif
212
+			;
213
+	}
214
+
215
+	if (qop && qop->qop_parsed != QOP_UNSPEC) {
216
+		hf.len += QOP_PARAM_START_LEN + qop->qop_str.len + QOP_PARAM_END_LEN;
217
+	}
218
+	hf.len += CRLF_LEN;
219
+	p = hf.s = pkg_malloc(hf.len);
220
+	if (!hf.s) {
221
+		LM_ERR("No memory left (%d bytes)\n", hf.len);
222
+		return -1;
223
+	}
224
+
225
+	memcpy(p, hfn->s, hfn->len); p += hfn->len;
226
+
227
+	if(realm){
228
+		memcpy(p, DIGEST_REALM, DIGEST_REALM_LEN); p += DIGEST_REALM_LEN;
229
+		memcpy(p, realm->s, realm->len); p += realm->len;
230
+	}
231
+
232
+	memcpy(p, DIGEST_NONCE, DIGEST_NONCE_LEN); p += DIGEST_NONCE_LEN;
233
+	if (nonce) {
234
+		memcpy(p, nonce->s, nonce->len); p += nonce->len;
235
+	}
236
+	else {
237
+		l=nonce_len;
238
+		if (calc_new_nonce(p, &l, cfg, msg) != 0)
239
+		{
240
+			LM_ERR("calc_nonce failed (len %d, needed %d)\n", nonce_len, l);
241
+			pkg_free(hf.s);
242
+			return -1;
243
+		}
244
+		p += l;
245
+	}
246
+	*p = '"'; p++;
247
+
248
+	if (qop && qop->qop_parsed != QOP_UNSPEC) {
249
+		memcpy(p, QOP_PARAM_START, QOP_PARAM_START_LEN);
250
+		p += QOP_PARAM_START_LEN;
251
+		memcpy(p, qop->qop_str.s, qop->qop_str.len);
252
+		p += qop->qop_str.len;
253
+		memcpy(p, QOP_PARAM_END, QOP_PARAM_END_LEN);
254
+		p += QOP_PARAM_END_LEN;
255
+	}
256
+	if (stale) {
257
+		memcpy(p, STALE_PARAM, STALE_PARAM_LEN);
258
+		p += STALE_PARAM_LEN;
259
+	}
260
+	if (algorithm) {
261
+		memcpy(p, DIGEST_ALGORITHM, DIGEST_ALGORITHM_LEN);
262
+		p += DIGEST_ALGORITHM_LEN;
263
+		memcpy(p, algorithm->s, algorithm->len);
264
+		p += algorithm->len;
265
+	}
266
+	else {
267
+#ifdef _PRINT_MD5
268
+		memcpy(p, DIGEST_MD5, DIGEST_MD5_LEN ); p += DIGEST_MD5_LEN;
269
+#endif
270
+	}
271
+	memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN;
272
+	hf.len=(int)(p-hf.s);	/* fix len, it might be smaller due to a smaller
273
+							 * nonce */
274
+
275
+	DBG("auth: '%.*s'\n", hf.len, ZSW(hf.s));
276
+	*ahf = hf;
277
+	return 0;
278
+}
279
+
280
+/**
281
+ * Create {WWW,Proxy}-Authenticate header field
282
+ * @param nonce nonce value
283
+ * @param algorithm algorithm value
284
+ * @return -1 on error, 0 on success
285
+ *
286
+ * The result is stored in an attribute.
287
+ * If nonce is not null that it is used, instead of call calc_nonce.
288
+ * If algorithm is not null that it is used irrespective of _PRINT_MD5
289
+ * The value of 'qop' module parameter is used.
290
+ *
291
+ * Major usage of nonce and algorithm params is AKA authentication.
292
+ */
293
+int build_challenge_hf(struct sip_msg* msg, int stale, str* realm,
294
+		str* nonce, str* algorithm, int hftype)
295
+{
296
+	str hf = {0, 0};
297
+	avp_value_t val;
298
+	int ret;
299
+
300
+	ret = get_challenge_hf(msg, stale, realm, nonce, algorithm, &auth_qop,
301
+			hftype, &hf);
302
+	if(ret < 0)
303
+		return ret;
304
+
305
+	val.s = hf;
306
+	if(add_avp(challenge_avpid.flags | AVP_VAL_STR, challenge_avpid.name, val)
307
+			< 0) {
308
+		LM_ERR("Error while creating attribute with challenge\n");
309
+		pkg_free(hf.s);
310
+		return -1;
311
+	}
312
+	pkg_free(hf.s);
313
+	return 0;
314
+}