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