|
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 */ |
|
11 |
|
12 |
|
13 @@ -375,14 +376,172 @@ |
|
14 HASHHEX response; |
|
15 str *new_hdr; |
|
16 |
|
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) */ |
|
186 |
|
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) |
|
200 |
|
201 */ |
|
202 |
|
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 }; |
|
211 |