Introduce authentication credential logic into the LCR module.

Wed, 10 Feb 2010 21:21:24 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 10 Feb 2010 21:21:24 +0100
changeset 17
733187d496d0
parent 16
c5c55937e44c
child 18
8ec65b8f6e2c

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.

opensips/lcr-auth.diff file | annotate | diff | comparison | revisions
opensips/lcr-auth.txt file | annotate | diff | comparison | revisions
opensips/modules/lcr/lcr_mod.c file | annotate | diff | comparison | revisions
opensips/scripts/db_berkeley/opensips/gw file | annotate | diff | comparison | revisions
opensips/scripts/dbtext/opensips/gw file | annotate | diff | comparison | revisions
opensips/scripts/mysql/lcr-create.sql file | annotate | diff | comparison | revisions
opensips/scripts/oracle/lcr-create.sql file | annotate | diff | comparison | revisions
opensips/scripts/postgres/lcr-create.sql file | annotate | diff | comparison | revisions
     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  

mercurial