/[resiprocate]/main/rutil/RADIUSDigestAuthenticator.cxx
ViewVC logotype

Contents of /main/rutil/RADIUSDigestAuthenticator.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9493 - (show annotations) (download)
Sat Apr 7 10:56:50 2012 UTC (7 years, 9 months ago) by dpocock
File MIME type: text/plain
File size: 12308 byte(s)
Include config.h from even more places where it may be needed
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #ifdef USE_RADIUS_CLIENT
6
7 #include "Logger.hxx"
8 #include "RADIUSDigestAuthenticator.hxx"
9
10
11 using namespace resip;
12 using namespace std;
13
14 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
15
16 struct attr *RADIUSDigestAuthenticator::attrs = NULL;
17 struct val *RADIUSDigestAuthenticator::vals = NULL;
18 rc_handle *RADIUSDigestAuthenticator::rh = NULL;
19
20 inline void init_av(rc_handle *rh, struct attr *at, struct val *vl, char *fn) {
21 int i;
22 DICT_ATTR *da;
23 DICT_VALUE *dv;
24
25 for (i = 0; i < A_MAX; i++) {
26 if (at[i].n == NULL)
27 continue;
28 da = rc_dict_findattr(rh, at[i].n);
29 if (da == NULL) {
30 ErrLog( <<"ERROR: " << Data(fn) << ": can't get code for the " << Data(at[i].n) << " attribute\n");
31 throw;
32 }
33 at[i].v = da->value;
34 }
35 for (i = 0; i < V_MAX; i++) {
36 if (vl[i].n == NULL)
37 continue;
38 dv = rc_dict_findval(rh, vl[i].n);
39 if (dv == NULL) {
40 ErrLog( <<"ERROR: " << fn << ": can't get code for the " << vl[i].n << " attribute value\n");
41 throw;
42 }
43 vl[i].v = dv->value;
44 }
45 }
46
47 RADIUSDigestAuthListener::~RADIUSDigestAuthListener() {
48 }
49
50
51 void RADIUSDigestAuthenticator::init(const char *radiusConfigFile) {
52 if(attrs != NULL)
53 throw; // may only be called once
54
55 if((attrs = (struct attr *)malloc(sizeof(struct attr) * A_MAX)) == NULL) {
56 ErrLog( <<"malloc failed");
57 throw;
58 }
59 if((vals = (struct val *)malloc(sizeof(struct val) * V_MAX)) == NULL) {
60 ErrLog(<< "malloc failed");
61 throw;
62 }
63
64 memset(attrs, 0, sizeof(struct attr) * A_MAX);
65 memset(vals, 0, sizeof(struct val) * V_MAX);
66 attrs[A_SERVICE_TYPE].n = "Service-Type";
67 attrs[A_SIP_RPID].n = "Sip-RPId";
68 attrs[A_SIP_URI_USER].n = "Sip-URI-User";
69 attrs[A_DIGEST_RESPONSE].n = "Digest-Response";
70 attrs[A_DIGEST_ALGORITHM].n = "Digest-Algorithm";
71 attrs[A_DIGEST_BODY_DIGEST].n = "Digest-Body-Digest";
72 attrs[A_DIGEST_CNONCE].n = "Digest-CNonce";
73 attrs[A_DIGEST_NONCE_COUNT].n = "Digest-Nonce-Count";
74 attrs[A_DIGEST_QOP].n = "Digest-QOP";
75 attrs[A_DIGEST_METHOD].n = "Digest-Method";
76 attrs[A_DIGEST_URI].n = "Digest-URI";
77 attrs[A_DIGEST_NONCE].n = "Digest-Nonce";
78 attrs[A_DIGEST_REALM].n = "Digest-Realm";
79 attrs[A_DIGEST_USER_NAME].n = "Digest-User-Name";
80 attrs[A_USER_NAME].n = "User-Name";
81 attrs[A_CISCO_AVPAIR].n = NULL;
82 //attrs[A_CISCO_AVPAIR].n = "Cisco-AVPair";
83 vals[V_SIP_SESSION].n = "Sip-Session";
84
85 const char *myRADIUSConfigFile = RADIUS_CONFIG;
86 if(radiusConfigFile != NULL)
87 myRADIUSConfigFile = radiusConfigFile;
88 if((rh = rc_read_config((char *)myRADIUSConfigFile)) == NULL) {
89 ErrLog(<< "radius: Error opening configuration file \n");
90 throw;
91 }
92
93 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) {
94 ErrLog(<< "radius: Error opening dictionary file \n");
95 throw;
96 }
97
98 init_av(rh, attrs, vals, "radius");
99
100 }
101
102 RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(const resip::Data& username, const resip::Data& digestUsername, const resip::Data& digestRealm, const resip::Data& digestNonce, const resip::Data& digestUri, const resip::Data& digestMethod, const resip::Data& digestResponse, RADIUSDigestAuthListener *listener) :
103 username(username), digestUsername(digestUsername), digestRealm(digestRealm), digestNonce(digestNonce), digestUri(digestUri), digestMethod(digestMethod), digestQop(""), digestNonceCount(""), digestCNonce(""), digestBodyDigest(""), digestResponse(digestResponse), listener(listener) {
104 }
105
106 // QoP auth
107 RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(const resip::Data& username, const resip::Data& digestUsername, const resip::Data& digestRealm, const resip::Data& digestNonce, const resip::Data& digestUri, const resip::Data& digestMethod, const resip::Data& digestQop, const resip::Data& digestNonceCount, const resip::Data& digestCNonce, const resip::Data& digestResponse, RADIUSDigestAuthListener *listener) :
108 username(username), digestUsername(digestUsername), digestRealm(digestRealm),
109 digestNonce(digestNonce), digestUri(digestUri), digestMethod(digestMethod), digestQop(digestQop), digestNonceCount(digestNonceCount), digestCNonce(digestCNonce), digestBodyDigest(""), digestResponse(digestResponse), listener(listener) {
110 }
111
112 // QoP auth-int
113 RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(const resip::Data& username, const resip::Data& digestUsername, const resip::Data& digestRealm, const resip::Data& digestNonce, const resip::Data& digestUri, const resip::Data& digestMethod, const resip::Data& digestQop, const resip::Data& digestNonceCount, const resip::Data& digestCNonce, const resip::Data& digestBodyDigest, const resip::Data& digestResponse, RADIUSDigestAuthListener *listener) :
114 username(username), digestUsername(digestUsername), digestRealm(digestRealm),
115 digestNonce(digestNonce), digestUri(digestUri), digestMethod(digestMethod), digestQop(digestQop), digestNonceCount(digestNonceCount), digestCNonce(digestCNonce), digestBodyDigest(digestBodyDigest), digestResponse(digestResponse), listener(listener) {
116 }
117
118 RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() {
119 DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() entered");
120 //terminate();
121 DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() done");
122 }
123
124 int RADIUSDigestAuthenticator::doRADIUSCheck() {
125 run();
126 detach();
127 return 0;
128 // return detach();
129 }
130
131 void RADIUSDigestAuthenticator::thread() {
132
133 DebugLog(<<"RADIUSDigestAuthenticator::thread() entered");
134
135 VALUE_PAIR *vp_s_start = createRADIUSRequest();
136 VALUE_PAIR *vp_r_start;
137
138 if(vp_s_start == NULL) {
139 WarningLog(<<"vp_s_start == NULL");
140 listener->onError();
141 delete listener;
142 //exit();
143 delete this;
144 return;
145 }
146
147 char msg[RADIUS_MSG_SIZE];
148 int i;
149 if ((i = rc_auth(rh, RADIUS_SIP_PORT, vp_s_start, &vp_r_start, msg)) == OK_RC) {
150 DebugLog(<<"rc_auth success for " << username.c_str());
151 rc_avpair_free(vp_s_start);
152 Data rpid("");
153 VALUE_PAIR *vp;
154 if ((vp = rc_avpair_get(vp_r_start, attrs[A_SIP_RPID].v, 0))) {
155 rpid = Data(vp->strvalue, vp->lvalue);
156 }
157 listener->onSuccess(rpid);
158 rc_avpair_free(vp_r_start);
159 } else {
160 DebugLog(<<"rc_auth failure for " << username.c_str());
161 rc_avpair_free(vp_s_start);
162 rc_avpair_free(vp_r_start);
163 if(i == BADRESP_RC)
164 listener->onAccessDenied();
165 else
166 listener->onError();
167 }
168 delete listener;
169 DebugLog(<<"RADIUSDigestAuthenticator::thread() exiting");
170 //exit();
171 delete this;
172 }
173
174 void RADIUSDigestAuthenticator::final() {
175 DebugLog(<<"RADIUSDigestAuthenticator::final() entered");
176 }
177
178 VALUE_PAIR *RADIUSDigestAuthenticator::createRADIUSRequest() {
179 VALUE_PAIR *vp_start = NULL;
180
181 if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0)) {
182 rc_avpair_free(vp_start);
183 return NULL;
184 }
185 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_USER_NAME].v, (char *)digestUsername.data(), digestUsername.size(), 0)) {
186 rc_avpair_free(vp_start);
187 return NULL;
188 }
189 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_REALM].v, (char *)digestRealm.data(), digestRealm.size(), 0)) {
190 rc_avpair_free(vp_start);
191 return NULL;
192 }
193 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_NONCE].v, (char *)digestNonce.data(), digestNonce.size(), 0)) {
194 rc_avpair_free(vp_start);
195 return NULL;
196 }
197 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_URI].v, (char *)digestUri.data(), digestUri.size(), 0)) {
198 rc_avpair_free(vp_start);
199 return NULL;
200 }
201 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_METHOD].v, (char *)digestMethod.data(), digestMethod.size(), 0)) {
202 rc_avpair_free(vp_start);
203 return NULL;
204 }
205 if(!digestQop.empty()) {
206 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_QOP].v, (char *)digestQop.data(), digestQop.size(), 0)) {
207 rc_avpair_free(vp_start);
208 return NULL;
209 }
210 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_NONCE_COUNT].v, (char *)digestNonceCount.data(), digestNonceCount.size(), 0)) {
211 rc_avpair_free(vp_start);
212 return NULL;
213 }
214 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_CNONCE].v, (char *)digestCNonce.data(), digestCNonce.size(), 0)) {
215 rc_avpair_free(vp_start);
216 return NULL;
217 }
218 if(!digestBodyDigest.empty()) {
219 if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0)) {
220 rc_avpair_free(vp_start);
221 return NULL;
222 }
223 }
224 } // end QoP
225
226 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_RESPONSE].v, (char *)digestResponse.data(), digestResponse.size(), 0)) {
227 rc_avpair_free(vp_start);
228 return NULL;
229 }
230
231 UINT4 service = vals[V_SIP_SESSION].v;
232 if (!rc_avpair_add(rh, &vp_start, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
233 rc_avpair_free(vp_start);
234 return NULL;
235 }
236
237 /* Add SIP URI as a check item */
238 // xxx
239 if (!rc_avpair_add(rh, &vp_start, attrs[A_SIP_URI_USER].v, (char *)digestUsername.data(), digestUsername.size(), 0)) {
240 rc_avpair_free(vp_start);
241 return NULL;
242 }
243
244 return vp_start;
245 }
246
247 TestRADIUSDigestAuthListener::TestRADIUSDigestAuthListener() {
248 }
249
250 void TestRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid) {
251 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess");
252 if(!rpid.empty())
253 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess rpid = " << rpid);
254 else
255 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess, no rpid");
256 }
257
258 void TestRADIUSDigestAuthListener::onAccessDenied() {
259 DebugLog(<<"TestRADIUSDigestAuthListener::onAccessDenied");
260 }
261
262 void TestRADIUSDigestAuthListener::onError() {
263 WarningLog(<<"TestRADIUSDigestAuthListener::onError");
264 }
265
266 #endif
267
268
269 /* ====================================================================
270 * The Vovida Software License, Version 1.0
271 *
272 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
273 *
274 * Redistribution and use in source and binary forms, with or without
275 * modification, are permitted provided that the following conditions
276 * are met:
277 *
278 * 1. Redistributions of source code must retain the above copyright
279 * notice, this list of conditions and the following disclaimer.
280 *
281 * 2. Redistributions in binary form must reproduce the above copyright
282 * notice, this list of conditions and the following disclaimer in
283 * the documentation and/or other materials provided with the
284 * distribution.
285 *
286 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
287 * and "Vovida Open Communication Application Library (VOCAL)" must
288 * not be used to endorse or promote products derived from this
289 * software without prior written permission. For written
290 * permission, please contact vocal@vovida.org.
291 *
292 * 4. Products derived from this software may not be called "VOCAL", nor
293 * may "VOCAL" appear in their name, without prior written
294 * permission of Vovida Networks, Inc.
295 *
296 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
297 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
298 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
299 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
300 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
301 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
302 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
303 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
304 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
305 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
306 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
307 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
308 * DAMAGE.
309 *
310 * ====================================================================
311 *
312 * This software consists of voluntary contributions made by Vovida
313 * Networks, Inc. and many individuals on behalf of Vovida Networks,
314 * Inc. For more information on Vovida Networks, Inc., please see
315 * <http://www.vovida.org/>.
316 *
317 */
318

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27