opensips/uac-reauth.diff

Mon, 16 Jan 2012 23:08:14 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 16 Jan 2012 23:08:14 +0100
changeset 23
d783b433388d
permissions
-rw-r--r--

Inconclusively complete possibly missing fields. This change introduces
inconsistencies difficult to correct given incomplete documentation of
IPKG and OPKG packaging standards.

     1 Index: modules/uac/auth.c
     2 diff -Nau modules/uac/auth.c.orig modules/uac/auth.c
     3 --- modules/uac/auth.c.orig	2010-01-18 12:32:26.152280000 +0100
     4 +++ modules/uac/auth.c	2010-02-10 20:25:06.204228079 +0100
     5 @@ -24,6 +24,7 @@
     6   * ---------
     7   *  2005-01-31  first version (ramona)
     8   *  2006-03-02  UAC authentication looks first in AVPs for credential (bogdan)
     9 + *  2010-01-18  UAC replaces proxy-auth entries with new credentials (msvb)
    10   */
    13 @@ -375,14 +376,172 @@
    14  	HASHHEX response;
    15  	str *new_hdr;
    17 +	/* pretransact */
    18 +	int nret = 0;
    19 +	pv_value_t pv_val;
    20 +	str *newuri = 0;
    21 +	struct uac_credential *tst = 0;
    22 +	struct hdr_field *tmp_hdr = 0;
    23 +	struct hdr_field *del_hdr = 0;
    24 +
    25 +
    26 +	/* Goes something like this...                          */
    27 +	/* HA1 = echo -n 'username:realm:password' | md5sum     */
    28 +	/*       echo -n 'itsme:mydom.com:stupidpass' | md5sum  */
    29 +	/* HA2 = echo -n 'message:uri' | md5sum                 */
    30 +	/*       echo -n 'INVITE:sip:danc@ing.fool.es' | md5sum */
    31 +	/* Response = echo -n 'HA1:nonce:HA2' | md5sum          */
    32  	/* get transaction */
    33  	t = uac_tmb.t_gett();
    34 -	if (t==T_UNDEFINED || t==T_NULL_CELL)
    35 -	{
    36 -		LM_CRIT("no current transaction found\n");
    37 -		goto error;
    38 -	}
    39 +	if (t==T_UNDEFINED || t==T_NULL_CELL) {
    40 +		/* begin without any transaction */
    41 +		/* set relevant structure variables */
    42 +		crd = 0;
    43 +		crd = pkg_malloc(sizeof(struct uac_credential));
    44 +		if (!crd) {
    45 +			LM_ERR("no more pkg memory\n");
    46 +			goto error;
    47 +		}
    48 +
    49 +		/* set the realm from existing UAC message */
    50 +		tmp_hdr = msg->proxy_auth;
    51 +		del_hdr = 0;
    52 +		while (tmp_hdr) {
    53 +			crd->realm.s = strchr(strstr(tmp_hdr->body.s, "realm="), '"') + 1;
    54 +			crd->realm.len = strchr(crd->realm.s, '"') - crd->realm.s;
    55 +			if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \
    56 +				&& pv_val.rs.len>0) /* ensure realm is the desired one */
    57 +				if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0)
    58 +					del_hdr = tmp_hdr;
    59 +			tmp_hdr = tmp_hdr->sibling;
    60 +		}
    61 +		if (del_hdr)
    62 +			crd->realm = pv_val.rs;	/* success */
    63 +		else
    64 +			nret++;					/* failure */
    65 +
    66 +		/* set username from new AVP proxy values */
    67 +		if(pv_get_spec_value(msg, &auth_username_spec, &pv_val)!=0 \
    68 +			|| pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0)
    69 +			nret++; /* signal failure with nonzero value */
    70 +		else
    71 +			crd->user = pv_val.rs;
    72 +
    73 +		/* set password from new AVP proxy values */
    74 +		if(pv_get_spec_value(msg, &auth_password_spec, &pv_val)!=0 \
    75 +			|| pv_val.flags&PV_VAL_NULL || pv_val.rs.len<=0)
    76 +			nret++; /* signal failure with nonzero value */
    77 +		else
    78 +			crd->passwd = pv_val.rs;
    79 +
    80 +		if (nret) { /* if not found, look into predefined credentials */
    81 +			tst = lookup_realm(&crd->realm);
    82 +
    83 +			if (tst==0) { /* found? */
    84 +				LM_DBG("no credential for realm \"%.*s\"\n", \
    85 +					crd->realm.len, crd->realm.s);
    86 +				pkg_free(crd);
    87 +				goto error;
    88 +			}
    89 +
    90 +			crd = tst; /* use predefined credentials */
    91 +			/* set the realm from existing UAC message */
    92 +			tmp_hdr = msg->proxy_auth;
    93 +			del_hdr = 0;
    94 +			while (tmp_hdr) {
    95 +				if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \
    96 +					&& pv_val.rs.len>0) /* ensure realm is the desired one */
    97 +					if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0)
    98 +						del_hdr = tmp_hdr;
    99 +				tmp_hdr = tmp_hdr->sibling;
   100 +			}
   101 +			if (del_hdr == 0) { /* proxy-auth header matching realm not found */
   102 +				LM_DBG("no credential for realm \"%.*s\"\n", \
   103 +					crd->realm.len, crd->realm.s);
   104 +				pkg_free(crd);
   105 +				goto error;
   106 +			}
   107 +		}
   108 +
   109 +		/* set the uri from existing UAC message */
   110 +		newuri = pkg_malloc(sizeof(str));
   111 +		if (!newuri) {
   112 +			LM_ERR("no more pkg memory\n");
   113 +			goto error;
   114 +		}
   115 +		newuri->s = pkg_malloc(msg->new_uri.len);
   116 +		if (!newuri->s) {
   117 +			LM_ERR("no more pkg memory\n");
   118 +			pkg_free(newuri);
   119 +			goto error;
   120 +		}
   121 +		newuri->len = msg->new_uri.len;
   122 +		strncpy(newuri->s, msg->new_uri.s, msg->new_uri.len);
   123 +		if (!newuri->s) {
   124 +			LM_DBG("failed to retrieve URI from UAC message\n");
   125 +			pkg_free(newuri->s);
   126 +			pkg_free(newuri);
   127 +			goto error;
   128 +		}
   129 +
   130 +		/* set the nonce from existing UAC message */
   131 +		tmp_hdr = msg->proxy_auth;
   132 +		auth.nonce.len = 0;
   133 +		auth.nonce.s = 0;
   134 +		while (tmp_hdr) {
   135 +			if(pv_get_spec_value(msg, &auth_realm_spec, &pv_val)==0 \
   136 +				&& pv_val.rs.len>0) /* ensure realm is the desired one */
   137 +				if (strncmp(crd->realm.s, pv_val.rs.s, crd->realm.len)==0) {
   138 +					auth.nonce.s = strchr(strstr(tmp_hdr->body.s, "nonce="), '"') + 1;
   139 +					auth.nonce.len = strchr(auth.nonce.s, '"') - auth.nonce.s;
   140 +				}
   141 +			tmp_hdr = tmp_hdr->sibling;
   142 +		}
   143 +		if (auth.nonce.s == 0) {
   144 +			LM_DBG("failed to retrieve nonce from UAC message\n");
   145 +			pkg_free(crd);
   146 +			goto error;
   147 +		}
   148 +
   149 +		/* do authentication */
   150 +		do_uac_auth(msg, newuri, crd, &auth, response);
   151 +		if (response==0) {
   152 +			LM_ERR("failed to calculate challenge response\n");
   153 +			pkg_free(crd);
   154 +			goto error;
   155 +		}
   156 +
   157 +		/* build the authorization header */
   158 +		new_hdr = build_authorization_hdr(407, newuri, crd, &auth, response);
   159 +		if (new_hdr==0) {
   160 +			LM_ERR("failed to build authorization hdr\n");
   161 +			pkg_free(crd);
   162 +			goto error;
   163 +		}
   164 +
   165 +		/* remove the old proxy-auth header and relink message index    */
   166 +		/* before updating the authorization credentials of the message */
   167 +		if (del_hdr) { /* updated a record and must remove the old one  */
   168 +			if (del_lump(msg, del_hdr->name.s - msg->buf, del_hdr->len, 0)==0) {
   169 +				LM_ERR("can't remove credentials\n");
   170 +				pkg_free(crd);
   171 +				goto error;
   172 +			}
   173 +		}
   174 +
   175 +		/* so far, so good -> add the header and set the proper RURI */
   176 +		if (apply_urihdr_changes(msg, newuri, new_hdr)<0)
   177 +		{
   178 +			LM_ERR("failed to apply changes\n");
   179 +			pkg_free(crd);
   180 +			goto error;
   181 +		}
   182 +
   183 +		pkg_free(crd); /* finished calculating new response string, success */
   184 +		return 0;
   185 +	} /* if (t==T_UNDEFINED || t==T_NULL_CELL) */
   187 +	/* begin with transaction reply */
   188  	/* get the selected branch */
   189  	branch = uac_tmb.t_get_picked();
   190  	if (branch<0) {
   191 Index: modules/uac/uac.c
   192 diff -Nau modules/uac/uac.c.orig modules/uac/uac.c
   193 --- modules/uac/uac.c.orig	2010-01-18 12:32:26.159078000 +0100
   194 +++ modules/uac/uac.c	2010-02-10 20:25:06.206731656 +0100
   195 @@ -29,6 +29,7 @@
   196   *  2006-03-03  the RR parameter is encrypted via XOR with a password
   197   *              (bogdan)
   198   *  2009-08-22  TO header replacement added (bogdan)
   199 + *  2010-01-18  UAC is able to construct credentials from request (msvb)
   201   */
   203 @@ -106,7 +107,7 @@
   204  			REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE },
   205  	{"uac_auth",          (cmd_function)w_uac_auth,       0,
   206  			0, 0,
   207 -			FAILURE_ROUTE },
   208 +			REQUEST_ROUTE|FAILURE_ROUTE },
   209  	{0,0,0,0,0,0}
   210  };

mercurial