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