opensips/lcr-auth.diff

Wed, 10 Feb 2010 21:25:01 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 10 Feb 2010 21:25:01 +0100
changeset 18
8ec65b8f6e2c
permissions
-rw-r--r--

Extend uac_auth() of the UAC module to workaround CSEQ problems.
This logic is meant to complement that of changeset 17, which
added rich authentication credentials to the gw table and its
associated logic in the LCR module.

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

mercurial