Wed, 10 Feb 2010 21:25:01 +0100
Extend uac_auth() of the UAC module to workaround CSEQ problems.
This logic is meant to complement that of changeset 17, which
added rich authentication credentials to the gw table and its
associated logic in the LCR module.
1 Index: modules/lcr/lcr_mod.c
2 diff -Nau modules/lcr/lcr_mod.c.orig modules/lcr/lcr_mod.c
3 --- modules/lcr/lcr_mod.c.orig 2010-01-18 12:32:29.697648000 +0100
4 +++ modules/lcr/lcr_mod.c 2010-02-10 19:52:14.838272303 +0100
5 @@ -114,9 +114,18 @@
7 #define PRIORITY_COL "priority"
9 +#define USER_COL "user"
10 +
11 +#define REALM_COL "realm"
12 +
13 +#define PASSWD_COL "passwd"
14 +
15 #define MAX_NO_OF_GWS 32
16 #define MAX_NO_OF_LCRS 256
17 #define MAX_PREFIX_LEN 256
18 +#define MAX_USER_LEN 64
19 +#define MAX_REALM_LEN 64
20 +#define MAX_PASSWD_LEN 64
21 #define MAX_TAG_LEN 16
22 #define MAX_FROM_URI_LEN 256
24 @@ -141,6 +150,12 @@
25 char tag[MAX_TAG_LEN + 1];
26 unsigned short tag_len;
27 unsigned int flags;
28 + char user[MAX_USER_LEN];
29 + unsigned short user_len;
30 + char realm[MAX_REALM_LEN];
31 + unsigned short realm_len;
32 + char passwd[MAX_PASSWD_LEN];
33 + unsigned short passwd_len;
34 };
36 struct lcr_info {
37 @@ -196,6 +211,9 @@
38 static str prefix_col = str_init(PREFIX_COL);
39 static str from_uri_col = str_init(FROM_URI_COL);
40 static str priority_col = str_init(PRIORITY_COL);
41 +static str user_col = str_init(USER_COL);
42 +static str realm_col = str_init(REALM_COL);
43 +static str passwd_col = str_init(PASSWD_COL);
45 /* timer */
46 int fr_inv_timer = DEF_FR_INV_TIMER;
47 @@ -208,6 +226,9 @@
48 static char *contact_avp_param = NULL;
49 static char *rpid_avp_param = NULL;
50 static char *flags_avp_param = NULL;
51 +static char *user_avp_param = NULL;
52 +static char *realm_avp_param = NULL;
53 +static char *passwd_avp_param = NULL;
55 /* prefix mode */
56 int prefix_mode_param = DEF_PREFIX_MODE;
57 @@ -239,6 +260,12 @@
58 static int_str rpid_avp;
59 static int flags_avp_type;
60 static int_str flags_avp;
61 +static int user_avp_type;
62 +static int_str user_avp;
63 +static int realm_avp_type;
64 +static int_str realm_avp;
65 +static int passwd_avp_type;
66 +static int_str passwd_avp;
68 struct gw_info **gws; /* Pointer to current gw table pointer */
69 struct gw_info *gws_1; /* Pointer to gw table 1 */
70 @@ -327,6 +354,12 @@
71 {"fr_inv_timer", INT_PARAM, &fr_inv_timer },
72 {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next },
73 {"prefix_mode", INT_PARAM, &prefix_mode_param },
74 + {"user_column", STR_PARAM, &user_col.s },
75 + {"realm_column", STR_PARAM, &realm_col.s },
76 + {"passwd_column", STR_PARAM, &passwd_col.s },
77 + {"auth_username_avp", STR_PARAM, &user_avp_param },
78 + {"auth_realm_avp", STR_PARAM, &realm_avp_param },
79 + {"auth_password_avp", STR_PARAM, &passwd_avp_param },
80 {0, 0, 0}
81 };
83 @@ -438,6 +471,9 @@
84 prefix_col.len = strlen(prefix_col.s);
85 from_uri_col.len = strlen(from_uri_col.s);
86 priority_col.len = strlen(priority_col.s);
87 + user_col.len = strlen(user_col.s);
88 + realm_col.len = strlen(realm_col.s);
89 + passwd_col.len = strlen(passwd_col.s);
91 /* Bind database */
92 if (lcr_db_bind(&db_url)) {
93 @@ -563,6 +599,60 @@
94 return -1;
95 }
97 + if (user_avp_param && *user_avp_param) {
98 + s.s = user_avp_param; s.len = strlen(s.s);
99 + if (pv_parse_spec(&s, &avp_spec)==0
100 + || avp_spec.type!=PVT_AVP) {
101 + LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param);
102 + return -1;
103 + }
104 +
105 + if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) {
106 + LM_ERR("Invalid AVP definition <%s>\n", user_avp_param);
107 + return -1;
108 + }
109 + user_avp_type = avp_flags;
110 + } else {
111 + LM_ERR("AVP user_avp has not been defined\n");
112 + return -1;
113 + }
114 +
115 + if (realm_avp_param && *realm_avp_param) {
116 + s.s = realm_avp_param; s.len = strlen(s.s);
117 + if (pv_parse_spec(&s, &avp_spec)==0
118 + || avp_spec.type!=PVT_AVP) {
119 + LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param);
120 + return -1;
121 + }
122 +
123 + if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) {
124 + LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param);
125 + return -1;
126 + }
127 + realm_avp_type = avp_flags;
128 + } else {
129 + LM_ERR("AVP realm_avp has not been defined\n");
130 + return -1;
131 + }
132 +
133 + if (passwd_avp_param && *passwd_avp_param) {
134 + s.s = passwd_avp_param; s.len = strlen(s.s);
135 + if (pv_parse_spec(&s, &avp_spec)==0
136 + || avp_spec.type!=PVT_AVP) {
137 + LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param);
138 + return -1;
139 + }
140 +
141 + if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) {
142 + LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param);
143 + return -1;
144 + }
145 + passwd_avp_type = avp_flags;
146 + } else {
147 + LM_ERR("AVP passwd_avp has not been defined\n");
148 + return -1;
149 + }
150 +
151 /* Check table version */
152 db_con_t* dbh;
153 if (lcr_dbf.init==0){
154 @@ -801,16 +891,17 @@
155 int reload_gws(void)
156 {
157 unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
158 - grp_id, priority;
159 + user_len, realm_len, passwd_len, grp_id, priority;
160 struct in_addr ip_addr;
161 unsigned int flags;
162 uri_type scheme;
163 uri_transport transport;
164 db_con_t* dbh;
165 char *tag, *prefix, *from_uri;
166 + char *user, *realm, *passwd;
167 db_res_t* res = NULL;
168 db_row_t* row;
169 - db_key_t gw_cols[8];
170 + db_key_t gw_cols[11];
171 db_key_t lcr_cols[4];
173 gw_cols[0] = &ip_addr_col;
174 @@ -823,6 +914,9 @@
175 in the two tables? (ge vw lcr) */
176 gw_cols[6] = &grp_id_col;
177 gw_cols[7] = &flags_col;
178 + gw_cols[8] = &user_col;
179 + gw_cols[9] = &realm_col;
180 + gw_cols[10] = &passwd_col;
182 lcr_cols[0] = &prefix_col;
183 lcr_cols[1] = &from_uri_col;
184 @@ -846,7 +940,7 @@
185 return -1;
186 }
188 - if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) {
189 + if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) {
190 LM_ERR("Failed to query gw data\n");
191 lcr_dbf.close(dbh);
192 return -1;
193 @@ -938,6 +1032,45 @@
194 lcr_dbf.close(dbh);
195 return -1;
196 }
197 + if (VAL_NULL(ROW_VALUES(row) + 8) == 1) {
198 + user_len = 0;
199 + user = (char *)0;
200 + } else {
201 + user = (char *)VAL_STRING(ROW_VALUES(row) + 8);
202 + user_len = strlen(user);
203 + if (user_len > MAX_USER_LEN) {
204 + LM_ERR("Too long gw user <%u>\n", user_len);
205 + lcr_dbf.free_result(dbh, res);
206 + lcr_dbf.close(dbh);
207 + return -1;
208 + }
209 + }
210 + if (VAL_NULL(ROW_VALUES(row) + 9) == 1) {
211 + realm_len = 0;
212 + realm = (char *)0;
213 + } else {
214 + realm = (char *)VAL_STRING(ROW_VALUES(row) + 9);
215 + realm_len = strlen(realm);
216 + if (realm_len > MAX_REALM_LEN) {
217 + LM_ERR("Too long gw realm <%u>\n", realm_len);
218 + lcr_dbf.free_result(dbh, res);
219 + lcr_dbf.close(dbh);
220 + return -1;
221 + }
222 + }
223 + if (VAL_NULL(ROW_VALUES(row) + 10) == 1) {
224 + passwd_len = 0;
225 + passwd = (char *)0;
226 + } else {
227 + passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10);
228 + passwd_len = strlen(passwd);
229 + if (passwd_len > MAX_PASSWD_LEN) {
230 + LM_ERR("Too long gw passwd <%u>\n", passwd_len);
231 + lcr_dbf.free_result(dbh, res);
232 + lcr_dbf.close(dbh);
233 + return -1;
234 + }
235 + }
236 if (*gws == gws_1) {
237 gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr;
238 gws_2[i].port = port;
239 @@ -949,6 +1082,15 @@
240 gws_2[i].tag_len = tag_len;
241 if (tag_len)
242 memcpy(&(gws_2[i].tag[0]), tag, tag_len);
243 + gws_2[i].user_len = user_len;
244 + if (user_len)
245 + memcpy(&(gws_2[i].user[0]), user, user_len);
246 + gws_2[i].realm_len = realm_len;
247 + if (realm_len)
248 + memcpy(&(gws_2[i].realm[0]), realm, realm_len);
249 + gws_2[i].passwd_len = passwd_len;
250 + if (passwd_len)
251 + memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len);
252 } else {
253 gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr;
254 gws_1[i].port = port;
255 @@ -960,6 +1102,15 @@
256 gws_1[i].tag_len = tag_len;
257 if (tag_len)
258 memcpy(&(gws_1[i].tag[0]), tag, tag_len);
259 + gws_1[i].user_len = user_len;
260 + if (user_len)
261 + memcpy(&(gws_1[i].user[0]), user, user_len);
262 + gws_1[i].realm_len = realm_len;
263 + if (realm_len)
264 + memcpy(&(gws_1[i].realm[0]), realm, realm_len);
265 + gws_1[i].passwd_len = passwd_len;
266 + if (passwd_len)
267 + memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len);
268 }
269 }
271 @@ -1141,6 +1292,21 @@
272 attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len);
273 if(attr == NULL)
274 return -1;
275 +
276 + attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6,
277 + (*gws)[i].user, (*gws)[i].user_len );
278 + if(attr == NULL)
279 + return -1;
280 +
281 + attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6,
282 + (*gws)[i].realm, (*gws)[i].realm_len );
283 + if(attr == NULL)
284 + return -1;
285 +
286 + attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6,
287 + (*gws)[i].passwd, (*gws)[i].passwd_len );
288 + if(attr == NULL)
289 + return -1;
290 }
292 for (i = 0; i < MAX_NO_OF_LCRS; i++) {
293 @@ -1184,6 +1350,9 @@
294 char ruri[MAX_URI_SIZE];
295 unsigned int i, j, k, index, addr, port, strip, gw_index,
296 duplicated_gw, flags, have_rpid_avp;
297 + char *user;
298 + char *realm;
299 + char *passwd;
300 uri_type scheme;
301 uri_transport transport;
302 struct ip_addr address;
303 @@ -1407,6 +1576,9 @@
304 transport = (*gws)[index].transport;
305 flags = (*gws)[index].flags;
306 strip = (*gws)[index].strip;
307 + user = (*gws)[index].user;
308 + realm = (*gws)[index].realm;
309 + passwd = (*gws)[index].passwd;
310 if (strip > ruri_user.len) {
311 LM_ERR("Strip count of gw is too large <%u>\n", strip);
312 goto skip;
313 @@ -1476,6 +1648,25 @@
314 val.s = value;
315 add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
316 LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s);
317 +
318 + value.s = user;
319 + value.len = strlen(value.s);
320 + val.s = value;
321 + add_avp(user_avp_type|AVP_VAL_STR, user_avp, val);
322 + LM_DBG("Added user_avp <%.*s>\n", value.len, value.s);
323 +
324 + value.s = realm;
325 + value.len = strlen(value.s);
326 + val.s = value;
327 + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val);
328 + LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s);
329 +
330 + value.s = passwd;
331 + value.len = strlen(value.s);
332 + val.s = value;
333 + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val);
334 + LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s);
335 +
336 skip:
337 continue;
338 }
339 @@ -1558,7 +1749,8 @@
340 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
341 {
342 int_str gw_uri_val, ruri_user_val, val;
343 - struct usr_avp *gu_avp, *ru_avp;
344 + int_str user_val, realm_val, passwd_val;
345 + struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp;
346 int rval;
347 str new_ruri;
348 char *at, *at_char, *strip_char, *endptr;
349 @@ -1575,6 +1767,35 @@
350 gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s);
351 gw_uri_val.s.s = at;
353 + /* Save gateway AVPs for use in script */
354 + usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0);
355 + rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0);
356 + pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0);
357 + if (!usr_avp) {
358 + LM_DBG("User AVP no set\n");
359 + return -1;
360 + }
361 + else {
362 + add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val);
363 + LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s);
364 + }
365 + if (!rlm_avp) {
366 + LM_DBG("Realm AVP no set\n");
367 + return -1;
368 + }
369 + else {
370 + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val);
371 + LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s);
372 + }
373 + if (!pwd_avp) {
374 + LM_DBG("Passwd AVP no set\n");
375 + return -1;
376 + }
377 + else {
378 + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val);
379 + LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s);
380 + }
381 +
382 /* Create new Request-URI taking URI user from ruri_user AVP
383 and other parts of from gateway URI AVP. */
384 ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
385 Index: scripts/db_berkeley/opensips/gw
386 diff -Nau scripts/db_berkeley/opensips/gw.orig scripts/db_berkeley/opensips/gw
387 --- scripts/db_berkeley/opensips/gw.orig 2010-01-18 12:31:09.312068000 +0100
388 +++ scripts/db_berkeley/opensips/gw 2010-02-10 19:57:18.467214268 +0100
389 @@ -1,5 +1,5 @@
390 METADATA_COLUMNS
391 -id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int)
392 +id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int) user(str) realm(str) passwd(str)
393 METADATA_KEY
394 1
395 METADATA_READONLY
396 @@ -7,4 +7,4 @@
397 METADATA_LOGFLAGS
398 0
399 METADATA_DEFAULTS
400 -NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0
401 +NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0|NULL|NULL|NULL
402 Index: scripts/dbtext/opensips/gw
403 diff -Nau scripts/dbtext/opensips/gw.orig scripts/dbtext/opensips/gw
404 --- scripts/dbtext/opensips/gw.orig 2010-01-18 12:31:01.221183000 +0100
405 +++ scripts/dbtext/opensips/gw 2010-02-10 19:57:19.099512686 +0100
406 @@ -1 +1 @@
407 -id(int,auto) gw_name(string) grp_id(int) ip_addr(string) port(int,null) uri_scheme(int,null) transport(int,null) strip(int,null) tag(string,null) flags(int)
408 +id(int,auto) gw_name(string) grp_id(int) ip_addr(string) port(int,null) uri_scheme(int,null) transport(int,null) strip(int,null) tag(string,null) flags(int) user(string,null) realm(string,null) passwd(string,null)
409 Index: scripts/mysql/lcr-create.sql
410 diff -Nau scripts/mysql/lcr-create.sql.orig scripts/mysql/lcr-create.sql
411 --- scripts/mysql/lcr-create.sql.orig 2010-01-18 12:31:05.995635000 +0100
412 +++ scripts/mysql/lcr-create.sql 2010-02-10 20:00:24.123864285 +0100
413 @@ -10,6 +10,9 @@
414 strip TINYINT UNSIGNED,
415 tag CHAR(16) DEFAULT NULL,
416 flags INT UNSIGNED DEFAULT 0 NOT NULL,
417 + user CHAR(16) DEFAULT NULL,
418 + realm CHAR(16) DEFAULT NULL,
419 + passwd CHAR(16) DEFAULT NULL,
420 CONSTRAINT gw_name_idx UNIQUE (gw_name)
421 ) ENGINE=MyISAM;
423 Index: scripts/oracle/lcr-create.sql
424 diff -Nau scripts/oracle/lcr-create.sql.orig scripts/oracle/lcr-create.sql
425 --- scripts/oracle/lcr-create.sql.orig 2010-01-18 12:31:09.035730000 +0100
426 +++ scripts/oracle/lcr-create.sql 2010-02-10 20:00:23.643867960 +0100
427 @@ -10,6 +10,9 @@
428 strip NUMBER(5),
429 tag VARCHAR2(16) DEFAULT NULL,
430 flags NUMBER(10) DEFAULT 0 NOT NULL,
431 + user VARCHAR2(16) DEFAULT NULL,
432 + realm VARCHAR2(16) DEFAULT NULL,
433 + passwd VARCHAR2(16) DEFAULT NULL,
434 CONSTRAINT gw_gw_name_idx UNIQUE (gw_name)
435 );
437 Index: scripts/postgres/lcr-create.sql
438 diff -Nau scripts/postgres/lcr-create.sql.orig scripts/postgres/lcr-create.sql
439 --- scripts/postgres/lcr-create.sql.orig 2010-01-18 12:31:09.151881000 +0100
440 +++ scripts/postgres/lcr-create.sql 2010-02-10 19:59:19.649196584 +0100
441 @@ -10,6 +10,9 @@
442 strip SMALLINT,
443 tag VARCHAR(16) DEFAULT NULL,
444 flags INTEGER DEFAULT 0 NOT NULL,
445 + user VARCHAR(16) DEFAULT NULL,
446 + realm VARCHAR(16) DEFAULT NULL,
447 + passwd VARCHAR(16) DEFAULT NULL,
448 CONSTRAINT gw_gw_name_idx UNIQUE (gw_name)
449 );