reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
RADIUSDigestAuthenticator.cxx
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#ifdef USE_RADIUS_CLIENT
6
7#include "Logger.hxx"
9
10
11using namespace resip;
12using namespace std;
13
14#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
15
16struct attr *RADIUSDigestAuthenticator::attrs = NULL;
17struct val *RADIUSDigestAuthenticator::vals = NULL;
18rc_handle *RADIUSDigestAuthenticator::rh = NULL;
19
20inline void init_av(rc_handle *rh, struct attr *at, struct val *vl, const char *fn)
21{
22 int i;
25
26 for (i = 0; i < A_MAX; i++)
27 {
28 if (at[i].n == NULL)
29 continue;
30 da = rc_dict_findattr(rh, at[i].n);
31 if (da == NULL)
32 {
33 ErrLog( <<"ERROR: " << Data(fn) << ": can't get code for the " << Data(at[i].n) << " attribute\n");
34 throw;
35 }
36 at[i].v = da->value;
37 }
38 for (i = 0; i < V_MAX; i++)
39 {
40 if (vl[i].n == NULL)
41 continue;
43 if (dv == NULL)
44 {
45 ErrLog( <<"ERROR: " << fn << ": can't get code for the " << vl[i].n << " attribute value\n");
46 throw;
47 }
48 vl[i].v = dv->value;
49 }
50}
51
52RADIUSDigestAuthListener::~RADIUSDigestAuthListener() {
53}
54
55
56void RADIUSDigestAuthenticator::init(const char *radiusConfigFile)
57{
58 if(attrs != NULL)
59 {
60 WarningLog(<<"invoked more than once, ignoring");
61 return;
62 }
63
64 if((attrs = (struct attr *)malloc(sizeof(struct attr) * A_MAX)) == NULL)
65 {
66 ErrLog( <<"malloc failed");
67 throw;
68 }
69 if((vals = (struct val *)malloc(sizeof(struct val) * V_MAX)) == NULL)
70 {
71 ErrLog(<< "malloc failed");
72 throw;
73 }
74
75 memset(attrs, 0, sizeof(struct attr) * A_MAX);
76 memset(vals, 0, sizeof(struct val) * V_MAX);
77 attrs[A_SERVICE_TYPE].n = "Service-Type";
78 attrs[A_SIP_RPID].n = "Sip-RPId";
79 attrs[A_SIP_URI_USER].n = "Sip-URI-User";
80 attrs[A_DIGEST_RESPONSE].n = "Digest-Response";
81 attrs[A_DIGEST_ALGORITHM].n = "Digest-Algorithm";
82 attrs[A_DIGEST_BODY_DIGEST].n = "Digest-Body-Digest";
83 attrs[A_DIGEST_CNONCE].n = "Digest-CNonce";
84 attrs[A_DIGEST_NONCE_COUNT].n = "Digest-Nonce-Count";
85 attrs[A_DIGEST_QOP].n = "Digest-QOP";
86 attrs[A_DIGEST_METHOD].n = "Digest-Method";
87 attrs[A_DIGEST_URI].n = "Digest-URI";
88 attrs[A_DIGEST_NONCE].n = "Digest-Nonce";
89 attrs[A_DIGEST_REALM].n = "Digest-Realm";
90 attrs[A_DIGEST_USER_NAME].n = "Digest-User-Name";
91 attrs[A_USER_NAME].n = "User-Name";
93 //attrs[A_CISCO_AVPAIR].n = "Cisco-AVPair";
94 vals[V_SIP_SESSION].n = "Sip-Session";
95
98 {
100 }
101 // FIXME: this should not use a cast, freeradius-client.h to be fixed
102 // pull request submitted via github
103 // https://github.com/FreeRADIUS/freeradius-client/pull/8
104 if((rh = rc_read_config((char *)myRADIUSConfigFile)) == NULL)
105 {
106 ErrLog(<< "radius: Error opening configuration file \n");
107 throw;
108 }
109
110 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
111 {
112 ErrLog(<< "radius: Error opening dictionary file \n");
113 throw;
114 }
115
116 init_av(rh, attrs, vals, "radius");
117
118}
119
120RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(
121 const resip::Data& username,
127 username(username),
133 digestQop(""),
135 digestCNonce(""),
139{
140}
141
142// QoP auth
143RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(
144 const resip::Data& username,
148 const resip::Data& digestUri,
150 const resip::Data& digestQop,
155 username(username),
167{
168}
169
170// QoP auth-int
171RADIUSDigestAuthenticator::RADIUSDigestAuthenticator(
172 const resip::Data& username,
176 const resip::Data& digestUri,
178 const resip::Data& digestQop,
184 username(username),
196{
197}
198
199RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator()
200{
201 DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() entered");
202 //terminate();
203 DebugLog(<<"RADIUSDigestAuthenticator::~RADIUSDigestAuthenticator() done");
204}
205
206int RADIUSDigestAuthenticator::doRADIUSCheck()
207{
208 run();
209 detach();
210 return 0;
211 // return detach();
212}
213
214void RADIUSDigestAuthenticator::thread()
215{
216
217 DebugLog(<<"RADIUSDigestAuthenticator::thread() entered");
218
221
222 if(vp_s_start == NULL)
223 {
224 WarningLog(<<"vp_s_start == NULL");
225 listener->onError();
226 delete listener;
227 //exit();
228 delete this;
229 return;
230 }
231
232 char msg[RADIUS_MSG_SIZE];
233 int i;
235 {
236 DebugLog(<<"rc_auth success for " << username.c_str());
238 Data rpid("");
239 VALUE_PAIR *vp;
241 {
242 rpid = Data(vp->strvalue, vp->lvalue);
243 }
244 listener->onSuccess(rpid);
246 }
247 else
248 {
249 DebugLog(<<"rc_auth failure for " << username.c_str()
250 <<", code = " << i);
253 if(i == REJECT_RC)
254 {
255 listener->onAccessDenied();
256 }
257 else
258 {
259 listener->onError();
260 }
261 }
262 delete listener;
263 DebugLog(<<"RADIUSDigestAuthenticator::thread() exiting");
264 //exit();
265 delete this;
266}
267
268void RADIUSDigestAuthenticator::final()
269{
270 DebugLog(<<"RADIUSDigestAuthenticator::final() entered");
271}
272
273VALUE_PAIR *RADIUSDigestAuthenticator::createRADIUSRequest()
274{
276
277 if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0))
278 {
280 return NULL;
281 }
283 {
285 return NULL;
286 }
287 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_REALM].v, (char *)digestRealm.data(), digestRealm.size(), 0))
288 {
290 return NULL;
291 }
292 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_NONCE].v, (char *)digestNonce.data(), digestNonce.size(), 0))
293 {
295 return NULL;
296 }
297 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_URI].v, (char *)digestUri.data(), digestUri.size(), 0))
298 {
300 return NULL;
301 }
302 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_METHOD].v, (char *)digestMethod.data(), digestMethod.size(), 0))
303 {
305 return NULL;
306 }
307 if(!digestQop.empty())
308 {
309 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_QOP].v, (char *)digestQop.data(), digestQop.size(), 0))
310 {
312 return NULL;
313 }
315 {
317 return NULL;
318 }
319 if(!rc_avpair_add(rh, &vp_start, attrs[A_DIGEST_CNONCE].v, (char *)digestCNonce.data(), digestCNonce.size(), 0))
320 {
322 return NULL;
323 }
324 if(!digestBodyDigest.empty())
325 {
326 if(!rc_avpair_add(rh, &vp_start, attrs[A_USER_NAME].v, (char *)username.data(), username.size(), 0))
327 {
329 return NULL;
330 }
331 }
332 } // end QoP
333
335 {
337 return NULL;
338 }
339
340 UINT4 service = vals[V_SIP_SESSION].v;
341 if (!rc_avpair_add(rh, &vp_start, attrs[A_SERVICE_TYPE].v, &service, -1, 0))
342 {
344 return NULL;
345 }
346
347 /* Add SIP URI as a check item */
348 // xxx
349 if (!rc_avpair_add(rh, &vp_start, attrs[A_SIP_URI_USER].v, (char *)digestUsername.data(), digestUsername.size(), 0))
350 {
352 return NULL;
353 }
354
355 return vp_start;
356}
357
358TestRADIUSDigestAuthListener::TestRADIUSDigestAuthListener()
359{
360}
361
362void TestRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid)
363{
364 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess");
365 if(!rpid.empty())
366 {
367 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess rpid = " << rpid);
368 }
369 else
370 {
371 DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess, no rpid");
372 }
373}
374
375void TestRADIUSDigestAuthListener::onAccessDenied()
376{
377 DebugLog(<<"TestRADIUSDigestAuthListener::onAccessDenied");
378}
379
380void TestRADIUSDigestAuthListener::onError()
381{
382 WarningLog(<<"TestRADIUSDigestAuthListener::onError");
383}
384
385#endif
386
387
388/* ====================================================================
389 *
390 * Copyright 2012 Daniel Pocock. All rights reserved.
391 *
392 * Redistribution and use in source and binary forms, with or without
393 * modification, are permitted provided that the following conditions
394 * are met:
395 *
396 * 1. Redistributions of source code must retain the above copyright
397 * notice, this list of conditions and the following disclaimer.
398 *
399 * 2. Redistributions in binary form must reproduce the above copyright
400 * notice, this list of conditions and the following disclaimer in
401 * the documentation and/or other materials provided with the
402 * distribution.
403 *
404 * 3. Neither the name of the author(s) nor the names of any contributors
405 * may be used to endorse or promote products derived from this software
406 * without specific prior written permission.
407 *
408 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND
409 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
411 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
412 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
413 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
414 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
415 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
416 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
417 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
418 * SUCH DAMAGE.
419 *
420 * ====================================================================
421 *
422 *
423 */
424
#define DebugLog(args_)
Definition Logger.hxx:128
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
dcm! – add UnusedChecking(_enum) below;
void list()
Definition userAdmin.cxx:66