Wed, 10 Feb 2010 21:21:24 +0100
Introduce authentication credential logic into the LCR module.
This logic is meant to complement that of changeset 18, adding
additional authentication flexibility to the UAC module.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/opensips/lcr-auth.diff Wed Feb 10 21:21:24 2010 +0100 1.3 @@ -0,0 +1,450 @@ 1.4 +Index: modules/lcr/lcr_mod.c 1.5 +diff -Nau modules/lcr/lcr_mod.c.orig modules/lcr/lcr_mod.c 1.6 +--- modules/lcr/lcr_mod.c.orig 2010-01-18 12:32:29.697648000 +0100 1.7 ++++ modules/lcr/lcr_mod.c 2010-02-10 19:52:14.838272303 +0100 1.8 +@@ -114,9 +114,18 @@ 1.9 + 1.10 + #define PRIORITY_COL "priority" 1.11 + 1.12 ++#define USER_COL "user" 1.13 ++ 1.14 ++#define REALM_COL "realm" 1.15 ++ 1.16 ++#define PASSWD_COL "passwd" 1.17 ++ 1.18 + #define MAX_NO_OF_GWS 32 1.19 + #define MAX_NO_OF_LCRS 256 1.20 + #define MAX_PREFIX_LEN 256 1.21 ++#define MAX_USER_LEN 64 1.22 ++#define MAX_REALM_LEN 64 1.23 ++#define MAX_PASSWD_LEN 64 1.24 + #define MAX_TAG_LEN 16 1.25 + #define MAX_FROM_URI_LEN 256 1.26 + 1.27 +@@ -141,6 +150,12 @@ 1.28 + char tag[MAX_TAG_LEN + 1]; 1.29 + unsigned short tag_len; 1.30 + unsigned int flags; 1.31 ++ char user[MAX_USER_LEN]; 1.32 ++ unsigned short user_len; 1.33 ++ char realm[MAX_REALM_LEN]; 1.34 ++ unsigned short realm_len; 1.35 ++ char passwd[MAX_PASSWD_LEN]; 1.36 ++ unsigned short passwd_len; 1.37 + }; 1.38 + 1.39 + struct lcr_info { 1.40 +@@ -196,6 +211,9 @@ 1.41 + static str prefix_col = str_init(PREFIX_COL); 1.42 + static str from_uri_col = str_init(FROM_URI_COL); 1.43 + static str priority_col = str_init(PRIORITY_COL); 1.44 ++static str user_col = str_init(USER_COL); 1.45 ++static str realm_col = str_init(REALM_COL); 1.46 ++static str passwd_col = str_init(PASSWD_COL); 1.47 + 1.48 + /* timer */ 1.49 + int fr_inv_timer = DEF_FR_INV_TIMER; 1.50 +@@ -208,6 +226,9 @@ 1.51 + static char *contact_avp_param = NULL; 1.52 + static char *rpid_avp_param = NULL; 1.53 + static char *flags_avp_param = NULL; 1.54 ++static char *user_avp_param = NULL; 1.55 ++static char *realm_avp_param = NULL; 1.56 ++static char *passwd_avp_param = NULL; 1.57 + 1.58 + /* prefix mode */ 1.59 + int prefix_mode_param = DEF_PREFIX_MODE; 1.60 +@@ -239,6 +260,12 @@ 1.61 + static int_str rpid_avp; 1.62 + static int flags_avp_type; 1.63 + static int_str flags_avp; 1.64 ++static int user_avp_type; 1.65 ++static int_str user_avp; 1.66 ++static int realm_avp_type; 1.67 ++static int_str realm_avp; 1.68 ++static int passwd_avp_type; 1.69 ++static int_str passwd_avp; 1.70 + 1.71 + struct gw_info **gws; /* Pointer to current gw table pointer */ 1.72 + struct gw_info *gws_1; /* Pointer to gw table 1 */ 1.73 +@@ -327,6 +354,12 @@ 1.74 + {"fr_inv_timer", INT_PARAM, &fr_inv_timer }, 1.75 + {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next }, 1.76 + {"prefix_mode", INT_PARAM, &prefix_mode_param }, 1.77 ++ {"user_column", STR_PARAM, &user_col.s }, 1.78 ++ {"realm_column", STR_PARAM, &realm_col.s }, 1.79 ++ {"passwd_column", STR_PARAM, &passwd_col.s }, 1.80 ++ {"auth_username_avp", STR_PARAM, &user_avp_param }, 1.81 ++ {"auth_realm_avp", STR_PARAM, &realm_avp_param }, 1.82 ++ {"auth_password_avp", STR_PARAM, &passwd_avp_param }, 1.83 + {0, 0, 0} 1.84 + }; 1.85 + 1.86 +@@ -438,6 +471,9 @@ 1.87 + prefix_col.len = strlen(prefix_col.s); 1.88 + from_uri_col.len = strlen(from_uri_col.s); 1.89 + priority_col.len = strlen(priority_col.s); 1.90 ++ user_col.len = strlen(user_col.s); 1.91 ++ realm_col.len = strlen(realm_col.s); 1.92 ++ passwd_col.len = strlen(passwd_col.s); 1.93 + 1.94 + /* Bind database */ 1.95 + if (lcr_db_bind(&db_url)) { 1.96 +@@ -563,6 +599,60 @@ 1.97 + return -1; 1.98 + } 1.99 + 1.100 ++ if (user_avp_param && *user_avp_param) { 1.101 ++ s.s = user_avp_param; s.len = strlen(s.s); 1.102 ++ if (pv_parse_spec(&s, &avp_spec)==0 1.103 ++ || avp_spec.type!=PVT_AVP) { 1.104 ++ LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param); 1.105 ++ return -1; 1.106 ++ } 1.107 ++ 1.108 ++ if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) { 1.109 ++ LM_ERR("Invalid AVP definition <%s>\n", user_avp_param); 1.110 ++ return -1; 1.111 ++ } 1.112 ++ user_avp_type = avp_flags; 1.113 ++ } else { 1.114 ++ LM_ERR("AVP user_avp has not been defined\n"); 1.115 ++ return -1; 1.116 ++ } 1.117 ++ 1.118 ++ if (realm_avp_param && *realm_avp_param) { 1.119 ++ s.s = realm_avp_param; s.len = strlen(s.s); 1.120 ++ if (pv_parse_spec(&s, &avp_spec)==0 1.121 ++ || avp_spec.type!=PVT_AVP) { 1.122 ++ LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param); 1.123 ++ return -1; 1.124 ++ } 1.125 ++ 1.126 ++ if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) { 1.127 ++ LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param); 1.128 ++ return -1; 1.129 ++ } 1.130 ++ realm_avp_type = avp_flags; 1.131 ++ } else { 1.132 ++ LM_ERR("AVP realm_avp has not been defined\n"); 1.133 ++ return -1; 1.134 ++ } 1.135 ++ 1.136 ++ if (passwd_avp_param && *passwd_avp_param) { 1.137 ++ s.s = passwd_avp_param; s.len = strlen(s.s); 1.138 ++ if (pv_parse_spec(&s, &avp_spec)==0 1.139 ++ || avp_spec.type!=PVT_AVP) { 1.140 ++ LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param); 1.141 ++ return -1; 1.142 ++ } 1.143 ++ 1.144 ++ if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) { 1.145 ++ LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param); 1.146 ++ return -1; 1.147 ++ } 1.148 ++ passwd_avp_type = avp_flags; 1.149 ++ } else { 1.150 ++ LM_ERR("AVP passwd_avp has not been defined\n"); 1.151 ++ return -1; 1.152 ++ } 1.153 ++ 1.154 + /* Check table version */ 1.155 + db_con_t* dbh; 1.156 + if (lcr_dbf.init==0){ 1.157 +@@ -801,16 +891,17 @@ 1.158 + int reload_gws(void) 1.159 + { 1.160 + unsigned int i, port, strip, tag_len, prefix_len, from_uri_len, 1.161 +- grp_id, priority; 1.162 ++ user_len, realm_len, passwd_len, grp_id, priority; 1.163 + struct in_addr ip_addr; 1.164 + unsigned int flags; 1.165 + uri_type scheme; 1.166 + uri_transport transport; 1.167 + db_con_t* dbh; 1.168 + char *tag, *prefix, *from_uri; 1.169 ++ char *user, *realm, *passwd; 1.170 + db_res_t* res = NULL; 1.171 + db_row_t* row; 1.172 +- db_key_t gw_cols[8]; 1.173 ++ db_key_t gw_cols[11]; 1.174 + db_key_t lcr_cols[4]; 1.175 + 1.176 + gw_cols[0] = &ip_addr_col; 1.177 +@@ -823,6 +914,9 @@ 1.178 + in the two tables? (ge vw lcr) */ 1.179 + gw_cols[6] = &grp_id_col; 1.180 + gw_cols[7] = &flags_col; 1.181 ++ gw_cols[8] = &user_col; 1.182 ++ gw_cols[9] = &realm_col; 1.183 ++ gw_cols[10] = &passwd_col; 1.184 + 1.185 + lcr_cols[0] = &prefix_col; 1.186 + lcr_cols[1] = &from_uri_col; 1.187 +@@ -846,7 +940,7 @@ 1.188 + return -1; 1.189 + } 1.190 + 1.191 +- if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) { 1.192 ++ if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) { 1.193 + LM_ERR("Failed to query gw data\n"); 1.194 + lcr_dbf.close(dbh); 1.195 + return -1; 1.196 +@@ -938,6 +1032,45 @@ 1.197 + lcr_dbf.close(dbh); 1.198 + return -1; 1.199 + } 1.200 ++ if (VAL_NULL(ROW_VALUES(row) + 8) == 1) { 1.201 ++ user_len = 0; 1.202 ++ user = (char *)0; 1.203 ++ } else { 1.204 ++ user = (char *)VAL_STRING(ROW_VALUES(row) + 8); 1.205 ++ user_len = strlen(user); 1.206 ++ if (user_len > MAX_USER_LEN) { 1.207 ++ LM_ERR("Too long gw user <%u>\n", user_len); 1.208 ++ lcr_dbf.free_result(dbh, res); 1.209 ++ lcr_dbf.close(dbh); 1.210 ++ return -1; 1.211 ++ } 1.212 ++ } 1.213 ++ if (VAL_NULL(ROW_VALUES(row) + 9) == 1) { 1.214 ++ realm_len = 0; 1.215 ++ realm = (char *)0; 1.216 ++ } else { 1.217 ++ realm = (char *)VAL_STRING(ROW_VALUES(row) + 9); 1.218 ++ realm_len = strlen(realm); 1.219 ++ if (realm_len > MAX_REALM_LEN) { 1.220 ++ LM_ERR("Too long gw realm <%u>\n", realm_len); 1.221 ++ lcr_dbf.free_result(dbh, res); 1.222 ++ lcr_dbf.close(dbh); 1.223 ++ return -1; 1.224 ++ } 1.225 ++ } 1.226 ++ if (VAL_NULL(ROW_VALUES(row) + 10) == 1) { 1.227 ++ passwd_len = 0; 1.228 ++ passwd = (char *)0; 1.229 ++ } else { 1.230 ++ passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10); 1.231 ++ passwd_len = strlen(passwd); 1.232 ++ if (passwd_len > MAX_PASSWD_LEN) { 1.233 ++ LM_ERR("Too long gw passwd <%u>\n", passwd_len); 1.234 ++ lcr_dbf.free_result(dbh, res); 1.235 ++ lcr_dbf.close(dbh); 1.236 ++ return -1; 1.237 ++ } 1.238 ++ } 1.239 + if (*gws == gws_1) { 1.240 + gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr; 1.241 + gws_2[i].port = port; 1.242 +@@ -949,6 +1082,15 @@ 1.243 + gws_2[i].tag_len = tag_len; 1.244 + if (tag_len) 1.245 + memcpy(&(gws_2[i].tag[0]), tag, tag_len); 1.246 ++ gws_2[i].user_len = user_len; 1.247 ++ if (user_len) 1.248 ++ memcpy(&(gws_2[i].user[0]), user, user_len); 1.249 ++ gws_2[i].realm_len = realm_len; 1.250 ++ if (realm_len) 1.251 ++ memcpy(&(gws_2[i].realm[0]), realm, realm_len); 1.252 ++ gws_2[i].passwd_len = passwd_len; 1.253 ++ if (passwd_len) 1.254 ++ memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len); 1.255 + } else { 1.256 + gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr; 1.257 + gws_1[i].port = port; 1.258 +@@ -960,6 +1102,15 @@ 1.259 + gws_1[i].tag_len = tag_len; 1.260 + if (tag_len) 1.261 + memcpy(&(gws_1[i].tag[0]), tag, tag_len); 1.262 ++ gws_1[i].user_len = user_len; 1.263 ++ if (user_len) 1.264 ++ memcpy(&(gws_1[i].user[0]), user, user_len); 1.265 ++ gws_1[i].realm_len = realm_len; 1.266 ++ if (realm_len) 1.267 ++ memcpy(&(gws_1[i].realm[0]), realm, realm_len); 1.268 ++ gws_1[i].passwd_len = passwd_len; 1.269 ++ if (passwd_len) 1.270 ++ memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len); 1.271 + } 1.272 + } 1.273 + 1.274 +@@ -1141,6 +1292,21 @@ 1.275 + attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len); 1.276 + if(attr == NULL) 1.277 + return -1; 1.278 ++ 1.279 ++ attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6, 1.280 ++ (*gws)[i].user, (*gws)[i].user_len ); 1.281 ++ if(attr == NULL) 1.282 ++ return -1; 1.283 ++ 1.284 ++ attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6, 1.285 ++ (*gws)[i].realm, (*gws)[i].realm_len ); 1.286 ++ if(attr == NULL) 1.287 ++ return -1; 1.288 ++ 1.289 ++ attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6, 1.290 ++ (*gws)[i].passwd, (*gws)[i].passwd_len ); 1.291 ++ if(attr == NULL) 1.292 ++ return -1; 1.293 + } 1.294 + 1.295 + for (i = 0; i < MAX_NO_OF_LCRS; i++) { 1.296 +@@ -1184,6 +1350,9 @@ 1.297 + char ruri[MAX_URI_SIZE]; 1.298 + unsigned int i, j, k, index, addr, port, strip, gw_index, 1.299 + duplicated_gw, flags, have_rpid_avp; 1.300 ++ char *user; 1.301 ++ char *realm; 1.302 ++ char *passwd; 1.303 + uri_type scheme; 1.304 + uri_transport transport; 1.305 + struct ip_addr address; 1.306 +@@ -1407,6 +1576,9 @@ 1.307 + transport = (*gws)[index].transport; 1.308 + flags = (*gws)[index].flags; 1.309 + strip = (*gws)[index].strip; 1.310 ++ user = (*gws)[index].user; 1.311 ++ realm = (*gws)[index].realm; 1.312 ++ passwd = (*gws)[index].passwd; 1.313 + if (strip > ruri_user.len) { 1.314 + LM_ERR("Strip count of gw is too large <%u>\n", strip); 1.315 + goto skip; 1.316 +@@ -1476,6 +1648,25 @@ 1.317 + val.s = value; 1.318 + add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val); 1.319 + LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s); 1.320 ++ 1.321 ++ value.s = user; 1.322 ++ value.len = strlen(value.s); 1.323 ++ val.s = value; 1.324 ++ add_avp(user_avp_type|AVP_VAL_STR, user_avp, val); 1.325 ++ LM_DBG("Added user_avp <%.*s>\n", value.len, value.s); 1.326 ++ 1.327 ++ value.s = realm; 1.328 ++ value.len = strlen(value.s); 1.329 ++ val.s = value; 1.330 ++ add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val); 1.331 ++ LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s); 1.332 ++ 1.333 ++ value.s = passwd; 1.334 ++ value.len = strlen(value.s); 1.335 ++ val.s = value; 1.336 ++ add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val); 1.337 ++ LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s); 1.338 ++ 1.339 + skip: 1.340 + continue; 1.341 + } 1.342 +@@ -1558,7 +1749,8 @@ 1.343 + static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) 1.344 + { 1.345 + int_str gw_uri_val, ruri_user_val, val; 1.346 +- struct usr_avp *gu_avp, *ru_avp; 1.347 ++ int_str user_val, realm_val, passwd_val; 1.348 ++ struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp; 1.349 + int rval; 1.350 + str new_ruri; 1.351 + char *at, *at_char, *strip_char, *endptr; 1.352 +@@ -1575,6 +1767,35 @@ 1.353 + gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s); 1.354 + gw_uri_val.s.s = at; 1.355 + 1.356 ++ /* Save gateway AVPs for use in script */ 1.357 ++ usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0); 1.358 ++ rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0); 1.359 ++ pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0); 1.360 ++ if (!usr_avp) { 1.361 ++ LM_DBG("User AVP no set\n"); 1.362 ++ return -1; 1.363 ++ } 1.364 ++ else { 1.365 ++ add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val); 1.366 ++ LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s); 1.367 ++ } 1.368 ++ if (!rlm_avp) { 1.369 ++ LM_DBG("Realm AVP no set\n"); 1.370 ++ return -1; 1.371 ++ } 1.372 ++ else { 1.373 ++ add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val); 1.374 ++ LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s); 1.375 ++ } 1.376 ++ if (!pwd_avp) { 1.377 ++ LM_DBG("Passwd AVP no set\n"); 1.378 ++ return -1; 1.379 ++ } 1.380 ++ else { 1.381 ++ add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val); 1.382 ++ LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s); 1.383 ++ } 1.384 ++ 1.385 + /* Create new Request-URI taking URI user from ruri_user AVP 1.386 + and other parts of from gateway URI AVP. */ 1.387 + ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp, 1.388 +Index: scripts/db_berkeley/opensips/gw 1.389 +diff -Nau scripts/db_berkeley/opensips/gw.orig scripts/db_berkeley/opensips/gw 1.390 +--- scripts/db_berkeley/opensips/gw.orig 2010-01-18 12:31:09.312068000 +0100 1.391 ++++ scripts/db_berkeley/opensips/gw 2010-02-10 19:57:18.467214268 +0100 1.392 +@@ -1,5 +1,5 @@ 1.393 + METADATA_COLUMNS 1.394 +-id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int) 1.395 ++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) 1.396 + METADATA_KEY 1.397 + 1 1.398 + METADATA_READONLY 1.399 +@@ -7,4 +7,4 @@ 1.400 + METADATA_LOGFLAGS 1.401 + 0 1.402 + METADATA_DEFAULTS 1.403 +-NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0 1.404 ++NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0|NULL|NULL|NULL 1.405 +Index: scripts/dbtext/opensips/gw 1.406 +diff -Nau scripts/dbtext/opensips/gw.orig scripts/dbtext/opensips/gw 1.407 +--- scripts/dbtext/opensips/gw.orig 2010-01-18 12:31:01.221183000 +0100 1.408 ++++ scripts/dbtext/opensips/gw 2010-02-10 19:57:19.099512686 +0100 1.409 +@@ -1 +1 @@ 1.410 +-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) 1.411 ++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) 1.412 +Index: scripts/mysql/lcr-create.sql 1.413 +diff -Nau scripts/mysql/lcr-create.sql.orig scripts/mysql/lcr-create.sql 1.414 +--- scripts/mysql/lcr-create.sql.orig 2010-01-18 12:31:05.995635000 +0100 1.415 ++++ scripts/mysql/lcr-create.sql 2010-02-10 20:00:24.123864285 +0100 1.416 +@@ -10,6 +10,9 @@ 1.417 + strip TINYINT UNSIGNED, 1.418 + tag CHAR(16) DEFAULT NULL, 1.419 + flags INT UNSIGNED DEFAULT 0 NOT NULL, 1.420 ++ user CHAR(16) DEFAULT NULL, 1.421 ++ realm CHAR(16) DEFAULT NULL, 1.422 ++ passwd CHAR(16) DEFAULT NULL, 1.423 + CONSTRAINT gw_name_idx UNIQUE (gw_name) 1.424 + ) ENGINE=MyISAM; 1.425 + 1.426 +Index: scripts/oracle/lcr-create.sql 1.427 +diff -Nau scripts/oracle/lcr-create.sql.orig scripts/oracle/lcr-create.sql 1.428 +--- scripts/oracle/lcr-create.sql.orig 2010-01-18 12:31:09.035730000 +0100 1.429 ++++ scripts/oracle/lcr-create.sql 2010-02-10 20:00:23.643867960 +0100 1.430 +@@ -10,6 +10,9 @@ 1.431 + strip NUMBER(5), 1.432 + tag VARCHAR2(16) DEFAULT NULL, 1.433 + flags NUMBER(10) DEFAULT 0 NOT NULL, 1.434 ++ user VARCHAR2(16) DEFAULT NULL, 1.435 ++ realm VARCHAR2(16) DEFAULT NULL, 1.436 ++ passwd VARCHAR2(16) DEFAULT NULL, 1.437 + CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) 1.438 + ); 1.439 + 1.440 +Index: scripts/postgres/lcr-create.sql 1.441 +diff -Nau scripts/postgres/lcr-create.sql.orig scripts/postgres/lcr-create.sql 1.442 +--- scripts/postgres/lcr-create.sql.orig 2010-01-18 12:31:09.151881000 +0100 1.443 ++++ scripts/postgres/lcr-create.sql 2010-02-10 19:59:19.649196584 +0100 1.444 +@@ -10,6 +10,9 @@ 1.445 + strip SMALLINT, 1.446 + tag VARCHAR(16) DEFAULT NULL, 1.447 + flags INTEGER DEFAULT 0 NOT NULL, 1.448 ++ user VARCHAR(16) DEFAULT NULL, 1.449 ++ realm VARCHAR(16) DEFAULT NULL, 1.450 ++ passwd VARCHAR(16) DEFAULT NULL, 1.451 + CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) 1.452 + ); 1.453 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/opensips/lcr-auth.txt Wed Feb 10 21:21:24 2010 +0100 2.3 @@ -0,0 +1,73 @@ 2.4 +LCR module authentication extention (contribution) 2.5 + 2.6 +Rationale 2.7 + 2.8 +An orthoganal approach to abstract authentication logic out of the 2.9 +routing script improves administration by keeping unnecessarily hard 2.10 +coded authentication credentials out of the routing script. 2.11 + 2.12 +Usage 2.13 + 2.14 +The new lcr module parameters which achieve this are 'auth_realm_avp', 2.15 +'auth_username_avp', and 'auth_password_avp'. To specify where the lcr 2.16 +module should write these values set the parameters like so: 2.17 + 2.18 + modparam("lcr", "auth_realm_avp", "$avp(s:arealm)") 2.19 + modparam("lcr", "auth_username_avp", "$avp(s:auser)") 2.20 + modparam("lcr", "auth_password_avp", "$avp(s:apass)") 2.21 + 2.22 +Typically these parameters are used in conjunction with the uac modules 2.23 +uac_auth() function, which uses similar variables which are specified in 2.24 +a similar manner. In fact, the parameters of both lcr and uac modules 2.25 +can be specified at the same time like so: 2.26 + 2.27 + modparam("uac|lcr", "auth_realm_avp", "$avp(s:arealm)") 2.28 + modparam("uac|lcr", "auth_username_avp", "$avp(s:auser)") 2.29 + modparam("uac|lcr", "auth_password_avp", "$avp(s:apass)") 2.30 + 2.31 +In addition to the existing column module parameters, specify the name 2.32 +of each of the new gw table columns like so: 2.33 + 2.34 + modparam("lcr", "user_column", "user") 2.35 + modparam("lcr", "realm_column", "realm") 2.36 + modparam("lcr", "passwd_column", "passwd") 2.37 + 2.38 +At this point the new functionality of the lcr module is ready to be 2.39 +used. Enter values into the gw table with its new columns and call the 2.40 +standard lcr module functions load_gws() and next_gw(). 2.41 + 2.42 +Result 2.43 + 2.44 +After calling load_gws() and next_gw(), inspect the variables associated 2.45 +with the user, realm, and password columns (see the modparam entries) to 2.46 +find that the lcr module can now hand off authentication credentials to 2.47 +other modules with ease. 2.48 + 2.49 +Location 2.50 + 2.51 +http://scm.europalab.com/contrib/opensips/ 2.52 +http://scm.europalab.com/contrib/file/tip/opensips/ 2.53 +http://scm.europalab.com/contrib/file/tip/opensips/lcr-auth.txt 2.54 +http://scm.europalab.com/contrib/file/tip/opensips/lcr-auth.diff 2.55 + 2.56 +Instructions 2.57 + 2.58 +To integrate this contributed logic into the source code tree of 2.59 +a OpenSIPS distribution, download the unified diff and use the 2.60 +patch(1) command: 2.61 + 2.62 + $ cd /tmp && mkdir lcr-patch && cd lcr-patch 2.63 + $ wget http://scm.europalab.com/contrib/raw-file/tip/opensips/lcr-auth.diff 2.64 + $ tar zxf /tmp/opensips-<version>-tls.tar.gz 2.65 + $ cd opensips-<version>-tls 2.66 + $ patch -p0 <../lcr-auth.diff 2.67 + 2.68 +Disclaimer 2.69 + 2.70 +This software contribution is based on source code from OpenSIPS SVN 2.71 +revision 6590. The author makes no guarantees as to this contribution. 2.72 +A user who downloads and executes it does so at his own risk. 2.73 + 2.74 +Michael Schloh von Bennewitz 2.75 +http://michael.schloh.com/ 2.76 +Wednsday, 10. February 2010
3.1 --- a/opensips/modules/lcr/lcr_mod.c Wed Feb 10 21:14:04 2010 +0100 3.2 +++ b/opensips/modules/lcr/lcr_mod.c Wed Feb 10 21:21:24 2010 +0100 3.3 @@ -114,9 +114,18 @@ 3.4 3.5 #define PRIORITY_COL "priority" 3.6 3.7 +#define USER_COL "user" 3.8 + 3.9 +#define REALM_COL "realm" 3.10 + 3.11 +#define PASSWD_COL "passwd" 3.12 + 3.13 #define MAX_NO_OF_GWS 32 3.14 #define MAX_NO_OF_LCRS 256 3.15 #define MAX_PREFIX_LEN 256 3.16 +#define MAX_USER_LEN 64 3.17 +#define MAX_REALM_LEN 64 3.18 +#define MAX_PASSWD_LEN 64 3.19 #define MAX_TAG_LEN 16 3.20 #define MAX_FROM_URI_LEN 256 3.21 3.22 @@ -141,6 +150,12 @@ 3.23 char tag[MAX_TAG_LEN + 1]; 3.24 unsigned short tag_len; 3.25 unsigned int flags; 3.26 + char user[MAX_USER_LEN]; 3.27 + unsigned short user_len; 3.28 + char realm[MAX_REALM_LEN]; 3.29 + unsigned short realm_len; 3.30 + char passwd[MAX_PASSWD_LEN]; 3.31 + unsigned short passwd_len; 3.32 }; 3.33 3.34 struct lcr_info { 3.35 @@ -196,6 +211,9 @@ 3.36 static str prefix_col = str_init(PREFIX_COL); 3.37 static str from_uri_col = str_init(FROM_URI_COL); 3.38 static str priority_col = str_init(PRIORITY_COL); 3.39 +static str user_col = str_init(USER_COL); 3.40 +static str realm_col = str_init(REALM_COL); 3.41 +static str passwd_col = str_init(PASSWD_COL); 3.42 3.43 /* timer */ 3.44 int fr_inv_timer = DEF_FR_INV_TIMER; 3.45 @@ -208,6 +226,9 @@ 3.46 static char *contact_avp_param = NULL; 3.47 static char *rpid_avp_param = NULL; 3.48 static char *flags_avp_param = NULL; 3.49 +static char *user_avp_param = NULL; 3.50 +static char *realm_avp_param = NULL; 3.51 +static char *passwd_avp_param = NULL; 3.52 3.53 /* prefix mode */ 3.54 int prefix_mode_param = DEF_PREFIX_MODE; 3.55 @@ -239,6 +260,12 @@ 3.56 static int_str rpid_avp; 3.57 static int flags_avp_type; 3.58 static int_str flags_avp; 3.59 +static int user_avp_type; 3.60 +static int_str user_avp; 3.61 +static int realm_avp_type; 3.62 +static int_str realm_avp; 3.63 +static int passwd_avp_type; 3.64 +static int_str passwd_avp; 3.65 3.66 struct gw_info **gws; /* Pointer to current gw table pointer */ 3.67 struct gw_info *gws_1; /* Pointer to gw table 1 */ 3.68 @@ -327,6 +354,12 @@ 3.69 {"fr_inv_timer", INT_PARAM, &fr_inv_timer }, 3.70 {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next }, 3.71 {"prefix_mode", INT_PARAM, &prefix_mode_param }, 3.72 + {"user_column", STR_PARAM, &user_col.s }, 3.73 + {"realm_column", STR_PARAM, &realm_col.s }, 3.74 + {"passwd_column", STR_PARAM, &passwd_col.s }, 3.75 + {"auth_username_avp", STR_PARAM, &user_avp_param }, 3.76 + {"auth_realm_avp", STR_PARAM, &realm_avp_param }, 3.77 + {"auth_password_avp", STR_PARAM, &passwd_avp_param }, 3.78 {0, 0, 0} 3.79 }; 3.80 3.81 @@ -438,6 +471,9 @@ 3.82 prefix_col.len = strlen(prefix_col.s); 3.83 from_uri_col.len = strlen(from_uri_col.s); 3.84 priority_col.len = strlen(priority_col.s); 3.85 + user_col.len = strlen(user_col.s); 3.86 + realm_col.len = strlen(realm_col.s); 3.87 + passwd_col.len = strlen(passwd_col.s); 3.88 3.89 /* Bind database */ 3.90 if (lcr_db_bind(&db_url)) { 3.91 @@ -563,6 +599,60 @@ 3.92 return -1; 3.93 } 3.94 3.95 + if (user_avp_param && *user_avp_param) { 3.96 + s.s = user_avp_param; s.len = strlen(s.s); 3.97 + if (pv_parse_spec(&s, &avp_spec)==0 3.98 + || avp_spec.type!=PVT_AVP) { 3.99 + LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param); 3.100 + return -1; 3.101 + } 3.102 + 3.103 + if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) { 3.104 + LM_ERR("Invalid AVP definition <%s>\n", user_avp_param); 3.105 + return -1; 3.106 + } 3.107 + user_avp_type = avp_flags; 3.108 + } else { 3.109 + LM_ERR("AVP user_avp has not been defined\n"); 3.110 + return -1; 3.111 + } 3.112 + 3.113 + if (realm_avp_param && *realm_avp_param) { 3.114 + s.s = realm_avp_param; s.len = strlen(s.s); 3.115 + if (pv_parse_spec(&s, &avp_spec)==0 3.116 + || avp_spec.type!=PVT_AVP) { 3.117 + LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param); 3.118 + return -1; 3.119 + } 3.120 + 3.121 + if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) { 3.122 + LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param); 3.123 + return -1; 3.124 + } 3.125 + realm_avp_type = avp_flags; 3.126 + } else { 3.127 + LM_ERR("AVP realm_avp has not been defined\n"); 3.128 + return -1; 3.129 + } 3.130 + 3.131 + if (passwd_avp_param && *passwd_avp_param) { 3.132 + s.s = passwd_avp_param; s.len = strlen(s.s); 3.133 + if (pv_parse_spec(&s, &avp_spec)==0 3.134 + || avp_spec.type!=PVT_AVP) { 3.135 + LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param); 3.136 + return -1; 3.137 + } 3.138 + 3.139 + if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) { 3.140 + LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param); 3.141 + return -1; 3.142 + } 3.143 + passwd_avp_type = avp_flags; 3.144 + } else { 3.145 + LM_ERR("AVP passwd_avp has not been defined\n"); 3.146 + return -1; 3.147 + } 3.148 + 3.149 /* Check table version */ 3.150 db_con_t* dbh; 3.151 if (lcr_dbf.init==0){ 3.152 @@ -801,16 +891,17 @@ 3.153 int reload_gws(void) 3.154 { 3.155 unsigned int i, port, strip, tag_len, prefix_len, from_uri_len, 3.156 - grp_id, priority; 3.157 + user_len, realm_len, passwd_len, grp_id, priority; 3.158 struct in_addr ip_addr; 3.159 unsigned int flags; 3.160 uri_type scheme; 3.161 uri_transport transport; 3.162 db_con_t* dbh; 3.163 char *tag, *prefix, *from_uri; 3.164 + char *user, *realm, *passwd; 3.165 db_res_t* res = NULL; 3.166 db_row_t* row; 3.167 - db_key_t gw_cols[8]; 3.168 + db_key_t gw_cols[11]; 3.169 db_key_t lcr_cols[4]; 3.170 3.171 gw_cols[0] = &ip_addr_col; 3.172 @@ -823,6 +914,9 @@ 3.173 in the two tables? (ge vw lcr) */ 3.174 gw_cols[6] = &grp_id_col; 3.175 gw_cols[7] = &flags_col; 3.176 + gw_cols[8] = &user_col; 3.177 + gw_cols[9] = &realm_col; 3.178 + gw_cols[10] = &passwd_col; 3.179 3.180 lcr_cols[0] = &prefix_col; 3.181 lcr_cols[1] = &from_uri_col; 3.182 @@ -846,7 +940,7 @@ 3.183 return -1; 3.184 } 3.185 3.186 - if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) { 3.187 + if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) { 3.188 LM_ERR("Failed to query gw data\n"); 3.189 lcr_dbf.close(dbh); 3.190 return -1; 3.191 @@ -938,6 +1032,45 @@ 3.192 lcr_dbf.close(dbh); 3.193 return -1; 3.194 } 3.195 + if (VAL_NULL(ROW_VALUES(row) + 8) == 1) { 3.196 + user_len = 0; 3.197 + user = (char *)0; 3.198 + } else { 3.199 + user = (char *)VAL_STRING(ROW_VALUES(row) + 8); 3.200 + user_len = strlen(user); 3.201 + if (user_len > MAX_USER_LEN) { 3.202 + LM_ERR("Too long gw user <%u>\n", user_len); 3.203 + lcr_dbf.free_result(dbh, res); 3.204 + lcr_dbf.close(dbh); 3.205 + return -1; 3.206 + } 3.207 + } 3.208 + if (VAL_NULL(ROW_VALUES(row) + 9) == 1) { 3.209 + realm_len = 0; 3.210 + realm = (char *)0; 3.211 + } else { 3.212 + realm = (char *)VAL_STRING(ROW_VALUES(row) + 9); 3.213 + realm_len = strlen(realm); 3.214 + if (realm_len > MAX_REALM_LEN) { 3.215 + LM_ERR("Too long gw realm <%u>\n", realm_len); 3.216 + lcr_dbf.free_result(dbh, res); 3.217 + lcr_dbf.close(dbh); 3.218 + return -1; 3.219 + } 3.220 + } 3.221 + if (VAL_NULL(ROW_VALUES(row) + 10) == 1) { 3.222 + passwd_len = 0; 3.223 + passwd = (char *)0; 3.224 + } else { 3.225 + passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10); 3.226 + passwd_len = strlen(passwd); 3.227 + if (passwd_len > MAX_PASSWD_LEN) { 3.228 + LM_ERR("Too long gw passwd <%u>\n", passwd_len); 3.229 + lcr_dbf.free_result(dbh, res); 3.230 + lcr_dbf.close(dbh); 3.231 + return -1; 3.232 + } 3.233 + } 3.234 if (*gws == gws_1) { 3.235 gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr; 3.236 gws_2[i].port = port; 3.237 @@ -949,6 +1082,15 @@ 3.238 gws_2[i].tag_len = tag_len; 3.239 if (tag_len) 3.240 memcpy(&(gws_2[i].tag[0]), tag, tag_len); 3.241 + gws_2[i].user_len = user_len; 3.242 + if (user_len) 3.243 + memcpy(&(gws_2[i].user[0]), user, user_len); 3.244 + gws_2[i].realm_len = realm_len; 3.245 + if (realm_len) 3.246 + memcpy(&(gws_2[i].realm[0]), realm, realm_len); 3.247 + gws_2[i].passwd_len = passwd_len; 3.248 + if (passwd_len) 3.249 + memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len); 3.250 } else { 3.251 gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr; 3.252 gws_1[i].port = port; 3.253 @@ -960,6 +1102,15 @@ 3.254 gws_1[i].tag_len = tag_len; 3.255 if (tag_len) 3.256 memcpy(&(gws_1[i].tag[0]), tag, tag_len); 3.257 + gws_1[i].user_len = user_len; 3.258 + if (user_len) 3.259 + memcpy(&(gws_1[i].user[0]), user, user_len); 3.260 + gws_1[i].realm_len = realm_len; 3.261 + if (realm_len) 3.262 + memcpy(&(gws_1[i].realm[0]), realm, realm_len); 3.263 + gws_1[i].passwd_len = passwd_len; 3.264 + if (passwd_len) 3.265 + memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len); 3.266 } 3.267 } 3.268 3.269 @@ -1141,6 +1292,21 @@ 3.270 attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len); 3.271 if(attr == NULL) 3.272 return -1; 3.273 + 3.274 + attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6, 3.275 + (*gws)[i].user, (*gws)[i].user_len ); 3.276 + if(attr == NULL) 3.277 + return -1; 3.278 + 3.279 + attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6, 3.280 + (*gws)[i].realm, (*gws)[i].realm_len ); 3.281 + if(attr == NULL) 3.282 + return -1; 3.283 + 3.284 + attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6, 3.285 + (*gws)[i].passwd, (*gws)[i].passwd_len ); 3.286 + if(attr == NULL) 3.287 + return -1; 3.288 } 3.289 3.290 for (i = 0; i < MAX_NO_OF_LCRS; i++) { 3.291 @@ -1184,6 +1350,9 @@ 3.292 char ruri[MAX_URI_SIZE]; 3.293 unsigned int i, j, k, index, addr, port, strip, gw_index, 3.294 duplicated_gw, flags, have_rpid_avp; 3.295 + char *user; 3.296 + char *realm; 3.297 + char *passwd; 3.298 uri_type scheme; 3.299 uri_transport transport; 3.300 struct ip_addr address; 3.301 @@ -1407,6 +1576,9 @@ 3.302 transport = (*gws)[index].transport; 3.303 flags = (*gws)[index].flags; 3.304 strip = (*gws)[index].strip; 3.305 + user = (*gws)[index].user; 3.306 + realm = (*gws)[index].realm; 3.307 + passwd = (*gws)[index].passwd; 3.308 if (strip > ruri_user.len) { 3.309 LM_ERR("Strip count of gw is too large <%u>\n", strip); 3.310 goto skip; 3.311 @@ -1476,6 +1648,25 @@ 3.312 val.s = value; 3.313 add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val); 3.314 LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s); 3.315 + 3.316 + value.s = user; 3.317 + value.len = strlen(value.s); 3.318 + val.s = value; 3.319 + add_avp(user_avp_type|AVP_VAL_STR, user_avp, val); 3.320 + LM_DBG("Added user_avp <%.*s>\n", value.len, value.s); 3.321 + 3.322 + value.s = realm; 3.323 + value.len = strlen(value.s); 3.324 + val.s = value; 3.325 + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val); 3.326 + LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s); 3.327 + 3.328 + value.s = passwd; 3.329 + value.len = strlen(value.s); 3.330 + val.s = value; 3.331 + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val); 3.332 + LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s); 3.333 + 3.334 skip: 3.335 continue; 3.336 } 3.337 @@ -1558,7 +1749,8 @@ 3.338 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) 3.339 { 3.340 int_str gw_uri_val, ruri_user_val, val; 3.341 - struct usr_avp *gu_avp, *ru_avp; 3.342 + int_str user_val, realm_val, passwd_val; 3.343 + struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp; 3.344 int rval; 3.345 str new_ruri; 3.346 char *at, *at_char, *strip_char, *endptr; 3.347 @@ -1575,6 +1767,35 @@ 3.348 gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s); 3.349 gw_uri_val.s.s = at; 3.350 3.351 + /* Save gateway AVPs for use in script */ 3.352 + usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0); 3.353 + rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0); 3.354 + pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0); 3.355 + if (!usr_avp) { 3.356 + LM_DBG("User AVP no set\n"); 3.357 + return -1; 3.358 + } 3.359 + else { 3.360 + add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val); 3.361 + LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s); 3.362 + } 3.363 + if (!rlm_avp) { 3.364 + LM_DBG("Realm AVP no set\n"); 3.365 + return -1; 3.366 + } 3.367 + else { 3.368 + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val); 3.369 + LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s); 3.370 + } 3.371 + if (!pwd_avp) { 3.372 + LM_DBG("Passwd AVP no set\n"); 3.373 + return -1; 3.374 + } 3.375 + else { 3.376 + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val); 3.377 + LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s); 3.378 + } 3.379 + 3.380 /* Create new Request-URI taking URI user from ruri_user AVP 3.381 and other parts of from gateway URI AVP. */ 3.382 ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
4.1 --- a/opensips/scripts/db_berkeley/opensips/gw Wed Feb 10 21:14:04 2010 +0100 4.2 +++ b/opensips/scripts/db_berkeley/opensips/gw Wed Feb 10 21:21:24 2010 +0100 4.3 @@ -1,5 +1,5 @@ 4.4 METADATA_COLUMNS 4.5 -id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int) 4.6 +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) 4.7 METADATA_KEY 4.8 1 4.9 METADATA_READONLY 4.10 @@ -7,4 +7,4 @@ 4.11 METADATA_LOGFLAGS 4.12 0 4.13 METADATA_DEFAULTS 4.14 -NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0 4.15 +NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0|NULL|NULL|NULL
5.1 --- a/opensips/scripts/dbtext/opensips/gw Wed Feb 10 21:14:04 2010 +0100 5.2 +++ b/opensips/scripts/dbtext/opensips/gw Wed Feb 10 21:21:24 2010 +0100 5.3 @@ -1,1 +1,1 @@ 5.4 -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) 5.5 +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)
6.1 --- a/opensips/scripts/mysql/lcr-create.sql Wed Feb 10 21:14:04 2010 +0100 6.2 +++ b/opensips/scripts/mysql/lcr-create.sql Wed Feb 10 21:21:24 2010 +0100 6.3 @@ -10,6 +10,9 @@ 6.4 strip TINYINT UNSIGNED, 6.5 tag CHAR(16) DEFAULT NULL, 6.6 flags INT UNSIGNED DEFAULT 0 NOT NULL, 6.7 + user CHAR(16) DEFAULT NULL, 6.8 + realm CHAR(16) DEFAULT NULL, 6.9 + passwd CHAR(16) DEFAULT NULL, 6.10 CONSTRAINT gw_name_idx UNIQUE (gw_name) 6.11 ) ENGINE=MyISAM; 6.12
7.1 --- a/opensips/scripts/oracle/lcr-create.sql Wed Feb 10 21:14:04 2010 +0100 7.2 +++ b/opensips/scripts/oracle/lcr-create.sql Wed Feb 10 21:21:24 2010 +0100 7.3 @@ -10,6 +10,9 @@ 7.4 strip NUMBER(5), 7.5 tag VARCHAR2(16) DEFAULT NULL, 7.6 flags NUMBER(10) DEFAULT 0 NOT NULL, 7.7 + user VARCHAR2(16) DEFAULT NULL, 7.8 + realm VARCHAR2(16) DEFAULT NULL, 7.9 + passwd VARCHAR2(16) DEFAULT NULL, 7.10 CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) 7.11 ); 7.12
8.1 --- a/opensips/scripts/postgres/lcr-create.sql Wed Feb 10 21:14:04 2010 +0100 8.2 +++ b/opensips/scripts/postgres/lcr-create.sql Wed Feb 10 21:21:24 2010 +0100 8.3 @@ -10,6 +10,9 @@ 8.4 strip SMALLINT, 8.5 tag VARCHAR(16) DEFAULT NULL, 8.6 flags INTEGER DEFAULT 0 NOT NULL, 8.7 + user VARCHAR(16) DEFAULT NULL, 8.8 + realm VARCHAR(16) DEFAULT NULL, 8.9 + passwd VARCHAR(16) DEFAULT NULL, 8.10 CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) 8.11 ); 8.12