michael@17: Index: modules/lcr/lcr_mod.c michael@17: diff -Nau modules/lcr/lcr_mod.c.orig modules/lcr/lcr_mod.c michael@17: --- modules/lcr/lcr_mod.c.orig 2010-01-18 12:32:29.697648000 +0100 michael@17: +++ modules/lcr/lcr_mod.c 2010-02-10 19:52:14.838272303 +0100 michael@17: @@ -114,9 +114,18 @@ michael@17: michael@17: #define PRIORITY_COL "priority" michael@17: michael@17: +#define USER_COL "user" michael@17: + michael@17: +#define REALM_COL "realm" michael@17: + michael@17: +#define PASSWD_COL "passwd" michael@17: + michael@17: #define MAX_NO_OF_GWS 32 michael@17: #define MAX_NO_OF_LCRS 256 michael@17: #define MAX_PREFIX_LEN 256 michael@17: +#define MAX_USER_LEN 64 michael@17: +#define MAX_REALM_LEN 64 michael@17: +#define MAX_PASSWD_LEN 64 michael@17: #define MAX_TAG_LEN 16 michael@17: #define MAX_FROM_URI_LEN 256 michael@17: michael@17: @@ -141,6 +150,12 @@ michael@17: char tag[MAX_TAG_LEN + 1]; michael@17: unsigned short tag_len; michael@17: unsigned int flags; michael@17: + char user[MAX_USER_LEN]; michael@17: + unsigned short user_len; michael@17: + char realm[MAX_REALM_LEN]; michael@17: + unsigned short realm_len; michael@17: + char passwd[MAX_PASSWD_LEN]; michael@17: + unsigned short passwd_len; michael@17: }; michael@17: michael@17: struct lcr_info { michael@17: @@ -196,6 +211,9 @@ michael@17: static str prefix_col = str_init(PREFIX_COL); michael@17: static str from_uri_col = str_init(FROM_URI_COL); michael@17: static str priority_col = str_init(PRIORITY_COL); michael@17: +static str user_col = str_init(USER_COL); michael@17: +static str realm_col = str_init(REALM_COL); michael@17: +static str passwd_col = str_init(PASSWD_COL); michael@17: michael@17: /* timer */ michael@17: int fr_inv_timer = DEF_FR_INV_TIMER; michael@17: @@ -208,6 +226,9 @@ michael@17: static char *contact_avp_param = NULL; michael@17: static char *rpid_avp_param = NULL; michael@17: static char *flags_avp_param = NULL; michael@17: +static char *user_avp_param = NULL; michael@17: +static char *realm_avp_param = NULL; michael@17: +static char *passwd_avp_param = NULL; michael@17: michael@17: /* prefix mode */ michael@17: int prefix_mode_param = DEF_PREFIX_MODE; michael@17: @@ -239,6 +260,12 @@ michael@17: static int_str rpid_avp; michael@17: static int flags_avp_type; michael@17: static int_str flags_avp; michael@17: +static int user_avp_type; michael@17: +static int_str user_avp; michael@17: +static int realm_avp_type; michael@17: +static int_str realm_avp; michael@17: +static int passwd_avp_type; michael@17: +static int_str passwd_avp; michael@17: michael@17: struct gw_info **gws; /* Pointer to current gw table pointer */ michael@17: struct gw_info *gws_1; /* Pointer to gw table 1 */ michael@17: @@ -327,6 +354,12 @@ michael@17: {"fr_inv_timer", INT_PARAM, &fr_inv_timer }, michael@17: {"fr_inv_timer_next", INT_PARAM, &fr_inv_timer_next }, michael@17: {"prefix_mode", INT_PARAM, &prefix_mode_param }, michael@17: + {"user_column", STR_PARAM, &user_col.s }, michael@17: + {"realm_column", STR_PARAM, &realm_col.s }, michael@17: + {"passwd_column", STR_PARAM, &passwd_col.s }, michael@17: + {"auth_username_avp", STR_PARAM, &user_avp_param }, michael@17: + {"auth_realm_avp", STR_PARAM, &realm_avp_param }, michael@17: + {"auth_password_avp", STR_PARAM, &passwd_avp_param }, michael@17: {0, 0, 0} michael@17: }; michael@17: michael@17: @@ -438,6 +471,9 @@ michael@17: prefix_col.len = strlen(prefix_col.s); michael@17: from_uri_col.len = strlen(from_uri_col.s); michael@17: priority_col.len = strlen(priority_col.s); michael@17: + user_col.len = strlen(user_col.s); michael@17: + realm_col.len = strlen(realm_col.s); michael@17: + passwd_col.len = strlen(passwd_col.s); michael@17: michael@17: /* Bind database */ michael@17: if (lcr_db_bind(&db_url)) { michael@17: @@ -563,6 +599,60 @@ michael@17: return -1; michael@17: } michael@17: michael@17: + if (user_avp_param && *user_avp_param) { michael@17: + s.s = user_avp_param; s.len = strlen(s.s); michael@17: + if (pv_parse_spec(&s, &avp_spec)==0 michael@17: + || avp_spec.type!=PVT_AVP) { michael@17: + LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param); michael@17: + return -1; michael@17: + } michael@17: + michael@17: + if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) { michael@17: + LM_ERR("Invalid AVP definition <%s>\n", user_avp_param); michael@17: + return -1; michael@17: + } michael@17: + user_avp_type = avp_flags; michael@17: + } else { michael@17: + LM_ERR("AVP user_avp has not been defined\n"); michael@17: + return -1; michael@17: + } michael@17: + michael@17: + if (realm_avp_param && *realm_avp_param) { michael@17: + s.s = realm_avp_param; s.len = strlen(s.s); michael@17: + if (pv_parse_spec(&s, &avp_spec)==0 michael@17: + || avp_spec.type!=PVT_AVP) { michael@17: + LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param); michael@17: + return -1; michael@17: + } michael@17: + michael@17: + if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) { michael@17: + LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param); michael@17: + return -1; michael@17: + } michael@17: + realm_avp_type = avp_flags; michael@17: + } else { michael@17: + LM_ERR("AVP realm_avp has not been defined\n"); michael@17: + return -1; michael@17: + } michael@17: + michael@17: + if (passwd_avp_param && *passwd_avp_param) { michael@17: + s.s = passwd_avp_param; s.len = strlen(s.s); michael@17: + if (pv_parse_spec(&s, &avp_spec)==0 michael@17: + || avp_spec.type!=PVT_AVP) { michael@17: + LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param); michael@17: + return -1; michael@17: + } michael@17: + michael@17: + if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) { michael@17: + LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param); michael@17: + return -1; michael@17: + } michael@17: + passwd_avp_type = avp_flags; michael@17: + } else { michael@17: + LM_ERR("AVP passwd_avp has not been defined\n"); michael@17: + return -1; michael@17: + } michael@17: + michael@17: /* Check table version */ michael@17: db_con_t* dbh; michael@17: if (lcr_dbf.init==0){ michael@17: @@ -801,16 +891,17 @@ michael@17: int reload_gws(void) michael@17: { michael@17: unsigned int i, port, strip, tag_len, prefix_len, from_uri_len, michael@17: - grp_id, priority; michael@17: + user_len, realm_len, passwd_len, grp_id, priority; michael@17: struct in_addr ip_addr; michael@17: unsigned int flags; michael@17: uri_type scheme; michael@17: uri_transport transport; michael@17: db_con_t* dbh; michael@17: char *tag, *prefix, *from_uri; michael@17: + char *user, *realm, *passwd; michael@17: db_res_t* res = NULL; michael@17: db_row_t* row; michael@17: - db_key_t gw_cols[8]; michael@17: + db_key_t gw_cols[11]; michael@17: db_key_t lcr_cols[4]; michael@17: michael@17: gw_cols[0] = &ip_addr_col; michael@17: @@ -823,6 +914,9 @@ michael@17: in the two tables? (ge vw lcr) */ michael@17: gw_cols[6] = &grp_id_col; michael@17: gw_cols[7] = &flags_col; michael@17: + gw_cols[8] = &user_col; michael@17: + gw_cols[9] = &realm_col; michael@17: + gw_cols[10] = &passwd_col; michael@17: michael@17: lcr_cols[0] = &prefix_col; michael@17: lcr_cols[1] = &from_uri_col; michael@17: @@ -846,7 +940,7 @@ michael@17: return -1; michael@17: } michael@17: michael@17: - if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) { michael@17: + if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) { michael@17: LM_ERR("Failed to query gw data\n"); michael@17: lcr_dbf.close(dbh); michael@17: return -1; michael@17: @@ -938,6 +1032,45 @@ michael@17: lcr_dbf.close(dbh); michael@17: return -1; michael@17: } michael@17: + if (VAL_NULL(ROW_VALUES(row) + 8) == 1) { michael@17: + user_len = 0; michael@17: + user = (char *)0; michael@17: + } else { michael@17: + user = (char *)VAL_STRING(ROW_VALUES(row) + 8); michael@17: + user_len = strlen(user); michael@17: + if (user_len > MAX_USER_LEN) { michael@17: + LM_ERR("Too long gw user <%u>\n", user_len); michael@17: + lcr_dbf.free_result(dbh, res); michael@17: + lcr_dbf.close(dbh); michael@17: + return -1; michael@17: + } michael@17: + } michael@17: + if (VAL_NULL(ROW_VALUES(row) + 9) == 1) { michael@17: + realm_len = 0; michael@17: + realm = (char *)0; michael@17: + } else { michael@17: + realm = (char *)VAL_STRING(ROW_VALUES(row) + 9); michael@17: + realm_len = strlen(realm); michael@17: + if (realm_len > MAX_REALM_LEN) { michael@17: + LM_ERR("Too long gw realm <%u>\n", realm_len); michael@17: + lcr_dbf.free_result(dbh, res); michael@17: + lcr_dbf.close(dbh); michael@17: + return -1; michael@17: + } michael@17: + } michael@17: + if (VAL_NULL(ROW_VALUES(row) + 10) == 1) { michael@17: + passwd_len = 0; michael@17: + passwd = (char *)0; michael@17: + } else { michael@17: + passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10); michael@17: + passwd_len = strlen(passwd); michael@17: + if (passwd_len > MAX_PASSWD_LEN) { michael@17: + LM_ERR("Too long gw passwd <%u>\n", passwd_len); michael@17: + lcr_dbf.free_result(dbh, res); michael@17: + lcr_dbf.close(dbh); michael@17: + return -1; michael@17: + } michael@17: + } michael@17: if (*gws == gws_1) { michael@17: gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr; michael@17: gws_2[i].port = port; michael@17: @@ -949,6 +1082,15 @@ michael@17: gws_2[i].tag_len = tag_len; michael@17: if (tag_len) michael@17: memcpy(&(gws_2[i].tag[0]), tag, tag_len); michael@17: + gws_2[i].user_len = user_len; michael@17: + if (user_len) michael@17: + memcpy(&(gws_2[i].user[0]), user, user_len); michael@17: + gws_2[i].realm_len = realm_len; michael@17: + if (realm_len) michael@17: + memcpy(&(gws_2[i].realm[0]), realm, realm_len); michael@17: + gws_2[i].passwd_len = passwd_len; michael@17: + if (passwd_len) michael@17: + memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len); michael@17: } else { michael@17: gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr; michael@17: gws_1[i].port = port; michael@17: @@ -960,6 +1102,15 @@ michael@17: gws_1[i].tag_len = tag_len; michael@17: if (tag_len) michael@17: memcpy(&(gws_1[i].tag[0]), tag, tag_len); michael@17: + gws_1[i].user_len = user_len; michael@17: + if (user_len) michael@17: + memcpy(&(gws_1[i].user[0]), user, user_len); michael@17: + gws_1[i].realm_len = realm_len; michael@17: + if (realm_len) michael@17: + memcpy(&(gws_1[i].realm[0]), realm, realm_len); michael@17: + gws_1[i].passwd_len = passwd_len; michael@17: + if (passwd_len) michael@17: + memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len); michael@17: } michael@17: } michael@17: michael@17: @@ -1141,6 +1292,21 @@ michael@17: attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len); michael@17: if(attr == NULL) michael@17: return -1; michael@17: + michael@17: + attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6, michael@17: + (*gws)[i].user, (*gws)[i].user_len ); michael@17: + if(attr == NULL) michael@17: + return -1; michael@17: + michael@17: + attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6, michael@17: + (*gws)[i].realm, (*gws)[i].realm_len ); michael@17: + if(attr == NULL) michael@17: + return -1; michael@17: + michael@17: + attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6, michael@17: + (*gws)[i].passwd, (*gws)[i].passwd_len ); michael@17: + if(attr == NULL) michael@17: + return -1; michael@17: } michael@17: michael@17: for (i = 0; i < MAX_NO_OF_LCRS; i++) { michael@17: @@ -1184,6 +1350,9 @@ michael@17: char ruri[MAX_URI_SIZE]; michael@17: unsigned int i, j, k, index, addr, port, strip, gw_index, michael@17: duplicated_gw, flags, have_rpid_avp; michael@17: + char *user; michael@17: + char *realm; michael@17: + char *passwd; michael@17: uri_type scheme; michael@17: uri_transport transport; michael@17: struct ip_addr address; michael@17: @@ -1407,6 +1576,9 @@ michael@17: transport = (*gws)[index].transport; michael@17: flags = (*gws)[index].flags; michael@17: strip = (*gws)[index].strip; michael@17: + user = (*gws)[index].user; michael@17: + realm = (*gws)[index].realm; michael@17: + passwd = (*gws)[index].passwd; michael@17: if (strip > ruri_user.len) { michael@17: LM_ERR("Strip count of gw is too large <%u>\n", strip); michael@17: goto skip; michael@17: @@ -1476,6 +1648,25 @@ michael@17: val.s = value; michael@17: add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val); michael@17: LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s); michael@17: + michael@17: + value.s = user; michael@17: + value.len = strlen(value.s); michael@17: + val.s = value; michael@17: + add_avp(user_avp_type|AVP_VAL_STR, user_avp, val); michael@17: + LM_DBG("Added user_avp <%.*s>\n", value.len, value.s); michael@17: + michael@17: + value.s = realm; michael@17: + value.len = strlen(value.s); michael@17: + val.s = value; michael@17: + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val); michael@17: + LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s); michael@17: + michael@17: + value.s = passwd; michael@17: + value.len = strlen(value.s); michael@17: + val.s = value; michael@17: + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val); michael@17: + LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s); michael@17: + michael@17: skip: michael@17: continue; michael@17: } michael@17: @@ -1558,7 +1749,8 @@ michael@17: static int next_gw(struct sip_msg* _m, char* _s1, char* _s2) michael@17: { michael@17: int_str gw_uri_val, ruri_user_val, val; michael@17: - struct usr_avp *gu_avp, *ru_avp; michael@17: + int_str user_val, realm_val, passwd_val; michael@17: + struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp; michael@17: int rval; michael@17: str new_ruri; michael@17: char *at, *at_char, *strip_char, *endptr; michael@17: @@ -1575,6 +1767,35 @@ michael@17: gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s); michael@17: gw_uri_val.s.s = at; michael@17: michael@17: + /* Save gateway AVPs for use in script */ michael@17: + usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0); michael@17: + rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0); michael@17: + pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0); michael@17: + if (!usr_avp) { michael@17: + LM_DBG("User AVP no set\n"); michael@17: + return -1; michael@17: + } michael@17: + else { michael@17: + add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val); michael@17: + LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s); michael@17: + } michael@17: + if (!rlm_avp) { michael@17: + LM_DBG("Realm AVP no set\n"); michael@17: + return -1; michael@17: + } michael@17: + else { michael@17: + add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val); michael@17: + LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s); michael@17: + } michael@17: + if (!pwd_avp) { michael@17: + LM_DBG("Passwd AVP no set\n"); michael@17: + return -1; michael@17: + } michael@17: + else { michael@17: + add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val); michael@17: + LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s); michael@17: + } michael@17: + michael@17: /* Create new Request-URI taking URI user from ruri_user AVP michael@17: and other parts of from gateway URI AVP. */ michael@17: ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp, michael@17: Index: scripts/db_berkeley/opensips/gw michael@17: diff -Nau scripts/db_berkeley/opensips/gw.orig scripts/db_berkeley/opensips/gw michael@17: --- scripts/db_berkeley/opensips/gw.orig 2010-01-18 12:31:09.312068000 +0100 michael@17: +++ scripts/db_berkeley/opensips/gw 2010-02-10 19:57:18.467214268 +0100 michael@17: @@ -1,5 +1,5 @@ michael@17: METADATA_COLUMNS michael@17: -id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int) michael@17: +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) michael@17: METADATA_KEY michael@17: 1 michael@17: METADATA_READONLY michael@17: @@ -7,4 +7,4 @@ michael@17: METADATA_LOGFLAGS michael@17: 0 michael@17: METADATA_DEFAULTS michael@17: -NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0 michael@17: +NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0|NULL|NULL|NULL michael@17: Index: scripts/dbtext/opensips/gw michael@17: diff -Nau scripts/dbtext/opensips/gw.orig scripts/dbtext/opensips/gw michael@17: --- scripts/dbtext/opensips/gw.orig 2010-01-18 12:31:01.221183000 +0100 michael@17: +++ scripts/dbtext/opensips/gw 2010-02-10 19:57:19.099512686 +0100 michael@17: @@ -1 +1 @@ michael@17: -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) michael@17: +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) michael@17: Index: scripts/mysql/lcr-create.sql michael@17: diff -Nau scripts/mysql/lcr-create.sql.orig scripts/mysql/lcr-create.sql michael@17: --- scripts/mysql/lcr-create.sql.orig 2010-01-18 12:31:05.995635000 +0100 michael@17: +++ scripts/mysql/lcr-create.sql 2010-02-10 20:00:24.123864285 +0100 michael@17: @@ -10,6 +10,9 @@ michael@17: strip TINYINT UNSIGNED, michael@17: tag CHAR(16) DEFAULT NULL, michael@17: flags INT UNSIGNED DEFAULT 0 NOT NULL, michael@17: + user CHAR(16) DEFAULT NULL, michael@17: + realm CHAR(16) DEFAULT NULL, michael@17: + passwd CHAR(16) DEFAULT NULL, michael@17: CONSTRAINT gw_name_idx UNIQUE (gw_name) michael@17: ) ENGINE=MyISAM; michael@17: michael@17: Index: scripts/oracle/lcr-create.sql michael@17: diff -Nau scripts/oracle/lcr-create.sql.orig scripts/oracle/lcr-create.sql michael@17: --- scripts/oracle/lcr-create.sql.orig 2010-01-18 12:31:09.035730000 +0100 michael@17: +++ scripts/oracle/lcr-create.sql 2010-02-10 20:00:23.643867960 +0100 michael@17: @@ -10,6 +10,9 @@ michael@17: strip NUMBER(5), michael@17: tag VARCHAR2(16) DEFAULT NULL, michael@17: flags NUMBER(10) DEFAULT 0 NOT NULL, michael@17: + user VARCHAR2(16) DEFAULT NULL, michael@17: + realm VARCHAR2(16) DEFAULT NULL, michael@17: + passwd VARCHAR2(16) DEFAULT NULL, michael@17: CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) michael@17: ); michael@17: michael@17: Index: scripts/postgres/lcr-create.sql michael@17: diff -Nau scripts/postgres/lcr-create.sql.orig scripts/postgres/lcr-create.sql michael@17: --- scripts/postgres/lcr-create.sql.orig 2010-01-18 12:31:09.151881000 +0100 michael@17: +++ scripts/postgres/lcr-create.sql 2010-02-10 19:59:19.649196584 +0100 michael@17: @@ -10,6 +10,9 @@ michael@17: strip SMALLINT, michael@17: tag VARCHAR(16) DEFAULT NULL, michael@17: flags INTEGER DEFAULT 0 NOT NULL, michael@17: + user VARCHAR(16) DEFAULT NULL, michael@17: + realm VARCHAR(16) DEFAULT NULL, michael@17: + passwd VARCHAR(16) DEFAULT NULL, michael@17: CONSTRAINT gw_gw_name_idx UNIQUE (gw_name) michael@17: ); michael@17: