Annotation of embedaddon/mpd/src/radsrv.c, revision 1.1.1.3
1.1 misho 1:
2: /*
3: * radsrv.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "radsrv.h"
10: #include "util.h"
1.1.1.3 ! misho 11: #include <stdint.h>
1.1 misho 12: #include <radlib.h>
13: #include <radlib_vs.h>
14:
15: #ifdef RAD_COA_REQUEST
16:
17: /*
18: * DEFINITIONS
19: */
20:
21: /* Set menu options */
22: enum {
23: SET_OPEN,
24: SET_CLOSE,
25: SET_SELF,
26: SET_PEER,
27: SET_DISABLE,
28: SET_ENABLE
29: };
30:
31:
32: /*
33: * INTERNAL FUNCTIONS
34: */
35:
36: static int RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg);
37:
38: /*
39: * GLOBAL VARIABLES
40: */
41:
42: const struct cmdtab RadsrvSetCmds[] = {
43: { "open", "Open the radsrv" ,
44: RadsrvSetCommand, NULL, 2, (void *) SET_OPEN },
45: { "close", "Close the radsrv" ,
46: RadsrvSetCommand, NULL, 2, (void *) SET_CLOSE },
47: { "self {ip} [{port}]", "Set radsrv ip and port" ,
48: RadsrvSetCommand, NULL, 2, (void *) SET_SELF },
49: { "peer {ip} {secret}", "Set peer ip and secret" ,
50: RadsrvSetCommand, NULL, 2, (void *) SET_PEER },
51: { "enable [opt ...]", "Enable radsrv option" ,
52: RadsrvSetCommand, NULL, 2, (void *) SET_ENABLE },
53: { "disable [opt ...]", "Disable radsrv option" ,
54: RadsrvSetCommand, NULL, 2, (void *) SET_DISABLE },
55: { NULL },
56: };
57:
58:
59: /*
60: * INTERNAL VARIABLES
61: */
62:
63: static const struct confinfo gConfList[] = {
64: { 0, RADSRV_DISCONNECT, "disconnect" },
65: { 0, RADSRV_COA, "coa" },
66: { 0, 0, NULL },
67: };
68:
69: /*
70: * RadsrvInit()
71: */
72:
73: int
74: RadsrvInit(Radsrv w)
75: {
76: /* setup radsrv-defaults */
77: memset(w, 0, sizeof(*w));
78:
79: Enable(&w->options, RADSRV_DISCONNECT);
80: Enable(&w->options, RADSRV_COA);
81:
82: ParseAddr(DEFAULT_RADSRV_IP, &w->addr, ALLOW_IPV4);
83: w->port = DEFAULT_RADSRV_PORT;
84:
85: return (0);
86: }
87:
88: static void
89: RadsrvEvent(int type, void *cookie)
90: {
91: Radsrv w = (Radsrv)cookie;
92: const void *data;
93: size_t len;
94: int res, result, found, err, anysesid, l;
95: Bund B;
96: Link L;
97: char *tmpval;
98: char *username = NULL, *called = NULL, *calling = NULL, *sesid = NULL;
99: char *msesid = NULL, *link = NULL, *bundle = NULL, *iface = NULL;
100: int nasport = -1, serv_type = 0, ifindex = -1, i;
1.1.1.3 ! misho 101: u_int session_timeout = UINT_MAX, idle_timeout = UINT_MAX;
! 102: u_int acct_update = UINT_MAX;
! 103: struct in_addr ip = { INADDR_BROADCAST };
! 104: struct in_addr nas_ip = { INADDR_BROADCAST };
1.1 misho 105: char buf[64];
106: u_int32_t vendor;
1.1.1.2 misho 107: u_char *state = NULL, *rad_class = NULL;
1.1 misho 108: int state_len = 0;
1.1.1.2 misho 109: int class_len = 0;
1.1 misho 110: int authentic = 0;
111: #if defined(USE_NG_BPF) || defined(USE_IPFW)
112: struct acl **acls, *acls1;
113: char *acl, *acl1, *acl2, *acl3;
114: #endif
115: #ifdef USE_IPFW
116: struct acl *acl_rule = NULL; /* ipfw rules */
117: struct acl *acl_pipe = NULL; /* ipfw pipes */
118: struct acl *acl_queue = NULL; /* ipfw queues */
119: struct acl *acl_table = NULL; /* ipfw tables */
120: #endif
121: #ifdef USE_NG_BPF
122: struct acl *acl_filters[ACL_FILTERS]; /* mpd's internal bpf filters */
123: struct acl *acl_limits[ACL_DIRS]; /* traffic limits based on mpd's filters */
124: char std_acct[ACL_DIRS][ACL_NAME_LEN]; /* Names of ACL returned in standard accounting */
125:
126: bzero(acl_filters, sizeof(acl_filters));
127: bzero(acl_limits, sizeof(acl_limits));
128: bzero(std_acct, sizeof(std_acct));
129: #endif
130: result = rad_receive_request(w->handle);
131: if (result < 0) {
132: Log(LG_ERR, ("radsrv: request receive error: %d", result));
133: return;
134: }
135: switch (result) {
136: case RAD_DISCONNECT_REQUEST:
137: if (!Enabled(&w->options, RADSRV_DISCONNECT)) {
138: Log(LG_ERR, ("radsrv: DISCONNECT request, support disabled"));
139: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
140: rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
141: rad_send_response(w->handle);
142: return;
143: }
144: Log(LG_ERR, ("radsrv: DISCONNECT request"));
145: break;
146: case RAD_COA_REQUEST:
147: if (!Enabled(&w->options, RADSRV_COA)) {
148: Log(LG_ERR, ("radsrv: CoA request, support disabled"));
149: rad_create_response(w->handle, RAD_COA_NAK);
150: rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
151: rad_send_response(w->handle);
152: return;
153: }
154: Log(LG_ERR, ("radsrv: CoA request"));
155: break;
156: default:
157: Log(LG_ERR, ("radsrv: unsupported request: %d", result));
158: return;
159: }
160: anysesid = 0;
161: while ((res = rad_get_attr(w->handle, &data, &len)) > 0) {
162: switch (res) {
163: case RAD_USER_NAME:
164: anysesid = 1;
1.1.1.2 misho 165: if (username)
166: free(username);
1.1 misho 167: username = rad_cvt_string(data, len);
1.1.1.2 misho 168: Log(LG_RADIUS2, ("radsrv: Got RAD_USER_NAME: %s", username));
169: break;
170: case RAD_CLASS:
171: tmpval = Bin2Hex(data, len);
172: Log(LG_RADIUS2, ("radsrv: Got RAD_CLASS: %s", tmpval));
173: Freee(tmpval);
174: class_len = len;
175: if (rad_class != NULL)
176: Freee(rad_class);
177: rad_class = Mdup(MB_AUTH, data, len);
1.1 misho 178: break;
179: case RAD_NAS_IP_ADDRESS:
180: nas_ip = rad_cvt_addr(data);
1.1.1.2 misho 181: Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_IP_ADDRESS: %s",
1.1 misho 182: inet_ntoa(nas_ip)));
183: break;
184: case RAD_SERVICE_TYPE:
185: serv_type = rad_cvt_int(data);
186: Log(LG_RADIUS2, ("radsrv: Got RAD_SERVICE_TYPE: %d",
187: serv_type));
188: break;
189: case RAD_STATE:
190: tmpval = Bin2Hex(data, len);
1.1.1.2 misho 191: Log(LG_RADIUS2, ("radsrv: Got RAD_STATE: 0x%s", tmpval));
1.1 misho 192: Freee(tmpval);
193: state_len = len;
194: if (state != NULL)
195: Freee(state);
196: state = Mdup(MB_RADSRV, data, len);
197: break;
198: case RAD_CALLED_STATION_ID:
199: anysesid = 1;
1.1.1.2 misho 200: if (called)
201: free(called);
1.1 misho 202: called = rad_cvt_string(data, len);
1.1.1.2 misho 203: Log(LG_RADIUS2, ("radsrv: Got RAD_CALLED_STATION_ID: %s",
1.1 misho 204: called));
205: break;
206: case RAD_CALLING_STATION_ID:
207: anysesid = 1;
1.1.1.2 misho 208: if (calling)
209: free(calling);
1.1 misho 210: calling = rad_cvt_string(data, len);
1.1.1.2 misho 211: Log(LG_RADIUS2, ("radsrv: Got RAD_CALLING_STATION_ID: %s",
1.1 misho 212: calling));
213: break;
214: case RAD_ACCT_SESSION_ID:
215: anysesid = 1;
1.1.1.2 misho 216: if (sesid)
217: free(sesid);
1.1 misho 218: sesid = rad_cvt_string(data, len);
1.1.1.2 misho 219: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_SESSION_ID: %s",
1.1 misho 220: sesid));
221: break;
222: case RAD_ACCT_MULTI_SESSION_ID:
223: anysesid = 1;
1.1.1.2 misho 224: if (msesid)
225: free(msesid);
1.1 misho 226: msesid = rad_cvt_string(data, len);
1.1.1.2 misho 227: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_MULTI_SESSION_ID: %s",
1.1 misho 228: msesid));
229: break;
230: case RAD_FRAMED_IP_ADDRESS:
231: anysesid = 1;
232: ip = rad_cvt_addr(data);
1.1.1.2 misho 233: Log(LG_RADIUS2, ("radsrv: Got RAD_FRAMED_IP_ADDRESS: %s",
1.1 misho 234: inet_ntoa(ip)));
1.1.1.3 ! misho 235: if (ip.s_addr == INADDR_BROADCAST)
! 236: Log(LG_ERR, ("radsrv: incorrect Framed-IP-Address"));
1.1 misho 237: break;
238: case RAD_NAS_PORT:
239: anysesid = 1;
240: nasport = rad_cvt_int(data);
1.1.1.2 misho 241: Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_PORT: %d",
1.1 misho 242: nasport));
243: break;
244: case RAD_SESSION_TIMEOUT:
245: session_timeout = rad_cvt_int(data);
1.1.1.2 misho 246: Log(LG_RADIUS2, ("radsrv: Got RAD_SESSION_TIMEOUT: %u",
1.1 misho 247: session_timeout));
248: break;
249: case RAD_IDLE_TIMEOUT:
250: idle_timeout = rad_cvt_int(data);
1.1.1.2 misho 251: Log(LG_RADIUS2, ("radsrv: Got RAD_IDLE_TIMEOUT: %u",
1.1 misho 252: idle_timeout));
253: break;
254: case RAD_ACCT_INTERIM_INTERVAL:
255: acct_update = rad_cvt_int(data);
1.1.1.2 misho 256: Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_INTERIM_INTERVAL: %u",
1.1 misho 257: acct_update));
258: break;
259: case RAD_MESSAGE_AUTHENTIC:
260: Log(LG_RADIUS2, ("radsrv: Got RAD_MESSAGE_AUTHENTIC"));
261: authentic = 1;
262: break;
263: case RAD_VENDOR_SPECIFIC:
264: if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
1.1.1.2 misho 265: Log(LG_RADIUS, ("radsrv: Get vendor attr failed: %s",
1.1 misho 266: rad_strerror(w->handle)));
267: break;
268: }
269: switch (vendor) {
270: case RAD_VENDOR_MPD:
271: if (res == RAD_MPD_LINK) {
272: if (link)
273: free(link);
274: link = rad_cvt_string(data, len);
275: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LINK: %s",
276: link));
277: anysesid = 1;
278: break;
279: } else if (res == RAD_MPD_BUNDLE) {
280: if (bundle)
281: free(bundle);
282: bundle = rad_cvt_string(data, len);
283: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_BINDLE: %s",
284: bundle));
285: anysesid = 1;
286: break;
287: } else if (res == RAD_MPD_IFACE) {
288: if (iface)
289: free(iface);
290: iface = rad_cvt_string(data, len);
291: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE: %s",
292: iface));
293: anysesid = 1;
294: break;
295: } else if (res == RAD_MPD_IFACE_INDEX) {
296: ifindex = rad_cvt_int(data);
297: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE_INDEX: %d",
298: ifindex));
299: anysesid = 1;
300: break;
301: } else
302: #ifdef USE_IPFW
303: if (res == RAD_MPD_RULE) {
304: acl1 = acl = rad_cvt_string(data, len);
305: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_RULE: %s",
306: acl));
307: acls = &acl_rule;
308: } else if (res == RAD_MPD_PIPE) {
309: acl1 = acl = rad_cvt_string(data, len);
310: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_PIPE: %s",
311: acl));
312: acls = &acl_pipe;
313: } else if (res == RAD_MPD_QUEUE) {
314: acl1 = acl = rad_cvt_string(data, len);
315: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_QUEUE: %s",
316: acl));
317: acls = &acl_queue;
318: } else if (res == RAD_MPD_TABLE) {
319: acl1 = acl = rad_cvt_string(data, len);
320: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE: %s",
321: acl));
322: acls = &acl_table;
323: } else if (res == RAD_MPD_TABLE_STATIC) {
324: acl1 = acl = rad_cvt_string(data, len);
325: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE_STATIC: %s",
326: acl));
327: acls = &acl_table;
328: } else
329: #endif /* USE_IPFW */
330: #ifdef USE_NG_BPF
331: if (res == RAD_MPD_FILTER) {
332: acl1 = acl = rad_cvt_string(data, len);
333: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_FILTER: %s",
334: acl));
335: acl2 = strsep(&acl1, "#");
1.1.1.2 misho 336: i = atoi(acl2);
1.1 misho 337: if (i <= 0 || i > ACL_FILTERS) {
338: Log(LG_RADIUS, ("radsrv: Wrong filter number: %i", i));
339: free(acl);
340: break;
341: }
342: acls = &(acl_filters[i - 1]);
343: } else if (res == RAD_MPD_LIMIT) {
344: acl1 = acl = rad_cvt_string(data, len);
345: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LIMIT: %s",
346: acl));
347: acl2 = strsep(&acl1, "#");
348: if (strcasecmp(acl2, "in") == 0) {
349: i = 0;
350: } else if (strcasecmp(acl2, "out") == 0) {
351: i = 1;
352: } else {
353: Log(LG_ERR, ("radsrv: Wrong limit direction: '%s'",
354: acl2));
355: free(acl);
356: break;
357: }
358: acls = &(acl_limits[i]);
359: } else if (res == RAD_MPD_INPUT_ACCT) {
360: tmpval = rad_cvt_string(data, len);
361: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_INPUT_ACCT: %s",
362: tmpval));
363: strlcpy(std_acct[0], tmpval, sizeof(std_acct[0]));
364: free(tmpval);
365: break;
366: } else if (res == RAD_MPD_OUTPUT_ACCT) {
367: tmpval = rad_cvt_string(data, len);
368: Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_OUTPUT_ACCT: %s",
369: tmpval));
370: strlcpy(std_acct[1], tmpval, sizeof(std_acct[1]));
371: free(tmpval);
372: break;
373: } else
374: #endif /* USE_NG_BPF */
375: {
376: Log(LG_RADIUS2, ("radsrv: Dropping MPD vendor specific attribute: %d",
377: res));
378: break;
379: }
380: #if defined(USE_NG_BPF) || defined(USE_IPFW)
381: if (acl1 == NULL) {
382: Log(LG_ERR, ("radsrv: Incorrect acl!"));
383: free(acl);
384: break;
385: }
386:
387: acl3 = acl1;
388: strsep(&acl3, "=");
389: acl2 = acl1;
390: strsep(&acl2, "#");
1.1.1.2 misho 391: i = atoi(acl1);
1.1 misho 392: if (i <= 0) {
393: Log(LG_ERR, ("radsrv: Wrong acl number: %i", i));
394: free(acl);
395: break;
396: }
397: if ((acl3 == NULL) || (acl3[0] == 0)) {
398: Log(LG_ERR, ("radsrv: Wrong acl"));
399: free(acl);
400: break;
401: }
402: acls1 = Malloc(MB_AUTH, sizeof(struct acl) + strlen(acl3));
403: if (res != RAD_MPD_TABLE_STATIC) {
404: acls1->number = i;
405: acls1->real_number = 0;
406: } else {
407: acls1->number = 0;
408: acls1->real_number = i;
409: }
410: if (acl2)
411: strlcpy(acls1->name, acl2, sizeof(acls1->name));
412: strcpy(acls1->rule, acl3);
413: while ((*acls != NULL) && ((*acls)->number < acls1->number))
414: acls = &((*acls)->next);
415:
416: if (*acls == NULL) {
417: acls1->next = NULL;
418: } else if (((*acls)->number == acls1->number) &&
419: (res != RAD_MPD_TABLE) &&
420: (res != RAD_MPD_TABLE_STATIC)) {
421: Log(LG_ERR, ("radsrv: Duplicate acl"));
422: Freee(acls1);
423: free(acl);
424: break;
425: } else {
426: acls1->next = *acls;
427: }
428: *acls = acls1;
429:
430: free(acl);
431: break;
432: #endif /* USE_NG_BPF or USE_IPFW */
433:
434: default:
1.1.1.2 misho 435: Log(LG_RADIUS2, ("radsrv: Dropping vendor %d attribute: %d",
1.1 misho 436: vendor, res));
437: break;
438: }
439: break;
440: default:
1.1.1.2 misho 441: Log(LG_RADIUS2, ("radsrv: Unknown attribute: %d", res));
1.1 misho 442: break;
443: }
444: }
445: err = 0;
1.1.1.3 ! misho 446: if (w->addr.u.ip4.s_addr != 0 && nas_ip.s_addr != INADDR_BROADCAST
! 447: && w->addr.u.ip4.s_addr != nas_ip.s_addr) {
1.1 misho 448: Log(LG_ERR, ("radsrv: incorrect NAS-IP-Address"));
449: err = 403;
450: } else if (anysesid == 0) {
451: Log(LG_ERR, ("radsrv: request without session identification"));
452: err = 402;
453: } else if (serv_type != 0) {
454: Log(LG_ERR, ("radsrv: Service-Type attribute not supported"));
455: err = 405;
456: }
457: if (err) {
458: if (result == RAD_DISCONNECT_REQUEST)
459: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
460: else
461: rad_create_response(w->handle, RAD_COA_NAK);
462: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
463: if (state != NULL)
464: rad_put_attr(w->handle, RAD_STATE, state, state_len);
465: if (authentic)
466: rad_put_message_authentic(w->handle);
467: rad_send_response(w->handle);
468: goto cleanup;
469: }
470: found = 0;
471: err = 503;
472: for (l = 0; l < gNumLinks; l++) {
473: if ((L = gLinks[l]) != NULL) {
474: B = L->bund;
475: if (nasport != -1 && nasport != l)
476: continue;
477: if (sesid && strcmp(sesid, L->session_id))
478: continue;
479: if (link && strcmp(link, L->name))
480: continue;
481: if (msesid && strcmp(msesid, L->msession_id))
482: continue;
483: if (username && strcmp(username, L->lcp.auth.params.authname))
484: continue;
485: if (called && !PhysGetCalledNum(L, buf, sizeof(buf)) &&
486: strcmp(called, buf))
487: continue;
488: if (calling && !PhysGetCallingNum(L, buf, sizeof(buf)) &&
489: strcmp(calling, buf))
490: continue;
491: if (bundle && (!B || strcmp(bundle, B->name)))
492: continue;
493: if (iface && (!B || strcmp(iface, B->iface.ifname)))
494: continue;
1.1.1.3 ! misho 495: if (ifindex >= 0 && (!B || (uint)ifindex != B->iface.ifindex))
1.1 misho 496: continue;
1.1.1.3 ! misho 497: if (ip.s_addr != INADDR_BROADCAST && (!B ||
1.1 misho 498: ip.s_addr != B->iface.peer_addr.u.ip4.s_addr))
499: continue;
500:
1.1.1.2 misho 501: Log(LG_RADIUS2, ("radsrv: Matched link: %s", L->name));
1.1 misho 502: if (L->tmpl) {
503: Log(LG_ERR, ("radsrv: Impossible to affect template"));
504: err = 504;
505: continue;
506: }
507: found++;
1.1.1.2 misho 508:
1.1 misho 509: if (result == RAD_DISCONNECT_REQUEST) {
510: RecordLinkUpDownReason(NULL, L, 0, STR_MANUALLY, NULL);
511: LinkClose(L);
512: } else { /* CoA */
513: if (B && B->iface.up && !B->iface.dod) {
514: if (B->iface.ip_up)
515: IfaceIpIfaceDown(B);
516: if (B->iface.ipv6_up)
517: IfaceIpv6IfaceDown(B);
518: IfaceDown(B);
519: }
520: #ifdef USE_IPFW
521: ACLDestroy(L->lcp.auth.params.acl_rule);
522: ACLDestroy(L->lcp.auth.params.acl_pipe);
523: ACLDestroy(L->lcp.auth.params.acl_queue);
524: ACLDestroy(L->lcp.auth.params.acl_table);
525: L->lcp.auth.params.acl_rule = NULL;
526: L->lcp.auth.params.acl_pipe = NULL;
527: L->lcp.auth.params.acl_queue = NULL;
528: L->lcp.auth.params.acl_table = NULL;
529: ACLCopy(acl_rule, &L->lcp.auth.params.acl_rule);
530: ACLCopy(acl_pipe, &L->lcp.auth.params.acl_pipe);
531: ACLCopy(acl_queue, &L->lcp.auth.params.acl_queue);
532: ACLCopy(acl_table, &L->lcp.auth.params.acl_table);
533: #endif /* USE_IPFW */
1.1.1.2 misho 534: if (rad_class != NULL) {
535: if (L->lcp.auth.params.class != NULL)
536: Freee(L->lcp.auth.params.class);
537: L->lcp.auth.params.class = Mdup(MB_AUTH, rad_class, class_len);
538: L->lcp.auth.params.class_len = class_len;
539: }
1.1 misho 540: #ifdef USE_NG_BPF
541: for (i = 0; i < ACL_FILTERS; i++) {
542: ACLDestroy(L->lcp.auth.params.acl_filters[i]);
543: L->lcp.auth.params.acl_filters[i] = NULL;
544: ACLCopy(acl_filters[i], &L->lcp.auth.params.acl_filters[i]);
545: }
546: for (i = 0; i < ACL_DIRS; i++) {
547: ACLDestroy(L->lcp.auth.params.acl_limits[i]);
548: L->lcp.auth.params.acl_limits[i] = NULL;
549: ACLCopy(acl_limits[i], &L->lcp.auth.params.acl_limits[i]);
550: }
551: strcpy(L->lcp.auth.params.std_acct[0], std_acct[0]);
552: strcpy(L->lcp.auth.params.std_acct[1], std_acct[1]);
553: #endif
1.1.1.3 ! misho 554: if (session_timeout != UINT_MAX)
1.1 misho 555: L->lcp.auth.params.session_timeout = session_timeout;
1.1.1.3 ! misho 556: if (idle_timeout != UINT_MAX)
1.1 misho 557: L->lcp.auth.params.idle_timeout = idle_timeout;
1.1.1.3 ! misho 558: if (acct_update != UINT_MAX) {
1.1 misho 559: L->lcp.auth.params.acct_update = acct_update;
560: /* Stop accounting update timer if running. */
561: TimerStop(&L->lcp.auth.acct_timer);
562: if (B) {
563: /* Start accounting update timer if needed. */
564: u_int updateInterval;
565: if (L->lcp.auth.params.acct_update > 0)
566: updateInterval = L->lcp.auth.params.acct_update;
567: else
568: updateInterval = L->lcp.auth.conf.acct_update;
569: if (updateInterval > 0) {
570: TimerInit(&L->lcp.auth.acct_timer, "AuthAccountTimer",
571: updateInterval * SECONDS, AuthAccountTimeout, L);
572: TimerStartRecurring(&L->lcp.auth.acct_timer);
573: }
574: }
575: }
576: if (B && B->iface.up && !B->iface.dod) {
577: authparamsDestroy(&B->params);
578: authparamsCopy(&L->lcp.auth.params,&B->params);
579: if (B->iface.ip_up)
580: IfaceIpIfaceUp(B, 1);
581: if (B->iface.ipv6_up)
582: IfaceIpv6IfaceUp(B, 1);
583: IfaceUp(B, 1);
584: }
585: }
586: }
587: }
588: if (result == RAD_DISCONNECT_REQUEST) {
589: if (found) {
590: rad_create_response(w->handle, RAD_DISCONNECT_ACK);
591: } else {
592: rad_create_response(w->handle, RAD_DISCONNECT_NAK);
593: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
594: }
595: } else {
596: if (found) {
597: rad_create_response(w->handle, RAD_COA_ACK);
598: } else {
599: rad_create_response(w->handle, RAD_COA_NAK);
600: rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
601: }
602: }
603: if (state != NULL)
604: rad_put_attr(w->handle, RAD_STATE, state, state_len);
605: if (authentic)
606: rad_put_message_authentic(w->handle);
607: rad_send_response(w->handle);
608:
609: cleanup:
610: if (username)
611: free(username);
1.1.1.2 misho 612: if (rad_class != NULL)
613: Freee(rad_class);
1.1 misho 614: if (called)
615: free(called);
616: if (calling)
617: free(calling);
618: if (sesid)
619: free(sesid);
620: if (msesid)
621: free(msesid);
622: if (link)
623: free(link);
624: if (bundle)
625: free(bundle);
626: if (iface)
627: free(iface);
628: if (state != NULL)
629: Freee(state);
630: #ifdef USE_IPFW
631: ACLDestroy(acl_rule);
632: ACLDestroy(acl_pipe);
633: ACLDestroy(acl_queue);
634: ACLDestroy(acl_table);
635: #endif /* USE_IPFW */
636: #ifdef USE_NG_BPF
637: for (i = 0; i < ACL_FILTERS; i++)
638: ACLDestroy(acl_filters[i]);
639: for (i = 0; i < ACL_DIRS; i++)
640: ACLDestroy(acl_limits[i]);
641: #endif /* USE_NG_BPF */
642: }
643:
644: /*
645: * RadsrvOpen()
646: */
647:
648: int
649: RadsrvOpen(Radsrv w)
650: {
651: char addrstr[INET6_ADDRSTRLEN];
652: struct sockaddr_in sin;
653: struct radiusclient_conf *s;
654:
655: if (w->handle) {
656: Log(LG_ERR, ("radsrv: radsrv already running"));
657: return (-1);
658: }
659:
660: if ((w->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
661: Perror("%s: Cannot create socket", __FUNCTION__);
662: return (-1);
663: }
664: memset(&sin, 0, sizeof sin);
665: sin.sin_len = sizeof sin;
666: sin.sin_family = AF_INET;
667: sin.sin_addr = w->addr.u.ip4;
668: sin.sin_port = htons(w->port);
669: if (bind(w->fd, (const struct sockaddr *)&sin,
670: sizeof sin) == -1) {
671: Log(LG_ERR, ("%s: bind: %s", __FUNCTION__, strerror(errno)));
672: close(w->fd);
673: w->fd = -1;
674: return (-1);
675: }
676:
677: if (!(w->handle = rad_server_open(w->fd))) {
678: Log(LG_ERR, ("%s: rad_server_open error", __FUNCTION__));
679: close(w->fd);
680: w->fd = -1;
681: return(-1);
682: }
683:
684: EventRegister(&w->event, EVENT_READ, w->fd,
685: EVENT_RECURRING, RadsrvEvent, w);
686:
687: s = w->clients;
688: while (s) {
689: Log(LG_RADIUS2, ("radsrv: Adding client %s", s->hostname));
690: if (rad_add_server (w->handle, s->hostname,
691: 0, s->sharedsecret, 0, 0) == -1) {
692: Log(LG_RADIUS, ("radsrv: Adding client error: %s",
693: rad_strerror(w->handle)));
694: }
695: s = s->next;
696: }
697:
1.1.1.2 misho 698: Log(LG_ERR, ("radsrv: listening on %s %d",
1.1 misho 699: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
700: return (0);
701: }
702:
703: /*
704: * RadsrvClose()
705: */
706:
707: int
708: RadsrvClose(Radsrv w)
709: {
710:
711: if (!w->handle) {
712: Log(LG_ERR, ("radsrv: radsrv is not running"));
713: return (-1);
714: }
715: EventUnRegister(&w->event);
716: rad_close(w->handle);
717: w->handle = NULL;
718:
719: Log(LG_ERR, ("radsrv: stop listening"));
720: return (0);
721: }
722:
723: /*
724: * RadsrvStat()
725: */
726:
727: int
728: RadsrvStat(Context ctx, int ac, char *av[], void *arg)
729: {
730: Radsrv w = &gRadsrv;
731: char addrstr[64];
732: struct radiusclient_conf *client;
733:
734: Printf("Radsrv configuration:\r\n");
735: Printf("\tState : %s\r\n", w->handle ? "OPENED" : "CLOSED");
736: Printf("\tSelf : %s %d\r\n",
737: u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port);
738: Printf("\tPeer:\r\n");
739: client = w->clients;
740: while (client) {
741: Printf("\t %s ********\r\n", client->hostname);
742: client = client->next;
743: }
744: Printf("Radsrv options:\r\n");
745: OptStat(ctx, &w->options, gConfList);
746:
747: return (0);
748: }
749:
750: /*
751: * RadsrvSetCommand()
752: */
753:
754: static int
755: RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg)
756: {
757: Radsrv w = &gRadsrv;
758: int port, count;
759: struct radiusclient_conf *peer, *t_peer;
760:
761: switch ((intptr_t)arg) {
762:
763: case SET_OPEN:
764: RadsrvOpen(w);
765: break;
766:
767: case SET_CLOSE:
768: RadsrvClose(w);
769: break;
770:
771: case SET_ENABLE:
772: EnableCommand(ac, av, &w->options, gConfList);
773: break;
774:
775: case SET_DISABLE:
776: DisableCommand(ac, av, &w->options, gConfList);
777: break;
778:
779: case SET_SELF:
780: if (ac < 1 || ac > 2)
781: return(-1);
782:
783: if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4))
784: Error("Bogus IP address given %s", av[0]);
785:
786: if (ac == 2) {
787: port = strtol(av[1], NULL, 10);
788: if (port < 1 || port > 65535)
789: Error("Bogus port given %s", av[1]);
790: w->port=port;
791: }
792: break;
793:
794: case SET_PEER:
795: if (ac != 2)
796: return(-1);
797:
798: count = 0;
799: for ( t_peer = w->clients ; t_peer ;
800: t_peer = t_peer->next) {
801: count++;
802: }
803: if (count > RADSRV_MAX_SERVERS) {
804: Error("cannot configure more than %d peers",
805: RADSRV_MAX_SERVERS);
806: }
807: if (strlen(av[0]) > MAXHOSTNAMELEN-1)
808: Error("Hostname too long. > %d char.", MAXHOSTNAMELEN-1);
809: if (strlen(av[1]) > 127)
810: Error("Shared Secret too long. > 127 char.");
811:
812: peer = Malloc(MB_RADSRV, sizeof(*peer));
813: peer->hostname = Mstrdup(MB_RADSRV, av[0]);
814: peer->sharedsecret = Mstrdup(MB_RADSRV, av[1]);
815: peer->next = w->clients;
816: w->clients = peer;
817: break;
818:
819: default:
820: return(-1);
821:
822: }
823:
824: return 0;
825: }
826:
827: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>