opensips/lcr-auth.diff

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
permissions
-rw-r--r--

Introduce authentication credential logic into the LCR module.
This logic is meant to complement that of changeset 18, adding
additional authentication flexibility to the UAC module.

     1 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