Mon, 16 Jan 2012 23:08:14 +0100
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 };