Annotation of embedaddon/mpd/src/radius.c, revision 1.1.1.2
1.1 misho 1: /*
2: * See ``COPYRIGHT.mpd''
3: *
1.1.1.2 ! misho 4: * $Id: radius.c,v 1.162 2012/12/17 10:14:14 dmitryluhtionov Exp $
1.1 misho 5: *
6: */
7:
8: #include "ppp.h"
9: #ifdef PHYSTYPE_PPPOE
10: #include "pppoe.h"
11: #endif
12: #ifdef PHYSTYPE_PPTP
13: #include "pptp.h"
14: #endif
15: #ifdef PHYSTYPE_L2TP
16: #include "l2tp.h"
17: #endif
18: #ifdef PHYSTYPE_TCP
19: #include "tcp.h"
20: #endif
21: #ifdef PHYSTYPE_UDP
22: #include "udp.h"
23: #endif
24: #ifdef PHYSTYPE_MODEM
25: #include "modem.h"
26: #endif
27: #ifdef PHYSTYPE_NG_SOCKET
28: #include "ng.h"
29: #endif
30: #include "util.h"
31:
32: #include <sys/types.h>
33:
34: #include <radlib.h>
35: #include <radlib_vs.h>
36:
37:
38: /* Global variables */
39:
40: static int RadiusSetCommand(Context ctx, int ac, char *av[], void *arg);
41: static int RadiusAddServer(AuthData auth, short request_type);
42: static int RadiusOpen(AuthData auth, short request_type);
43: static int RadiusStart(AuthData auth, short request_type);
44: static int RadiusPutAuth(AuthData auth);
45: static int RadiusPutAcct(AuthData auth);
46: static int RadiusGetParams(AuthData auth, int eap_proxy);
47: static int RadiusSendRequest(AuthData auth);
48:
49: /* Set menu options */
50:
51: enum {
1.1.1.2 ! misho 52: UNSET_SERVER,
1.1 misho 53: SET_SERVER,
54: SET_ME,
55: SET_MEV6,
56: SET_IDENTIFIER,
57: SET_TIMEOUT,
58: SET_RETRIES,
59: SET_CONFIG,
60: SET_ENABLE,
61: SET_DISABLE
62: };
63:
64: /*
65: * GLOBAL VARIABLES
66: */
1.1.1.2 ! misho 67: const struct cmdtab RadiusUnSetCmds[] = {
! 68: { "server {name} [{auth port}] [{acct port}]", "Unset (remove) radius server" ,
! 69: RadiusSetCommand, NULL, 2, (void *) UNSET_SERVER },
! 70: { NULL },
! 71: };
! 72:
1.1 misho 73: const struct cmdtab RadiusSetCmds[] = {
74: { "server {name} {secret} [{auth port}] [{acct port}]", "Set radius server parameters" ,
75: RadiusSetCommand, NULL, 2, (void *) SET_SERVER },
76: { "me {ip}", "Set NAS IP address" ,
77: RadiusSetCommand, NULL, 2, (void *) SET_ME },
78: { "v6me {ip}", "Set NAS IPv6 address" ,
79: RadiusSetCommand, NULL, 2, (void *) SET_MEV6 },
80: { "identifier {name}", "Set NAS identifier string" ,
81: RadiusSetCommand, NULL, 2, (void *) SET_IDENTIFIER },
82: { "timeout {seconds}", "Set timeout in seconds",
83: RadiusSetCommand, NULL, 2, (void *) SET_TIMEOUT },
84: { "retries {# retries}", "set number of retries",
85: RadiusSetCommand, NULL, 2, (void *) SET_RETRIES },
86: { "config {path to radius.conf}", "set path to config file for libradius",
87: RadiusSetCommand, NULL, 2, (void *) SET_CONFIG },
88: { "enable [opt ...]", "Enable option",
89: RadiusSetCommand, NULL, 2, (void *) SET_ENABLE },
90: { "disable [opt ...]", "Disable option",
91: RadiusSetCommand, NULL, 2, (void *) SET_DISABLE },
92: { NULL },
93: };
94:
95: /*
96: * INTERNAL VARIABLES
97: */
98:
99: static struct confinfo gConfList[] = {
100: { 0, RADIUS_CONF_MESSAGE_AUTHENTIC, "message-authentic" },
101: { 0, 0, NULL },
102: };
103:
104: #define RAD_NACK 0
105: #define RAD_ACK 1
106:
107: static int
108: rad_put_string_tag(struct rad_handle *h, int type, u_char tag, const char *str);
109:
110: static int
111: rad_put_string_tag(struct rad_handle *h, int type, u_char tag, const char *str)
112: {
113: char *tmp;
114: int res;
115: int len = strlen(str);
116:
117: if (tag == 0) {
118: res = rad_put_attr(h, type, str, len);
119: } else if (tag <= 0x1F) {
120: tmp = Malloc(MB_RADIUS, len + 1);
121: tmp[0] = tag;
122: memcpy(tmp + 1, str, len);
123: res = rad_put_attr(h, type, tmp, len + 1);
124: Freee(tmp);
125: } else {
126: res = -1;
127: }
128: return (res);
129: }
130:
131: /*
132: * RadiusInit()
133: */
134:
135: void
136: RadiusInit(Link l)
137: {
138: RadConf const conf = &l->lcp.auth.conf.radius;
139:
140: memset(conf, 0, sizeof(*conf));
141: conf->radius_retries = 3;
142: conf->radius_timeout = 5;
143: }
144:
145: int
146: RadiusAuthenticate(AuthData auth)
147: {
148: Log(LG_RADIUS, ("[%s] RADIUS: Authenticating user '%s'",
149: auth->info.lnkname, auth->params.authname));
150:
151: if ((RadiusStart(auth, RAD_ACCESS_REQUEST) == RAD_NACK) ||
152: (RadiusPutAuth(auth) == RAD_NACK) ||
153: (RadiusSendRequest(auth) == RAD_NACK)) {
154: return (-1);
155: }
156:
157: return (0);
158: }
159:
160: /*
161: * RadiusAccount()
162: *
163: * Do RADIUS accounting
164: * NOTE: thread-safety is needed here
165: */
166:
167: int
168: RadiusAccount(AuthData auth)
169: {
170: Log(auth->acct_type != AUTH_ACCT_UPDATE ? LG_RADIUS : LG_RADIUS2,
171: ("[%s] RADIUS: Accounting user '%s' (Type: %d)",
172: auth->info.lnkname, auth->params.authname, auth->acct_type));
173:
174: if ((RadiusStart(auth, RAD_ACCOUNTING_REQUEST) == RAD_NACK) ||
175: (RadiusPutAcct(auth) == RAD_NACK) ||
176: (RadiusSendRequest(auth) == RAD_NACK)) {
177: return (-1);
178: }
179:
180: return (0);
181: }
182:
183: /*
184: * RadiusEapProxy()
185: *
186: * paction handler for RADIUS EAP Proxy requests.
187: * Thread-Safety is needed here
188: * auth->status must be set to AUTH_STATUS_FAIL, if the
189: * request couldn't sent, because for EAP a successful
190: * RADIUS request is mandatory
191: */
192:
193: void
194: RadiusEapProxy(void *arg)
195: {
196: AuthData auth = (AuthData)arg;
197: int pos = 0, mlen = RAD_MAX_ATTR_LEN;
198:
199: Log(LG_RADIUS, ("[%s] RADIUS: EAP proxying user '%s'",
200: auth->info.lnkname, auth->params.authname));
201:
202: if (RadiusStart(auth, RAD_ACCESS_REQUEST) == RAD_NACK) {
203: auth->status = AUTH_STATUS_FAIL;
204: return;
205: }
206:
207: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s",
208: auth->info.lnkname, auth->params.authname));
209: if (rad_put_string(auth->radius.handle, RAD_USER_NAME, auth->params.authname) == -1) {
210: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s",
211: auth->info.lnkname, rad_strerror(auth->radius.handle)));
212: auth->status = AUTH_STATUS_FAIL;
213: return;
214: }
215:
216: for (pos = 0; pos <= auth->params.eapmsg_len; pos += RAD_MAX_ATTR_LEN) {
217: char chunk[RAD_MAX_ATTR_LEN];
218:
219: if (pos + RAD_MAX_ATTR_LEN > auth->params.eapmsg_len)
220: mlen = auth->params.eapmsg_len - pos;
221:
222: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_EAP_MESSAGE: len %d of %d",
223: auth->info.lnkname, mlen, auth->params.eapmsg_len));
224: memcpy(chunk, &auth->params.eapmsg[pos], mlen);
225: if (rad_put_attr(auth->radius.handle, RAD_EAP_MESSAGE, chunk, mlen) == -1) {
226: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_EAP_MESSAGE failed %s",
227: auth->info.lnkname, rad_strerror(auth->radius.handle)));
228: auth->status = AUTH_STATUS_FAIL;
229: return;
230: }
231: }
232:
233: if (RadiusSendRequest(auth) == RAD_NACK) {
234: auth->status = AUTH_STATUS_FAIL;
235: return;
236: }
237:
238: return;
239: }
240:
241: void
242: RadiusClose(AuthData auth)
243: {
244: if (auth->radius.handle != NULL)
245: rad_close(auth->radius.handle);
246: auth->radius.handle = NULL;
247: }
248:
249: int
250: RadStat(Context ctx, int ac, char *av[], void *arg)
251: {
252: Auth const a = &ctx->lnk->lcp.auth;
253: RadConf const conf = &a->conf.radius;
254: int i;
255: char *buf;
256: RadServe_Conf server;
257: char buf1[64];
258:
259: Printf("Configuration:\r\n");
260: Printf("\tTimeout : %d\r\n", conf->radius_timeout);
261: Printf("\tRetries : %d\r\n", conf->radius_retries);
262: Printf("\tConfig-file : %s\r\n", (conf->file ? conf->file : "none"));
263: Printf("\tMe (NAS-IP) : %s\r\n", inet_ntoa(conf->radius_me));
264: Printf("\tv6Me (NAS-IP): %s\r\n", u_addrtoa(&conf->radius_mev6, buf1, sizeof(buf1)));
265: Printf("\tIdentifier : %s\r\n", (conf->identifier ? conf->identifier : ""));
266:
267: if (conf->server != NULL) {
268:
269: server = conf->server;
270: i = 1;
271:
272: while (server) {
273: Printf("\t--------------- Radius Server %d ---------------\r\n", i);
274: Printf("\thostname : %s\r\n", server->hostname);
275: Printf("\tsecret : *********\r\n");
276: Printf("\tauth port : %d\r\n", server->auth_port);
277: Printf("\tacct port : %d\r\n", server->acct_port);
278: i++;
279: server = server->next;
280: }
281:
282: }
283:
284: Printf("RADIUS options\r\n");
285: OptStat(ctx, &conf->options, gConfList);
286:
287: Printf("Data:\r\n");
288: Printf("\tAuthenticated : %s\r\n", a->params.authentic == AUTH_CONF_RADIUS_AUTH ?
289: "yes" : "no");
290:
291: buf = Bin2Hex(a->params.state, a->params.state_len);
292: Printf("\tState : 0x%s\r\n", buf);
293: Freee(buf);
294:
295: buf = Bin2Hex(a->params.class, a->params.class_len);
296: Printf("\tClass : 0x%s\r\n", buf);
297: Freee(buf);
298:
299: return (0);
300: }
301:
302: static int
303: RadiusAddServer(AuthData auth, short request_type)
304: {
305: RadConf const c = &auth->conf.radius;
306: RadServe_Conf s;
307:
308: if (c->server == NULL)
309: return (RAD_ACK);
310:
311: s = c->server;
312: while (s) {
313:
314: if (request_type == RAD_ACCESS_REQUEST) {
315: if (s->auth_port != 0) {
316: Log(LG_RADIUS2, ("[%s] RADIUS: Adding server %s %d", auth->info.lnkname, s->hostname, s->auth_port));
317: if (rad_add_server (auth->radius.handle, s->hostname,
318: s->auth_port,
319: s->sharedsecret,
320: c->radius_timeout,
321: c->radius_retries) == -1) {
322: Log(LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname,
323: rad_strerror(auth->radius.handle)));
324: return (RAD_NACK);
325: }
326: }
327: } else if (s->acct_port != 0) {
328: Log(LG_RADIUS2, ("[%s] RADIUS: Adding server %s %d", auth->info.lnkname, s->hostname, s->acct_port));
329: if (rad_add_server (auth->radius.handle, s->hostname,
330: s->acct_port,
331: s->sharedsecret,
332: c->radius_timeout,
333: c->radius_retries) == -1) {
334: Log(LG_RADIUS, ("[%s] RADIUS: Adding server error: %s", auth->info.lnkname,
335: rad_strerror(auth->radius.handle)));
336: return (RAD_NACK);
337: }
338: }
339:
340: s = s->next;
341: }
342:
343: return (RAD_ACK);
344: }
345:
346: /* Set menu options */
347: static int
348: RadiusSetCommand(Context ctx, int ac, char *av[], void *arg)
349: {
350: RadConf const conf = &ctx->lnk->lcp.auth.conf.radius;
351: RadServe_Conf server;
352: RadServe_Conf t_server;
1.1.1.2 ! misho 353: RadServe_Conf next, prev;
1.1 misho 354: int val, count;
355: struct u_addr t;
356: int auth_port = 1812;
357: int acct_port = 1813;
358:
359: if (ac == 0)
360: return(-1);
361:
362: switch ((intptr_t)arg) {
363:
1.1.1.2 ! misho 364: case UNSET_SERVER:
! 365:
! 366: if (ac > 3 || ac < 1) {
! 367: return(-1);
! 368: }
! 369: for ( prev = NULL, t_server = conf->server ;
! 370: t_server != NULL && (next = t_server->next, 1) ;
! 371: prev = t_server, t_server = next) {
! 372:
! 373: if (strcmp(t_server->hostname, av[0]) != 0)
! 374: continue;
! 375: if (ac > 1 && t_server->auth_port != atoi(av[1]))
! 376: continue;
! 377: if (ac > 2 && t_server->acct_port != atoi(av[2]))
! 378: continue;
! 379:
! 380: if (t_server == conf->server) {
! 381: conf->server = t_server->next;
! 382: } else {
! 383: prev->next = t_server->next;
! 384: t_server->next = NULL;
! 385: }
! 386:
! 387: Freee(t_server->hostname);
! 388: Freee(t_server->sharedsecret);
! 389: Freee(t_server);
! 390: t_server = prev;
! 391: }
! 392:
! 393: break;
! 394:
1.1 misho 395: case SET_SERVER:
396: if (ac > 4 || ac < 2) {
397: return(-1);
398: }
399:
400: count = 0;
401: for ( t_server = conf->server ; t_server ;
402: t_server = t_server->next) {
403: count++;
404: }
405: if (count > RADIUS_MAX_SERVERS) {
406: Error("cannot configure more than %d servers",
407: RADIUS_MAX_SERVERS);
408: }
409: if (strlen(av[0]) > MAXHOSTNAMELEN)
410: Error("Hostname too long. > %d char.", MAXHOSTNAMELEN);
411: if (strlen(av[1]) > 127)
412: Error("Shared Secret too long. > 127 char.");
413: if (ac > 2) {
414: auth_port = atoi(av[2]);
415: if (auth_port < 0 || auth_port >= 65535)
416: Error("Auth Port number too high. > 65535");
417: }
418: if (ac > 3) {
419: acct_port = atoi(av[3]);
420: if (acct_port < 0 || acct_port >= 65535)
421: Error("Acct Port number too high > 65535");
422: }
423: if (auth_port == 0 && acct_port == 0)
424: Error("At least one port must be specified.");
425:
426: server = Malloc(MB_RADIUS, sizeof(*server));
427: server->auth_port = auth_port;
428: server->acct_port = acct_port;
429: server->next = NULL;
430: server->hostname = Mstrdup(MB_RADIUS, av[0]);
431: server->sharedsecret = Mstrdup(MB_RADIUS, av[1]);
432: if (conf->server != NULL)
433: server->next = conf->server;
434: conf->server = server;
435:
436: break;
437:
438: case SET_ME:
439: if (ParseAddr(*av, &t, ALLOW_IPV4)) {
440: u_addrtoin_addr(&t,&conf->radius_me);
441: } else
442: Error("Bad NAS address '%s'.", *av);
443: break;
444:
445: case SET_MEV6:
446: if (!ParseAddr(*av, &conf->radius_mev6, ALLOW_IPV6))
447: Error("Bad NAS address '%s'.", *av);
448: break;
449:
450: case SET_TIMEOUT:
451: val = atoi(*av);
452: if (val <= 0)
453: Error("Timeout must be positive.");
454: else
455: conf->radius_timeout = val;
456: break;
457:
458: case SET_RETRIES:
459: val = atoi(*av);
460: if (val <= 0)
461: Error("Retries must be positive.");
462: else
463: conf->radius_retries = val;
464: break;
465:
466: case SET_CONFIG:
467: if (strlen(av[0]) > PATH_MAX) {
468: Error("RADIUS: Config file name too long.");
469: } else {
470: Freee(conf->file);
471: conf->file = Mstrdup(MB_RADIUS, av[0]);
472: }
473: break;
474:
475: case SET_IDENTIFIER:
476: if (strlen(av[0]) > RAD_MAX_ATTR_LEN) {
477: Error("RADIUS: Identifier too long.");
478: } else {
479: Freee(conf->identifier);
480: if (av[0][0] == 0)
481: conf->identifier = NULL;
482: else
483: conf->identifier = Mstrdup(MB_RADIUS, av[0]);
484: }
485: break;
486:
487: case SET_ENABLE:
488: EnableCommand(ac, av, &conf->options, gConfList);
489: break;
490:
491: case SET_DISABLE:
492: DisableCommand(ac, av, &conf->options, gConfList);
493: break;
494:
495: default:
496: assert(0);
497: }
498:
499: return 0;
500: }
501:
502: static int
503: RadiusOpen(AuthData auth, short request_type)
504: {
505: RadConf const conf = &auth->conf.radius;
506:
507: if (request_type == RAD_ACCESS_REQUEST) {
508:
509: if ((auth->radius.handle = rad_open()) == NULL) {
510: Log(LG_RADIUS, ("[%s] RADIUS: rad_open failed", auth->info.lnkname));
511: return (RAD_NACK);
512: }
513: } else { /* RAD_ACCOUNTING_REQUEST */
514:
515: if ((auth->radius.handle = rad_acct_open()) == NULL) {
516: Log(LG_RADIUS, ("[%s] RADIUS: rad_acct_open failed", auth->info.lnkname));
517: return (RAD_NACK);
518: }
519: }
520:
521: if (conf->file && strlen(conf->file)) {
522: Log(LG_RADIUS2, ("[%s] RADIUS: using %s", auth->info.lnkname, conf->file));
523: if (rad_config(auth->radius.handle, conf->file) != 0) {
524: Log(LG_RADIUS, ("[%s] RADIUS: rad_config: %s", auth->info.lnkname,
525: rad_strerror(auth->radius.handle)));
526: return (RAD_NACK);
527: }
528: }
529:
530: if (RadiusAddServer(auth, request_type) == RAD_NACK)
531: return (RAD_NACK);
532:
533: return (RAD_ACK);
534: }
535:
536: static int
537: RadiusStart(AuthData auth, short request_type)
538: {
539: RadConf const conf = &auth->conf.radius;
540: char host[MAXHOSTNAMELEN];
541: int porttype;
542: char buf[48];
543: char *tmpval;
544:
545: if (RadiusOpen(auth, request_type) == RAD_NACK)
546: return RAD_NACK;
547:
548: if (rad_create_request(auth->radius.handle, request_type) == -1) {
549: Log(LG_RADIUS, ("[%s] RADIUS: rad_create_request: %s",
550: auth->info.lnkname, rad_strerror(auth->radius.handle)));
551: return (RAD_NACK);
552: }
553:
554: if (conf->identifier) {
555: tmpval = conf->identifier;
556: } else {
557: if (gethostname(host, sizeof(host)) == -1) {
558: Log(LG_RADIUS, ("[%s] RADIUS: gethostname() for RAD_NAS_IDENTIFIER failed",
559: auth->info.lnkname));
560: return (RAD_NACK);
561: }
562: tmpval = host;
563: }
564: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IDENTIFIER: %s",
565: auth->info.lnkname, tmpval));
566: if (rad_put_string(auth->radius.handle, RAD_NAS_IDENTIFIER, tmpval) == -1) {
567: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IDENTIFIER failed %s", auth->info.lnkname,
568: rad_strerror(auth->radius.handle)));
569: return (RAD_NACK);
570: }
571:
572: if (conf->radius_me.s_addr != 0) {
573: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IP_ADDRESS: %s",
574: auth->info.lnkname, inet_ntoa(conf->radius_me)));
575: if (rad_put_addr(auth->radius.handle, RAD_NAS_IP_ADDRESS, conf->radius_me) == -1) {
576: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IP_ADDRESS failed %s",
577: auth->info.lnkname, rad_strerror(auth->radius.handle)));
578: return (RAD_NACK);
579: }
580: }
581:
582: if (!u_addrempty(&conf->radius_mev6)) {
583: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_IPV6_ADDRESS: %s",
584: auth->info.lnkname, u_addrtoa(&conf->radius_mev6,buf,sizeof(buf))));
585: if (rad_put_attr(auth->radius.handle, RAD_NAS_IPV6_ADDRESS, &conf->radius_mev6.u.ip6, sizeof(conf->radius_mev6.u.ip6)) == -1) {
586: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_IPV6_ADDRESS failed %s",
587: auth->info.lnkname, rad_strerror(auth->radius.handle)));
588: return (RAD_NACK);
589: }
590: }
591:
592: /* Insert the Message Authenticator RFC 3579
593: * If using EAP this is mandatory
594: */
595: if ((Enabled(&conf->options, RADIUS_CONF_MESSAGE_AUTHENTIC)
596: || auth->proto == PROTO_EAP)
597: && request_type != RAD_ACCOUNTING_REQUEST) {
598: Log(LG_RADIUS2, ("[%s] RADIUS: Put Message Authenticator", auth->info.lnkname));
599: if (rad_put_message_authentic(auth->radius.handle) == -1) {
600: Log(LG_RADIUS, ("[%s] RADIUS: Put message_authentic failed %s",
601: auth->info.lnkname, rad_strerror(auth->radius.handle)));
602: return (RAD_NACK);
603: }
604: }
605:
606: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_SESSION_ID: %s",
607: auth->info.lnkname, auth->info.session_id));
608: if (rad_put_string(auth->radius.handle, RAD_ACCT_SESSION_ID, auth->info.session_id) != 0) {
609: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_ID: %s",
610: auth->info.lnkname, rad_strerror(auth->radius.handle)));
611: return (RAD_NACK);
612: }
613:
614: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_PORT: %d",
615: auth->info.lnkname, auth->info.linkID));
616: if (rad_put_int(auth->radius.handle, RAD_NAS_PORT, auth->info.linkID) == -1) {
617: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT failed %s",
618: auth->info.lnkname, rad_strerror(auth->radius.handle)));
619: return (RAD_NACK);
620: }
621:
622: #ifdef PHYSTYPE_MODEM
623: if (auth->info.phys_type == &gModemPhysType) {
624: porttype = RAD_ASYNC;
625: } else
626: #endif
627: #ifdef PHYSTYPE_NG_SOCKET
628: if (auth->info.phys_type == &gNgPhysType) {
629: porttype = RAD_SYNC;
630: } else
631: #endif
632: #ifdef PHYSTYPE_PPPOE
633: if (auth->info.phys_type == &gPppoePhysType) {
634: porttype = RAD_ETHERNET;
635: } else
636: #endif
637: {
638: porttype = RAD_VIRTUAL;
639: };
640: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_PORT_TYPE: %d",
641: auth->info.lnkname, porttype));
642: if (rad_put_int(auth->radius.handle, RAD_NAS_PORT_TYPE, porttype) == -1) {
643: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_TYPE failed %s",
644: auth->info.lnkname, rad_strerror(auth->radius.handle)));
645: return (RAD_NACK);
646: }
647:
648: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_SERVICE_TYPE: RAD_FRAMED",
649: auth->info.lnkname));
650: if (rad_put_int(auth->radius.handle, RAD_SERVICE_TYPE, RAD_FRAMED) == -1) {
651: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_SERVICE_TYPE failed %s",
652: auth->info.lnkname, rad_strerror(auth->radius.handle)));
653: return (RAD_NACK);
654: }
655:
656: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_PROTOCOL: RAD_PPP",
657: auth->info.lnkname));
658: if (rad_put_int(auth->radius.handle, RAD_FRAMED_PROTOCOL, RAD_PPP) == -1) {
659: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_PROTOCOL failed %s",
660: auth->info.lnkname, rad_strerror(auth->radius.handle)));
661: return (RAD_NACK);
662: }
663:
664: if (auth->params.state != NULL) {
665: tmpval = Bin2Hex(auth->params.state, auth->params.state_len);
666: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_STATE: 0x%s", auth->info.lnkname, tmpval));
667: Freee(tmpval);
668: if (rad_put_attr(auth->radius.handle, RAD_STATE, auth->params.state, auth->params.state_len) == -1) {
669: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_STATE failed %s",
670: auth->info.lnkname, rad_strerror(auth->radius.handle)));
671: return (RAD_NACK);
672: }
673: }
674:
675: if (auth->params.class != NULL) {
676: tmpval = Bin2Hex(auth->params.class, auth->params.class_len);
677: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CLASS: 0x%s", auth->info.lnkname, tmpval));
678: Freee(tmpval);
679: if (rad_put_attr(auth->radius.handle, RAD_CLASS, auth->params.class, auth->params.class_len) == -1) {
680: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CLASS failed %s",
681: auth->info.lnkname, rad_strerror(auth->radius.handle)));
682: return (RAD_NACK);
683: }
684: }
685:
686: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CALLING_STATION_ID: %s",
687: auth->info.lnkname, auth->params.callingnum));
688: if (rad_put_string(auth->radius.handle, RAD_CALLING_STATION_ID,
689: auth->params.callingnum) == -1) {
690: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLING_STATION_ID failed %s",
691: auth->info.lnkname, rad_strerror(auth->radius.handle)));
692: return (RAD_NACK);
693: }
694: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CALLED_STATION_ID: %s",
695: auth->info.lnkname, auth->params.callednum));
696: if (rad_put_string(auth->radius.handle, RAD_CALLED_STATION_ID,
697: auth->params.callednum) == -1) {
698: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CALLED_STATION_ID failed %s",
699: auth->info.lnkname, rad_strerror(auth->radius.handle)));
700: return (RAD_NACK);
701: }
702:
703: if (auth->params.peeriface[0]) {
704: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_NAS_PORT_ID: %s",
705: auth->info.lnkname, auth->params.peeriface));
706: if (rad_put_string(auth->radius.handle, RAD_NAS_PORT_ID,
707: auth->params.peeriface) == -1) {
708: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_NAS_PORT_ID failed %s",
709: auth->info.lnkname, rad_strerror(auth->radius.handle)));
710: return (RAD_NACK);
711: }
712: }
713:
714: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_LINK: %s",
715: auth->info.lnkname, auth->info.lnkname));
716: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_LINK, auth->info.lnkname) != 0) {
717: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_LINK: %s", auth->info.lnkname,
718: rad_strerror(auth->radius.handle)));
719: return (RAD_NACK);
720: }
721:
722: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT: %s",
723: auth->info.lnkname, auth->info.peer_ident));
724: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD,
725: RAD_MPD_PEER_IDENT, auth->info.peer_ident) != 0) {
726: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
727: auth->info.lnkname, rad_strerror(auth->radius.handle)));
728: return (RAD_NACK);
729: }
730:
731: #ifdef PHYSTYPE_PPTP
732: if (auth->info.phys_type == &gPptpPhysType) {
733: porttype = 1;
734: } else
735: #endif
736: #ifdef PHYSTYPE_L2TP
737: if (auth->info.phys_type == &gL2tpPhysType) {
738: porttype = 3;
739: } else
740: #endif
741: #ifdef PHYSTYPE_TCP
742: if (auth->info.phys_type == &gTcpPhysType) {
743: porttype = -1;
744: } else
745: #endif
746: #ifdef PHYSTYPE_UDP
747: if (auth->info.phys_type == &gUdpPhysType) {
748: porttype = -2;
749: } else
750: #endif
751: #ifdef PHYSTYPE_PPPOE
752: if (auth->info.phys_type == &gPppoePhysType) {
753: porttype = -3;
754: } else
755: #endif
756: {
757: porttype = 0;
758: };
759: if (porttype > 0) {
760: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_TYPE: %d",
761: auth->info.lnkname, porttype));
762: if (rad_put_int(auth->radius.handle, RAD_TUNNEL_TYPE, porttype) == -1) {
763: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_TYPE failed %s",
764: auth->info.lnkname, rad_strerror(auth->radius.handle)));
765: return (RAD_NACK);
766: }
767: }
768: if (porttype != 0) {
769: if (porttype == -3) {
770: porttype = 6;
771: } else {
772: struct in6_addr ip6;
773: if (inet_pton(AF_INET6, auth->params.peeraddr, &ip6) == 1) {
774: porttype = 2;
775: } else {
776: porttype = 1;
777: }
778: }
779: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_MEDIUM_TYPE: %d",
780: auth->info.lnkname, porttype));
781: if (rad_put_int(auth->radius.handle, RAD_TUNNEL_MEDIUM_TYPE, porttype) == -1) {
782: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_MEDIUM_TYPE failed %s",
783: auth->info.lnkname, rad_strerror(auth->radius.handle)));
784: return (RAD_NACK);
785: }
786: if (auth->info.originate == LINK_ORIGINATE_LOCAL) {
787: tmpval = auth->params.peeraddr;
788: } else {
789: tmpval = auth->params.selfaddr;
790: }
791: if (tmpval[0]) {
792: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_ENDPOINT: %s",
793: auth->info.lnkname, tmpval));
794: if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_ENDPOINT,
795: 0, tmpval) == -1) {
796: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_ENDPOINT failed %s",
797: auth->info.lnkname, rad_strerror(auth->radius.handle)));
798: return (RAD_NACK);
799: }
800: }
801: if (auth->info.originate == LINK_ORIGINATE_LOCAL) {
802: tmpval = auth->params.selfaddr;
803: } else {
804: tmpval = auth->params.peeraddr;
805: }
806: if (tmpval[0]) {
807: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_ENDPOINT: %s",
808: auth->info.lnkname, tmpval));
809: if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_ENDPOINT,
810: 0, tmpval) == -1) {
811: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_ENDPOINT failed %s",
812: auth->info.lnkname, rad_strerror(auth->radius.handle)));
813: return (RAD_NACK);
814: }
815: }
816: if (auth->info.originate == LINK_ORIGINATE_LOCAL) {
817: tmpval = auth->params.peername;
818: } else {
819: tmpval = auth->params.selfname;
820: }
821: if (tmpval[0]) {
822: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_AUTH_ID: %s",
823: auth->info.lnkname, tmpval));
824: if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_AUTH_ID,
825: 0, tmpval) == -1) {
826: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_SERVER_AUTH_ID failed %s",
827: auth->info.lnkname, rad_strerror(auth->radius.handle)));
828: return (RAD_NACK);
829: }
830: }
831: if (auth->info.originate == LINK_ORIGINATE_LOCAL) {
832: tmpval = auth->params.selfname;
833: } else {
834: tmpval = auth->params.peername;
835: }
836: if (tmpval[0]) {
837: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_AUTH_ID: %s",
838: auth->info.lnkname, tmpval));
839: if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_AUTH_ID,
840: 0, tmpval) == -1) {
841: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_TUNNEL_CLIENT_AUTH_ID failed %s",
842: auth->info.lnkname, rad_strerror(auth->radius.handle)));
843: return (RAD_NACK);
844: }
845: }
846: }
847: #ifdef PHYSTYPE_PPPOE
848: if (auth->info.phys_type == &gPppoePhysType) {
849: if (auth->params.selfname[0]) {
850: Log(LG_RADIUS2, ("[%s] RADIUS: Put ADSL-Agent-Circuit-Id: %s",
851: auth->info.lnkname, auth->params.selfname));
852: if (rad_put_vendor_string(auth->radius.handle, 3561, 1,
853: auth->params.selfname) == -1) {
854: Log(LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Circuit-Id failed %s",
855: auth->info.lnkname, rad_strerror(auth->radius.handle)));
856: return (RAD_NACK);
857: }
858: }
859: if (auth->params.peername[0]) {
860: Log(LG_RADIUS2, ("[%s] RADIUS: Put ADSL-Agent-Remote-Id: %s",
861: auth->info.lnkname, auth->params.peername));
862: if (rad_put_vendor_string(auth->radius.handle, 3561, 2,
863: auth->params.peername) == -1) {
864: Log(LG_RADIUS, ("[%s] RADIUS: Put ADSL-Agent-Remote-Id failed %s",
865: auth->info.lnkname, rad_strerror(auth->radius.handle)));
866: return (RAD_NACK);
867: }
868: }
869: }
870: #endif
871:
872: return (RAD_ACK);
873: }
874:
875: static int
876: RadiusPutAuth(AuthData auth)
877: {
878: ChapParams const cp = &auth->params.chap;
879: PapParams const pp = &auth->params.pap;
880:
881: struct rad_chapvalue rad_chapval;
882: struct rad_mschapvalue rad_mschapval;
883: struct rad_mschapv2value rad_mschapv2val;
884: struct mschapvalue *mschapval;
885: struct mschapv2value *mschapv2val;
886:
887: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s",
888: auth->info.lnkname, auth->params.authname));
889: if (rad_put_string(auth->radius.handle, RAD_USER_NAME, auth->params.authname) == -1) {
890: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME failed %s",
891: auth->info.lnkname, rad_strerror(auth->radius.handle)));
892: return (RAD_NACK);
893: }
894:
895: if (auth->proto == PROTO_CHAP || auth->proto == PROTO_EAP) {
896: switch (auth->alg) {
897:
898: case CHAP_ALG_MSOFT:
899: if (cp->value_len != 49) {
900: Log(LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv1) unrecognised key length %d/%d",
901: auth->info.lnkname, cp->value_len, 49));
902: return (RAD_NACK);
903: }
904:
905: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE",
906: auth->info.lnkname));
907: if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP_CHALLENGE,
908: cp->chal_data, cp->chal_len) == -1) {
909: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
910: auth->info.lnkname, rad_strerror(auth->radius.handle)));
911: return (RAD_NACK);
912: }
913:
914: mschapval = (struct mschapvalue *)cp->value;
915: rad_mschapval.ident = auth->id;
916: rad_mschapval.flags = 0x01;
917: memcpy(rad_mschapval.lm_response, mschapval->lmHash, 24);
918: memcpy(rad_mschapval.nt_response, mschapval->ntHash, 24);
919:
920: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_RESPONSE",
921: auth->info.lnkname));
922: if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP_RESPONSE,
923: &rad_mschapval, sizeof(rad_mschapval)) == -1) {
924: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_RESPONSE failed %s",
925: auth->info.lnkname, rad_strerror(auth->radius.handle)));
926: return (RAD_NACK);
927: }
928: break;
929:
930: case CHAP_ALG_MSOFTv2:
931: if (cp->value_len != sizeof(*mschapv2val)) {
932: Log(LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv2) unrecognised key length %d/%d",
933: auth->info.lnkname, cp->value_len, (int)sizeof(*mschapv2val)));
934: return (RAD_NACK);
935: }
936:
937: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE",
938: auth->info.lnkname));
939: if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT,
940: RAD_MICROSOFT_MS_CHAP_CHALLENGE, cp->chal_data, cp->chal_len) == -1) {
941: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed %s",
942: auth->info.lnkname, rad_strerror(auth->radius.handle)));
943: return (RAD_NACK);
944: }
945:
946: mschapv2val = (struct mschapv2value *)cp->value;
947: rad_mschapv2val.ident = auth->id;
948: rad_mschapv2val.flags = mschapv2val->flags;
949: memcpy(rad_mschapv2val.response, mschapv2val->ntHash,
950: sizeof(rad_mschapv2val.response));
951: memset(rad_mschapv2val.reserved, '\0',
952: sizeof(rad_mschapv2val.reserved));
953: memcpy(rad_mschapv2val.pchallenge, mschapv2val->peerChal,
954: sizeof(rad_mschapv2val.pchallenge));
955:
956: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MICROSOFT_MS_CHAP2_RESPONSE",
957: auth->info.lnkname));
958: if (rad_put_vendor_attr(auth->radius.handle, RAD_VENDOR_MICROSOFT, RAD_MICROSOFT_MS_CHAP2_RESPONSE,
959: &rad_mschapv2val, sizeof(rad_mschapv2val)) == -1) {
960: Log(LG_RADIUS, ("[%s] RADIUS: Put vendor_attr(RAD_MICROSOFT_MS_CHAP2_RESPONSE failed %s",
961: auth->info.lnkname, rad_strerror(auth->radius.handle)));
962: return (RAD_NACK);
963: }
964: break;
965:
966: case CHAP_ALG_MD5:
967: /* RADIUS requires the CHAP Ident in the first byte of the CHAP-Password */
968: rad_chapval.ident = auth->id;
969: memcpy(rad_chapval.response, cp->value, cp->value_len);
970: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CHAP_CHALLENGE",
971: auth->info.lnkname));
972: if (rad_put_attr(auth->radius.handle, RAD_CHAP_CHALLENGE, cp->chal_data, cp->chal_len) == -1) {
973: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_CHALLENGE failed %s",
974: auth->info.lnkname, rad_strerror(auth->radius.handle)));
975: return (RAD_NACK);
976: }
977: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CHAP_PASSWORD",
978: auth->info.lnkname));
979: if (rad_put_attr(auth->radius.handle, RAD_CHAP_PASSWORD, &rad_chapval, cp->value_len + 1) == -1) {
980: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_CHAP_PASSWORD failed %s",
981: auth->info.lnkname, rad_strerror(auth->radius.handle)));
982: return (RAD_NACK);
983: }
984: break;
985:
986: default:
987: Log(LG_RADIUS, ("[%s] RADIUS: RADIUS unkown CHAP ALG %d",
988: auth->info.lnkname, auth->alg));
989: return (RAD_NACK);
990: }
991: } else if (auth->proto == PROTO_PAP) {
992:
993: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_PASSWORD",
994: auth->info.lnkname));
995: if (rad_put_string(auth->radius.handle, RAD_USER_PASSWORD, pp->peer_pass) == -1) {
996: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_PASSWORD failed %s",
997: auth->info.lnkname, rad_strerror(auth->radius.handle)));
998: return (RAD_NACK);
999: }
1000:
1001: } else {
1002: Log(LG_RADIUS, ("[%s] RADIUS: RADIUS unkown Proto %d",
1003: auth->info.lnkname, auth->proto));
1004: return (RAD_NACK);
1005: }
1006:
1007: return (RAD_ACK);
1008:
1009: }
1010:
1011: static int
1012: RadiusPutAcct(AuthData auth)
1013: {
1014: char *username;
1015: int authentic;
1016:
1017: if (auth->acct_type == AUTH_ACCT_START) {
1018: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_START",
1019: auth->info.lnkname));
1020: if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_START)) {
1021: Log(LG_RADIUS, ("[%s] RADIUS: Put STATUS_TYPE: %s",
1022: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1023: return (RAD_NACK);
1024: }
1025: }
1026:
1027: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_IP_ADDRESS: %s",
1028: auth->info.lnkname, inet_ntoa(auth->info.peer_addr)));
1029: if (rad_put_addr(auth->radius.handle, RAD_FRAMED_IP_ADDRESS, auth->info.peer_addr)) {
1030: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_ADDRESS: %s",
1031: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1032: return (RAD_NACK);
1033: }
1034:
1035: if (auth->params.netmask != 0) {
1036: struct in_addr ip;
1037: widthtoin_addr(auth->params.netmask, &ip);
1038: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_FRAMED_IP_NETMASK: %s",
1039: auth->info.lnkname, inet_ntoa(ip)));
1040: if (rad_put_addr(auth->radius.handle, RAD_FRAMED_IP_NETMASK, ip)) {
1041: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_FRAMED_IP_NETMASK: %s",
1042: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1043: return (RAD_NACK);
1044: }
1045: }
1046:
1047: username = auth->params.authname;
1048: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_NAME: %s",
1049: auth->info.lnkname, username));
1050: if (rad_put_string(auth->radius.handle, RAD_USER_NAME, username) != 0) {
1051: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_USER_NAME: %s",
1052: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1053: return (RAD_NACK);
1054: }
1055:
1056: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_MULTI_SESSION_ID: %s",
1057: auth->info.lnkname, auth->info.msession_id));
1058: if (rad_put_string(auth->radius.handle, RAD_ACCT_MULTI_SESSION_ID, auth->info.msession_id) != 0) {
1059: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_MULTI_SESSION_ID: %s",
1060: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1061: return (RAD_NACK);
1062: }
1063:
1064: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_BUNDLE: %s",
1065: auth->info.lnkname, auth->info.bundname));
1066: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_BUNDLE, auth->info.bundname) != 0) {
1067: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_BUNDLE: %s", auth->info.lnkname,
1068: rad_strerror(auth->radius.handle)));
1069: return (RAD_NACK);
1070: }
1071:
1072: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_IFACE: %s",
1073: auth->info.lnkname, auth->info.ifname));
1074: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_IFACE, auth->info.ifname) != 0) {
1075: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE: %s", auth->info.lnkname,
1076: rad_strerror(auth->radius.handle)));
1077: return (RAD_NACK);
1078: }
1079:
1080: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %u",
1081: auth->info.lnkname, auth->info.ifindex));
1082: if (rad_put_vendor_int(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_IFACE_INDEX, auth->info.ifindex) != 0) {
1083: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %s", auth->info.lnkname,
1084: rad_strerror(auth->radius.handle)));
1085: return (RAD_NACK);
1086: }
1087:
1088: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT: %s",
1089: auth->info.lnkname, auth->info.peer_ident));
1090: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_PEER_IDENT, auth->info.peer_ident) != 0) {
1091: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_PEER_IDENT failed %s",
1092: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1093: return (RAD_NACK);
1094: }
1095:
1096: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_LINK_COUNT: %d",
1097: auth->info.lnkname, auth->info.n_links));
1098: if (rad_put_int(auth->radius.handle, RAD_ACCT_LINK_COUNT, auth->info.n_links) != 0) {
1099: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_LINK_COUNT failed: %s",
1100: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1101: return (RAD_NACK);
1102: }
1103:
1104: if (auth->params.authentic == AUTH_CONF_RADIUS_AUTH) {
1105: authentic = RAD_AUTH_RADIUS;
1106: } else {
1107: authentic = RAD_AUTH_LOCAL;
1108: }
1109: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_AUTHENTIC: %d",
1110: auth->info.lnkname, authentic));
1111: if (rad_put_int(auth->radius.handle, RAD_ACCT_AUTHENTIC, authentic) != 0) {
1112: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_AUTHENTIC failed: %s",
1113: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1114: return (RAD_NACK);
1115: }
1116:
1117: if (auth->acct_type == AUTH_ACCT_STOP
1118: || auth->acct_type == AUTH_ACCT_UPDATE) {
1119: #ifdef USE_NG_BPF
1120: struct svcstatrec *ssr;
1121: #endif
1122:
1123: if (auth->acct_type == AUTH_ACCT_STOP) {
1124: int termCause = RAD_TERM_PORT_ERROR;
1125:
1126: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_STOP",
1127: auth->info.lnkname));
1128: if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_STOP)) {
1129: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s",
1130: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1131: return (RAD_NACK);
1132: }
1133:
1134: if ((auth->info.downReason == NULL) || (!strcmp(auth->info.downReason, ""))) {
1135: termCause = RAD_TERM_NAS_REQUEST;
1136: } else if (!strncmp(auth->info.downReason, STR_MANUALLY, strlen(STR_MANUALLY))) {
1137: termCause = RAD_TERM_ADMIN_RESET;
1138: } else if (!strncmp(auth->info.downReason, STR_PEER_DISC, strlen(STR_PEER_DISC))) {
1139: termCause = RAD_TERM_USER_REQUEST;
1140: } else if (!strncmp(auth->info.downReason, STR_ADMIN_SHUTDOWN, strlen(STR_ADMIN_SHUTDOWN))) {
1141: termCause = RAD_TERM_ADMIN_REBOOT;
1142: } else if (!strncmp(auth->info.downReason, STR_FATAL_SHUTDOWN, strlen(STR_FATAL_SHUTDOWN))) {
1143: termCause = RAD_TERM_NAS_REBOOT;
1144: } else if (!strncmp(auth->info.downReason, STR_IDLE_TIMEOUT, strlen(STR_IDLE_TIMEOUT))) {
1145: termCause = RAD_TERM_IDLE_TIMEOUT;
1146: } else if (!strncmp(auth->info.downReason, STR_SESSION_TIMEOUT, strlen(STR_SESSION_TIMEOUT))) {
1147: termCause = RAD_TERM_SESSION_TIMEOUT;
1148: } else if (!strncmp(auth->info.downReason, STR_DROPPED, strlen(STR_DROPPED))) {
1149: termCause = RAD_TERM_LOST_CARRIER;
1150: } else if (!strncmp(auth->info.downReason, STR_ECHO_TIMEOUT, strlen(STR_ECHO_TIMEOUT))) {
1151: termCause = RAD_TERM_LOST_SERVICE;
1152: } else if (!strncmp(auth->info.downReason, STR_PROTO_ERR, strlen(STR_PROTO_ERR))) {
1153: termCause = RAD_TERM_SERVICE_UNAVAILABLE;
1154: } else if (!strncmp(auth->info.downReason, STR_LOGIN_FAIL, strlen(STR_LOGIN_FAIL))) {
1155: termCause = RAD_TERM_USER_ERROR;
1156: } else if (!strncmp(auth->info.downReason, STR_PORT_UNNEEDED, strlen(STR_PORT_UNNEEDED))) {
1157: termCause = RAD_TERM_PORT_UNNEEDED;
1158: };
1159: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_TERMINATE_CAUSE: %s, RADIUS: %d",
1160: auth->info.lnkname, auth->info.downReason, termCause));
1161:
1162: if (rad_put_int(auth->radius.handle, RAD_ACCT_TERMINATE_CAUSE, termCause) != 0) {
1163: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_TERMINATE_CAUSE failed: %s",
1164: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1165: return (RAD_NACK);
1166: }
1167: } else {
1168: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_UPDATE",
1169: auth->info.lnkname));
1170: if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_UPDATE)) {
1171: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: %s",
1172: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1173: return (RAD_NACK);
1174: }
1175: }
1176:
1177: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_SESSION_TIME: %ld",
1178: auth->info.lnkname, (long int)(time(NULL) - auth->info.last_up)));
1179: if (rad_put_int(auth->radius.handle, RAD_ACCT_SESSION_TIME, time(NULL) - auth->info.last_up) != 0) {
1180: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_ACCT_SESSION_TIME failed: %s",
1181: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1182: return (RAD_NACK);
1183: }
1184:
1185: #ifdef USE_NG_BPF
1186: if (auth->params.std_acct[0][0] == 0) {
1187: #endif
1188: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_OCTETS: %lu",
1189: auth->info.lnkname, (long unsigned int)(auth->info.stats.recvOctets % MAX_U_INT32)));
1190: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_GIGAWORDS: %lu",
1191: auth->info.lnkname, (long unsigned int)(auth->info.stats.recvOctets / MAX_U_INT32)));
1192: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_PACKETS: %lu",
1193: auth->info.lnkname, (long unsigned int)(auth->info.stats.recvFrames)));
1194: if (rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_OCTETS, auth->info.stats.recvOctets % MAX_U_INT32) != 0 ||
1195: rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_PACKETS, auth->info.stats.recvFrames) != 0 ||
1196: rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_GIGAWORDS, auth->info.stats.recvOctets / MAX_U_INT32) != 0) {
1197: Log(LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
1198: rad_strerror(auth->radius.handle)));
1199: return (RAD_NACK);
1200: }
1201: #ifdef USE_NG_BPF
1202: }
1203: if (auth->params.std_acct[1][0] == 0) {
1204: #endif
1205: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_OCTETS: %lu",
1206: auth->info.lnkname, (long unsigned int)(auth->info.stats.xmitOctets % MAX_U_INT32)));
1207: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_GIGAWORDS: %lu",
1208: auth->info.lnkname, (long unsigned int)(auth->info.stats.xmitOctets / MAX_U_INT32)));
1209: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_PACKETS: %lu",
1210: auth->info.lnkname, (long unsigned int)(auth->info.stats.xmitFrames)));
1211: if (rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_OCTETS, auth->info.stats.xmitOctets % MAX_U_INT32) != 0 ||
1212: rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_PACKETS, auth->info.stats.xmitFrames) != 0 ||
1213: rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_GIGAWORDS, auth->info.stats.xmitOctets / MAX_U_INT32) != 0) {
1214: Log(LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
1215: rad_strerror(auth->radius.handle)));
1216: return (RAD_NACK);
1217: }
1218: #ifdef USE_NG_BPF
1219: }
1220: SLIST_FOREACH(ssr, &auth->info.ss.stat[0], next) {
1221: char str[64];
1222: snprintf(str, sizeof(str), "%s:%llu",
1223: ssr->name, (long long unsigned)ssr->Octets);
1224: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_INPUT_OCTETS: %s",
1225: auth->info.lnkname, str));
1226: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_OCTETS, str) != 0) {
1227: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_OCTETS: %s", auth->info.lnkname,
1228: rad_strerror(auth->radius.handle)));
1229: }
1230: snprintf(str, sizeof(str), "%s:%llu",
1231: ssr->name, (long long unsigned)ssr->Packets);
1232: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_INPUT_PACKETS: %s",
1233: auth->info.lnkname, str));
1234: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_PACKETS, str) != 0) {
1235: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_INPUT_PACKETS: %s", auth->info.lnkname,
1236: rad_strerror(auth->radius.handle)));
1237: }
1238: if (strcmp(ssr->name,auth->params.std_acct[0]) == 0) {
1239: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_OCTETS: %lu",
1240: auth->info.lnkname, (long unsigned int)(ssr->Octets % MAX_U_INT32)));
1241: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_GIGAWORDS: %lu",
1242: auth->info.lnkname, (long unsigned int)(ssr->Octets / MAX_U_INT32)));
1243: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_PACKETS: %lu",
1244: auth->info.lnkname, (long unsigned int)(ssr->Packets)));
1245: if (rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_OCTETS, ssr->Octets % MAX_U_INT32) != 0 ||
1246: rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_PACKETS, ssr->Packets) != 0 ||
1247: rad_put_int(auth->radius.handle, RAD_ACCT_INPUT_GIGAWORDS, ssr->Octets / MAX_U_INT32) != 0) {
1248: Log(LG_RADIUS, ("[%s] RADIUS: Put input stats: %s", auth->info.lnkname,
1249: rad_strerror(auth->radius.handle)));
1250: return (RAD_NACK);
1251: }
1252: }
1253: }
1254: SLIST_FOREACH(ssr, &auth->info.ss.stat[1], next) {
1255: char str[64];
1256: snprintf(str, sizeof(str), "%s:%llu",
1257: ssr->name, (long long unsigned)ssr->Octets);
1258: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_OCTETS: %s",
1259: auth->info.lnkname, str));
1260: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_OCTETS, str) != 0) {
1261: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_OCTETS: %s", auth->info.lnkname,
1262: rad_strerror(auth->radius.handle)));
1263: }
1264: snprintf(str, sizeof(str), "%s:%llu",
1265: ssr->name, (long long unsigned)ssr->Packets);
1266: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_PACKETS: %s",
1267: auth->info.lnkname, str));
1268: if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_PACKETS, str) != 0) {
1269: Log(LG_RADIUS, ("[%s] RADIUS: Put RAD_MPD_OUTPUT_PACKETS: %s", auth->info.lnkname,
1270: rad_strerror(auth->radius.handle)));
1271: }
1272: if (strcmp(ssr->name,auth->params.std_acct[1]) == 0) {
1273: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_OCTETS: %lu",
1274: auth->info.lnkname, (long unsigned int)(ssr->Octets % MAX_U_INT32)));
1275: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_GIGAWORDS: %lu",
1276: auth->info.lnkname, (long unsigned int)(ssr->Octets / MAX_U_INT32)));
1277: Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_PACKETS: %lu",
1278: auth->info.lnkname, (long unsigned int)(ssr->Packets)));
1279: if (rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_OCTETS, ssr->Octets % MAX_U_INT32) != 0 ||
1280: rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_PACKETS, ssr->Packets) != 0 ||
1281: rad_put_int(auth->radius.handle, RAD_ACCT_OUTPUT_GIGAWORDS, ssr->Octets / MAX_U_INT32) != 0) {
1282: Log(LG_RADIUS, ("[%s] RADIUS: Put output stats: %s", auth->info.lnkname,
1283: rad_strerror(auth->radius.handle)));
1284: return (RAD_NACK);
1285: }
1286: }
1287: }
1288: #endif /* USE_NG_BPF */
1289:
1290: }
1291: return (RAD_ACK);
1292: }
1293:
1294: static int
1295: RadiusSendRequest(AuthData auth)
1296: {
1297: struct timeval timelimit;
1298: struct timeval tv;
1299: int fd, n;
1300:
1301: Log(LG_RADIUS2, ("[%s] RADIUS: Send request for user '%s'",
1302: auth->info.lnkname, auth->params.authname));
1303: n = rad_init_send_request(auth->radius.handle, &fd, &tv);
1304: if (n != 0) {
1305: Log(LG_RADIUS, ("[%s] RADIUS: rad_init_send_request failed: %d %s",
1306: auth->info.lnkname, n, rad_strerror(auth->radius.handle)));
1307: return (RAD_NACK);
1308: }
1309:
1310: gettimeofday(&timelimit, NULL);
1311: timeradd(&tv, &timelimit, &timelimit);
1312:
1313: for ( ; ; ) {
1314: struct pollfd fds[1];
1315:
1316: fds[0].fd = fd;
1317: fds[0].events = POLLIN;
1318: fds[0].revents = 0;
1319:
1320: n = poll(fds,1,tv.tv_sec*1000+tv.tv_usec/1000);
1321:
1322: if (n == -1) {
1323: Log(LG_RADIUS, ("[%s] RADIUS: poll failed %s", auth->info.lnkname,
1324: strerror(errno)));
1325: return (RAD_NACK);
1326: }
1327:
1328: if ((fds[0].revents&POLLIN)!=POLLIN) {
1329: /* Compute a new timeout */
1330: gettimeofday(&tv, NULL);
1331: timersub(&timelimit, &tv, &tv);
1332: if (tv.tv_sec > 0 || (tv.tv_sec == 0 && tv.tv_usec > 0))
1333: continue; /* Continue the select */
1334: }
1335:
1336: Log(LG_RADIUS2, ("[%s] RADIUS: Sending request for user '%s'",
1337: auth->info.lnkname, auth->params.authname));
1338: n = rad_continue_send_request(auth->radius.handle, n, &fd, &tv);
1339: if (n != 0)
1340: break;
1341:
1342: gettimeofday(&timelimit, NULL);
1343: timeradd(&tv, &timelimit, &timelimit);
1344: }
1345:
1346: switch (n) {
1347:
1348: case RAD_ACCESS_ACCEPT:
1349: Log(LG_RADIUS, ("[%s] RADIUS: Rec'd RAD_ACCESS_ACCEPT for user '%s'",
1350: auth->info.lnkname, auth->params.authname));
1351: auth->status = AUTH_STATUS_SUCCESS;
1352: break;
1353:
1354: case RAD_ACCESS_CHALLENGE:
1355: Log(LG_RADIUS, ("[%s] RADIUS: Rec'd RAD_ACCESS_CHALLENGE for user '%s'",
1356: auth->info.lnkname, auth->params.authname));
1357: break;
1358:
1359: case RAD_ACCESS_REJECT:
1360: Log(LG_RADIUS, ("[%s] RADIUS: Rec'd RAD_ACCESS_REJECT for user '%s'",
1361: auth->info.lnkname, auth->params.authname));
1362: auth->status = AUTH_STATUS_FAIL;
1363: break;
1364:
1365: case RAD_ACCOUNTING_RESPONSE:
1366: Log(auth->acct_type != AUTH_ACCT_UPDATE ? LG_RADIUS : LG_RADIUS2,
1367: ("[%s] RADIUS: Rec'd RAD_ACCOUNTING_RESPONSE for user '%s'",
1368: auth->info.lnkname, auth->params.authname));
1369: break;
1370:
1371: case -1:
1372: Log(LG_RADIUS, ("[%s] RADIUS: rad_send_request for user '%s' failed: %s",
1373: auth->info.lnkname, auth->params.authname,
1374: rad_strerror(auth->radius.handle)));
1375: return (RAD_NACK);
1376:
1377: default:
1378: Log(LG_RADIUS, ("[%s] RADIUS: rad_send_request: unexpected return value: %d",
1379: auth->info.lnkname, n));
1380: return (RAD_NACK);
1381: }
1382:
1383: return (RadiusGetParams(auth, n == RAD_ACCESS_CHALLENGE));
1384: }
1385:
1386: static int
1387: RadiusGetParams(AuthData auth, int eap_proxy)
1388: {
1389: int res, i, j;
1390: size_t len;
1391: const void *data;
1392: u_int32_t vendor;
1393: char *route;
1394: char *tmpval;
1395: struct in_addr ip;
1396: #if defined(USE_NG_BPF) || defined(USE_IPFW)
1397: struct acl **acls, *acls1;
1398: char *acl, *acl1, *acl2, *acl3;
1399: #endif
1400: struct ifaceroute *r, *r1;
1401: struct u_range range;
1402: #ifdef CCP_MPPC
1403: u_char *tmpkey;
1404: size_t tmpkey_len;
1405: #endif
1406:
1407: Freee(auth->params.eapmsg);
1408: auth->params.eapmsg = NULL;
1409:
1410: while ((res = rad_get_attr(auth->radius.handle, &data, &len)) > 0) {
1411:
1412: switch (res) {
1413:
1414: case RAD_STATE:
1415: tmpval = Bin2Hex(data, len);
1416: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_STATE: 0x%s", auth->info.lnkname, tmpval));
1417: Freee(tmpval);
1418: auth->params.state_len = len;
1419: Freee(auth->params.state);
1420: auth->params.state = Mdup(MB_AUTH, data, len);
1421: continue;
1422:
1423: case RAD_CLASS:
1424: tmpval = Bin2Hex(data, len);
1425: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_CLASS: 0x%s", auth->info.lnkname, tmpval));
1426: Freee(tmpval);
1427: auth->params.class_len = len;
1428: Freee(auth->params.class);
1429: auth->params.class = Mdup(MB_AUTH, data, len);
1430: continue;
1431:
1432: /* libradius already checks the message-authenticator, so simply ignore it */
1433: case RAD_MESSAGE_AUTHENTIC:
1434: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MESSAGE_AUTHENTIC", auth->info.lnkname));
1435: continue;
1436:
1437: case RAD_EAP_MESSAGE:
1438: if (auth->params.eapmsg != NULL) {
1439: char *tbuf;
1440: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_EAP_MESSAGE: len %d of %d",
1441: auth->info.lnkname, (int)len, (int)(auth->params.eapmsg_len + len)));
1442: tbuf = Malloc(MB_AUTH, auth->params.eapmsg_len + len);
1443: memcpy(tbuf, auth->params.eapmsg, auth->params.eapmsg_len);
1444: memcpy(&tbuf[auth->params.eapmsg_len], data, len);
1445: auth->params.eapmsg_len += len;
1446: Freee(auth->params.eapmsg);
1447: auth->params.eapmsg = tbuf;
1448: } else {
1449: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_EAP_MESSAGE: len %d",
1450: auth->info.lnkname, (int)len));
1451: auth->params.eapmsg = Mdup(MB_AUTH, data, len);
1452: auth->params.eapmsg_len = len;
1453: }
1454: continue;
1455: }
1456:
1457: if (!eap_proxy)
1458: switch (res) {
1459:
1460: case RAD_FRAMED_IP_ADDRESS:
1461: ip = rad_cvt_addr(data);
1.1.1.2 ! misho 1462: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IP_ADDRESS: %s",
1.1 misho 1463: auth->info.lnkname, inet_ntoa(ip)));
1.1.1.2 ! misho 1464:
1.1 misho 1465: if (strcmp(inet_ntoa(ip), "255.255.255.255") == 0) {
1466: /* the peer can choose an address */
1467: Log(LG_RADIUS2, ("[%s] the peer can choose an address", auth->info.lnkname));
1468: ip.s_addr=0;
1469: in_addrtou_range(&ip, 0, &auth->params.range);
1470: auth->params.range_valid = 1;
1471: } else if (strcmp(inet_ntoa(ip), "255.255.255.254") == 0) {
1472: /* we should choose the ip */
1473: Log(LG_RADIUS2, ("[%s] we should choose an address", auth->info.lnkname));
1474: auth->params.range_valid = 0;
1475: } else {
1476: /* or use IP from Radius-server */
1477: in_addrtou_range(&ip, 32, &auth->params.range);
1478: auth->params.range_valid = 1;
1479: }
1480: break;
1481:
1482: case RAD_USER_NAME:
1483: tmpval = rad_cvt_string(data, len);
1484: /* copy it into the persistent data struct */
1485: strlcpy(auth->params.authname, tmpval, sizeof(auth->params.authname));
1486: free(tmpval);
1.1.1.2 ! misho 1487: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_USER_NAME: %s",
1.1 misho 1488: auth->info.lnkname, auth->params.authname));
1489: break;
1490:
1491: case RAD_FRAMED_IP_NETMASK:
1492: ip = rad_cvt_addr(data);
1493: auth->params.netmask = in_addrtowidth(&ip);
1.1.1.2 ! misho 1494: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IP_NETMASK: %s (/%d)",
1.1 misho 1495: auth->info.lnkname, inet_ntoa(ip), auth->params.netmask));
1496: break;
1497:
1498: case RAD_FRAMED_ROUTE:
1499: route = rad_cvt_string(data, len);
1.1.1.2 ! misho 1500: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: %s",
1.1 misho 1501: auth->info.lnkname, route));
1502: if (!ParseRange(route, &range, ALLOW_IPV4)) {
1503: Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: Bad route \"%s\"",
1504: auth->info.lnkname, route));
1505: free(route);
1506: break;
1507: }
1508: r = Malloc(MB_AUTH, sizeof(struct ifaceroute));
1509: r->dest = range;
1510: r->ok = 0;
1511: j = 0;
1512: SLIST_FOREACH(r1, &auth->params.routes, next) {
1513: if (!u_rangecompare(&r->dest, &r1->dest)) {
1514: Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
1515: auth->info.lnkname, route));
1516: j = 1;
1517: }
1518: };
1519: free(route);
1520: if (j == 0) {
1521: SLIST_INSERT_HEAD(&auth->params.routes, r, next);
1522: } else {
1523: Freee(r);
1524: }
1525: break;
1526:
1527: case RAD_FRAMED_IPV6_ROUTE:
1528: route = rad_cvt_string(data, len);
1.1.1.2 ! misho 1529: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: %s",
1.1 misho 1530: auth->info.lnkname, route));
1531: if (!ParseRange(route, &range, ALLOW_IPV6)) {
1532: Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: Bad route \"%s\"", auth->info.lnkname, route));
1533: free(route);
1534: break;
1535: }
1536: r = Malloc(MB_AUTH, sizeof(struct ifaceroute));
1537: r->dest = range;
1538: r->ok = 0;
1539: j = 0;
1540: SLIST_FOREACH(r1, &auth->params.routes, next) {
1541: if (!u_rangecompare(&r->dest, &r1->dest)) {
1542: Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
1543: auth->info.lnkname, route));
1544: j = 1;
1545: }
1546: };
1547: free(route);
1548: if (j == 0) {
1549: SLIST_INSERT_HEAD(&auth->params.routes, r, next);
1550: } else {
1551: Freee(r);
1552: }
1553: break;
1554:
1555: case RAD_SESSION_TIMEOUT:
1556: auth->params.session_timeout = rad_cvt_int(data);
1.1.1.2 ! misho 1557: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_SESSION_TIMEOUT: %u",
1.1 misho 1558: auth->info.lnkname, auth->params.session_timeout));
1559: break;
1560:
1561: case RAD_IDLE_TIMEOUT:
1562: auth->params.idle_timeout = rad_cvt_int(data);
1.1.1.2 ! misho 1563: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_IDLE_TIMEOUT: %u",
1.1 misho 1564: auth->info.lnkname, auth->params.idle_timeout));
1565: break;
1566:
1567: case RAD_ACCT_INTERIM_INTERVAL:
1568: auth->params.acct_update = rad_cvt_int(data);
1.1.1.2 ! misho 1569: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_ACCT_INTERIM_INTERVAL: %u",
1.1 misho 1570: auth->info.lnkname, auth->params.acct_update));
1571: break;
1572:
1573: case RAD_FRAMED_MTU:
1574: i = rad_cvt_int(data);
1.1.1.2 ! misho 1575: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_MTU: %u",
1.1 misho 1576: auth->info.lnkname, i));
1577: if (i < IFACE_MIN_MTU || i > IFACE_MAX_MTU) {
1.1.1.2 ! misho 1578: Log(LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_MTU: invalid MTU: %u",
1.1 misho 1579: auth->info.lnkname, i));
1580: auth->params.mtu = 0;
1581: break;
1582: }
1583: auth->params.mtu = i;
1584: break;
1585:
1586: case RAD_FRAMED_COMPRESSION:
1587: i = rad_cvt_int(data);
1588: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_COMPRESSION: %d",
1589: auth->info.lnkname, i));
1590: if (i == RAD_COMP_VJ)
1591: auth->params.vjc_enable = 1;
1592: break;
1593:
1594: case RAD_FRAMED_PROTOCOL:
1595: Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_FRAMED_PROTOCOL: %d)",
1596: auth->info.lnkname, rad_cvt_int(data)));
1597: break;
1598:
1599: case RAD_FRAMED_ROUTING:
1600: Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_FRAMED_ROUTING: %d)",
1601: auth->info.lnkname, rad_cvt_int(data)));
1602: break;
1603:
1604: case RAD_FILTER_ID:
1605: tmpval = rad_cvt_string(data, len);
1606: Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_FILTER_ID: %s)",
1607: auth->info.lnkname, tmpval));
1608: free(tmpval);
1609: break;
1610:
1611: case RAD_SERVICE_TYPE:
1612: Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_SERVICE_TYPE: %d)",
1613: auth->info.lnkname, rad_cvt_int(data)));
1614: break;
1615:
1616: case RAD_REPLY_MESSAGE:
1.1.1.2 ! misho 1617: Freee(auth->reply_message);
! 1618: auth->reply_message = NULL;
! 1619: if (len == 0)
! 1620: break;
1.1 misho 1621: tmpval = rad_cvt_string(data, len);
1622: auth->reply_message = Mdup(MB_AUTH, tmpval, len + 1);
1623: free(tmpval);
1.1.1.2 ! misho 1624: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_REPLY_MESSAGE: %s",
! 1625: auth->info.lnkname, auth->reply_message));
1.1 misho 1626: break;
1627:
1628: case RAD_FRAMED_POOL:
1629: tmpval = rad_cvt_string(data, len);
1630: /* copy it into the persistent data struct */
1631: strlcpy(auth->params.ippool, tmpval, sizeof(auth->params.ippool));
1632: free(tmpval);
1.1.1.2 ! misho 1633: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_POOL: %s",
1.1 misho 1634: auth->info.lnkname, auth->params.ippool));
1635: break;
1636:
1637: case RAD_VENDOR_SPECIFIC:
1638: if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
1.1.1.2 ! misho 1639: Log(LG_RADIUS, ("[%s] RADIUS: Get vendor attr failed: %s",
1.1 misho 1640: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1641: return RAD_NACK;
1642: }
1643:
1644: switch (vendor) {
1645:
1646: case RAD_VENDOR_MICROSOFT:
1647: switch (res) {
1648:
1649: case RAD_MICROSOFT_MS_CHAP_ERROR:
1650: Freee(auth->mschap_error);
1651: auth->mschap_error = NULL;
1652: if (len == 0)
1653: break;
1654:
1655: /* there is a nullbyte on the first pos, don't know why */
1656: if (((const char *)data)[0] == '\0') {
1657: data = (const char *)data + 1;
1658: len--;
1659: }
1660: tmpval = rad_cvt_string(data, len);
1661: auth->mschap_error = Mdup(MB_AUTH, tmpval, len + 1);
1662: free(tmpval);
1663:
1664: Log(LG_RADIUS2, ("[%s] RADIUS: Get MS-CHAP-Error: %s",
1665: auth->info.lnkname, auth->mschap_error));
1666: break;
1667:
1668: /* this was taken from userland ppp */
1669: case RAD_MICROSOFT_MS_CHAP2_SUCCESS:
1670: Freee(auth->mschapv2resp);
1671: auth->mschapv2resp = NULL;
1672: if (len == 0)
1673: break;
1674: if (len < 3 || ((const char *)data)[1] != '=') {
1675: /*
1676: * Only point at the String field if we don't think the
1677: * peer has misformatted the response.
1678: */
1679: data = (const char *)data + 1;
1680: len--;
1681: } else {
1682: Log(LG_RADIUS, ("[%s] RADIUS: Warning: The MS-CHAP2-Success attribute is mis-formatted. Compensating",
1683: auth->info.lnkname));
1684: }
1685: if ((tmpval = rad_cvt_string((const char *)data, len)) == NULL) {
1686: Log(LG_RADIUS, ("[%s] RADIUS: rad_cvt_string failed: %s",
1687: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1688: return RAD_NACK;
1689: }
1690: auth->mschapv2resp = Mdup(MB_AUTH, tmpval, len + 1);
1691: free(tmpval);
1692: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_CHAP2_SUCCESS: %s",
1693: auth->info.lnkname, auth->mschapv2resp));
1694: break;
1695:
1696: case RAD_MICROSOFT_MS_CHAP_DOMAIN:
1697: Freee(auth->params.msdomain);
1.1.1.2 ! misho 1698: auth->params.msdomain = NULL;
! 1699: if (len == 0)
! 1700: break;
1.1 misho 1701: tmpval = rad_cvt_string(data, len);
1702: auth->params.msdomain = Mdup(MB_AUTH, tmpval, len + 1);
1703: free(tmpval);
1704: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_CHAP_DOMAIN: %s",
1705: auth->info.lnkname, auth->params.msdomain));
1706: break;
1707:
1708: #ifdef CCP_MPPC
1709: /* MPPE Keys MS-CHAPv2 and EAP-TLS */
1710: case RAD_MICROSOFT_MS_MPPE_RECV_KEY:
1711: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_MPPE_RECV_KEY",
1712: auth->info.lnkname));
1713: tmpkey = rad_demangle_mppe_key(auth->radius.handle, data, len, &tmpkey_len);
1714: if (!tmpkey) {
1715: Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
1716: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1717: return RAD_NACK;
1718: }
1719:
1720: memcpy(auth->params.msoft.recv_key, tmpkey, MPPE_KEY_LEN);
1721: free(tmpkey);
1722: auth->params.msoft.has_keys = TRUE;
1723: break;
1724:
1725: case RAD_MICROSOFT_MS_MPPE_SEND_KEY:
1726: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_MPPE_SEND_KEY",
1727: auth->info.lnkname));
1728: tmpkey = rad_demangle_mppe_key(auth->radius.handle, data, len, &tmpkey_len);
1729: if (!tmpkey) {
1730: Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle_mppe_key failed: %s",
1731: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1732: return RAD_NACK;
1733: }
1734: memcpy(auth->params.msoft.xmit_key, tmpkey, MPPE_KEY_LEN);
1735: free(tmpkey);
1736: auth->params.msoft.has_keys = TRUE;
1737: break;
1738:
1739: /* MPPE Keys MS-CHAPv1 */
1740: case RAD_MICROSOFT_MS_CHAP_MPPE_KEYS:
1741: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_CHAP_MPPE_KEYS",
1742: auth->info.lnkname));
1743:
1744: if (len != 32) {
1745: Log(LG_RADIUS, ("[%s] RADIUS: Server returned garbage %d of expected %d Bytes",
1746: auth->info.lnkname, (int)len, 32));
1747: return RAD_NACK;
1748: }
1749:
1750: tmpkey = rad_demangle(auth->radius.handle, data, len);
1751: if (tmpkey == NULL) {
1752: Log(LG_RADIUS, ("[%s] RADIUS: rad_demangle failed: %s",
1753: auth->info.lnkname, rad_strerror(auth->radius.handle)));
1754: return RAD_NACK;
1755: }
1756: memcpy(auth->params.msoft.lm_hash, tmpkey, sizeof(auth->params.msoft.lm_hash));
1757: auth->params.msoft.has_lm_hash = TRUE;
1758: memcpy(auth->params.msoft.nt_hash_hash, &tmpkey[8], sizeof(auth->params.msoft.nt_hash_hash));
1759: auth->params.msoft.has_nt_hash = TRUE;
1760: free(tmpkey);
1761: break;
1762: #endif
1763:
1764: case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
1765: auth->params.msoft.policy = rad_cvt_int(data);
1766: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY: %d (%s)",
1767: auth->info.lnkname, auth->params.msoft.policy, AuthMPPEPolicyname(auth->params.msoft.policy)));
1768: break;
1769:
1770: case RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
1771: {
1.1.1.2 ! misho 1772: char buf[48];
1.1 misho 1773: auth->params.msoft.types = rad_cvt_int(data);
1774: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES: %d (%s)",
1775: auth->info.lnkname, auth->params.msoft.types,
1776: AuthMPPETypesname(auth->params.msoft.types, buf, sizeof(buf))));
1777: }
1778: break;
1779:
1780: case RAD_MICROSOFT_MS_PRIMARY_DNS_SERVER:
1781: auth->params.peer_dns[0] = rad_cvt_addr(data);
1782: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_PRIMARY_DNS_SERVER: %s",
1783: auth->info.lnkname, inet_ntoa(auth->params.peer_dns[0])));
1784: break;
1785:
1786: case RAD_MICROSOFT_MS_SECONDARY_DNS_SERVER:
1787: auth->params.peer_dns[1] = rad_cvt_addr(data);
1788: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_SECONDARY_DNS_SERVER: %s",
1789: auth->info.lnkname, inet_ntoa(auth->params.peer_dns[1])));
1790: break;
1791:
1792: case RAD_MICROSOFT_MS_PRIMARY_NBNS_SERVER:
1793: auth->params.peer_nbns[0] = rad_cvt_addr(data);
1794: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_PRIMARY_NBNS_SERVER: %s",
1795: auth->info.lnkname, inet_ntoa(auth->params.peer_nbns[0])));
1796: break;
1797:
1798: case RAD_MICROSOFT_MS_SECONDARY_NBNS_SERVER:
1799: auth->params.peer_nbns[1] = rad_cvt_addr(data);
1800: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MICROSOFT_MS_SECONDARY_NBNS_SERVER: %s",
1801: auth->info.lnkname, inet_ntoa(auth->params.peer_nbns[1])));
1802: break;
1803:
1804: default:
1.1.1.2 ! misho 1805: Log(LG_RADIUS2, ("[%s] RADIUS: Dropping MICROSOFT vendor specific attribute: %d",
1.1 misho 1806: auth->info.lnkname, res));
1807: break;
1808: }
1809: break;
1810:
1811: case RAD_VENDOR_MPD:
1812:
1813: if (res == RAD_MPD_DROP_USER) {
1814: auth->drop_user = rad_cvt_int(data);
1815: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_DROP_USER: %d",
1816: auth->info.lnkname, auth->drop_user));
1817: break;
1818: } else if (res == RAD_MPD_ACTION) {
1819: tmpval = rad_cvt_string(data, len);
1820: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_ACTION: %s",
1821: auth->info.lnkname, tmpval));
1822: strlcpy(auth->params.action, tmpval,
1823: sizeof(auth->params.action));
1824: free(tmpval);
1825: break;
1826: } else if (res == RAD_MPD_IFACE_NAME) {
1827: tmpval = rad_cvt_string(data, len);
1828: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_IFACE_NAME: %s",
1829: auth->info.lnkname, tmpval));
1830: strlcpy(auth->params.ifname, tmpval,
1831: sizeof(auth->params.ifname));
1832: free(tmpval);
1833: break;
1834: } else
1835: #ifdef SIOCSIFDESCR
1836: if (res == RAD_MPD_IFACE_DESCR) {
1837: tmpval = rad_cvt_string(data, len);
1838: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_IFACE_DESCR: %s",
1839: auth->info.lnkname, tmpval));
1840: Freee(auth->params.ifdescr);
1841: auth->params.ifdescr = Mdup(MB_AUTH, tmpval, len + 1);
1842: free(tmpval);
1843: break;
1844: } else
1845: #endif /* SIOCSIFDESCR */
1846: #ifdef SIOCAIFGROUP
1847: if (res == RAD_MPD_IFACE_GROUP) {
1848: tmpval = rad_cvt_string(data, len);
1849: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_IFACE_GROUP: %s",
1850: auth->info.lnkname, tmpval));
1851: strlcpy(auth->params.ifgroup, tmpval,
1852: sizeof(auth->params.ifgroup));
1853: free(tmpval);
1854: break;
1855: } else
1856: #endif /* SIOCAIFGROUP */
1857: #ifdef USE_IPFW
1858: if (res == RAD_MPD_RULE) {
1859: acl1 = acl = rad_cvt_string(data, len);
1860: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_RULE: %s",
1861: auth->info.lnkname, acl));
1862: acls = &(auth->params.acl_rule);
1863: } else if (res == RAD_MPD_PIPE) {
1864: acl1 = acl = rad_cvt_string(data, len);
1865: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_PIPE: %s",
1866: auth->info.lnkname, acl));
1867: acls = &(auth->params.acl_pipe);
1868: } else if (res == RAD_MPD_QUEUE) {
1869: acl1 = acl = rad_cvt_string(data, len);
1870: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_QUEUE: %s",
1871: auth->info.lnkname, acl));
1872: acls = &(auth->params.acl_queue);
1873: } else if (res == RAD_MPD_TABLE) {
1874: acl1 = acl = rad_cvt_string(data, len);
1875: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_TABLE: %s",
1876: auth->info.lnkname, acl));
1877: acls = &(auth->params.acl_table);
1878: } else if (res == RAD_MPD_TABLE_STATIC) {
1879: acl1 = acl = rad_cvt_string(data, len);
1880: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_TABLE_STATIC: %s",
1881: auth->info.lnkname, acl));
1882: acls = &(auth->params.acl_table);
1883: } else
1884: #endif /* USE_IPFW */
1885: #ifdef USE_NG_BPF
1886: if (res == RAD_MPD_FILTER) {
1887: acl1 = acl = rad_cvt_string(data, len);
1888: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_FILTER: %s",
1889: auth->info.lnkname, acl));
1890: acl2 = strsep(&acl1, "#");
1.1.1.2 ! misho 1891: i = atoi(acl2);
1.1 misho 1892: if (i <= 0 || i > ACL_FILTERS) {
1893: Log(LG_RADIUS, ("[%s] RADIUS: Wrong filter number: %i",
1894: auth->info.lnkname, i));
1895: free(acl);
1896: break;
1897: }
1898: acls = &(auth->params.acl_filters[i - 1]);
1899: } else if (res == RAD_MPD_LIMIT) {
1900: acl1 = acl = rad_cvt_string(data, len);
1901: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_LIMIT: %s",
1902: auth->info.lnkname, acl));
1903: acl2 = strsep(&acl1, "#");
1904: if (strcasecmp(acl2, "in") == 0) {
1905: i = 0;
1906: } else if (strcasecmp(acl2, "out") == 0) {
1907: i = 1;
1908: } else {
1909: Log(LG_ERR, ("[%s] RADIUS: Wrong limit direction: '%s'",
1910: auth->info.lnkname, acl2));
1911: free(acl);
1912: break;
1913: }
1914: acls = &(auth->params.acl_limits[i]);
1915: } else if (res == RAD_MPD_INPUT_ACCT) {
1916: tmpval = rad_cvt_string(data, len);
1917: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_INPUT_ACCT: %s",
1918: auth->info.lnkname, tmpval));
1919: strlcpy(auth->params.std_acct[0], tmpval,
1920: sizeof(auth->params.std_acct[0]));
1921: free(tmpval);
1922: break;
1923: } else if (res == RAD_MPD_OUTPUT_ACCT) {
1924: tmpval = rad_cvt_string(data, len);
1925: Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_MPD_OUTPUT_ACCT: %s",
1926: auth->info.lnkname, tmpval));
1927: strlcpy(auth->params.std_acct[1], tmpval,
1928: sizeof(auth->params.std_acct[1]));
1929: free(tmpval);
1930: break;
1931: } else
1932: #endif /* USE_NG_BPF */
1933: {
1934: Log(LG_RADIUS2, ("[%s] RADIUS: Dropping MPD vendor specific attribute: %d",
1935: auth->info.lnkname, res));
1936: break;
1937: }
1938: #if defined(USE_NG_BPF) || defined(USE_IPFW)
1939: if (acl1 == NULL) {
1.1.1.2 ! misho 1940: Log(LG_ERR, ("[%s] RADIUS: Incorrect acl!", auth->info.lnkname));
1.1 misho 1941: free(acl);
1942: break;
1943: }
1.1.1.2 ! misho 1944:
1.1 misho 1945: acl3 = acl1;
1946: strsep(&acl3, "=");
1947: acl2 = acl1;
1948: strsep(&acl2, "#");
1.1.1.2 ! misho 1949: i = atoi(acl1);
1.1 misho 1950: if (i <= 0) {
1951: Log(LG_ERR, ("[%s] RADIUS: Wrong acl number: %i",
1952: auth->info.lnkname, i));
1953: free(acl);
1954: break;
1955: }
1956: if ((acl3 == NULL) || (acl3[0] == 0)) {
1957: Log(LG_ERR, ("[%s] RADIUS: Wrong acl", auth->info.lnkname));
1958: free(acl);
1959: break;
1960: }
1961: acls1 = Malloc(MB_AUTH, sizeof(struct acl) + strlen(acl3));
1962: if (res != RAD_MPD_TABLE_STATIC) {
1963: acls1->number = i;
1964: acls1->real_number = 0;
1965: } else {
1966: acls1->number = 0;
1967: acls1->real_number = i;
1968: }
1969: if (acl2)
1970: strlcpy(acls1->name, acl2, sizeof(acls1->name));
1971: strcpy(acls1->rule, acl3);
1972: while ((*acls != NULL) && ((*acls)->number < acls1->number))
1973: acls = &((*acls)->next);
1974:
1975: if (*acls == NULL) {
1976: acls1->next = NULL;
1977: } else if (((*acls)->number == acls1->number) &&
1978: (res != RAD_MPD_TABLE) &&
1979: (res != RAD_MPD_TABLE_STATIC)) {
1.1.1.2 ! misho 1980: Log(LG_ERR, ("[%s] RADIUS: Duplicate acl", auth->info.lnkname));
1.1 misho 1981: Freee(acls1);
1982: free(acl);
1983: break;
1984: } else {
1985: acls1->next = *acls;
1986: }
1987: *acls = acls1;
1988:
1989: free(acl);
1990: break;
1991: #endif /* USE_NG_BPF or USE_IPFW */
1992:
1993: default:
1.1.1.2 ! misho 1994: Log(LG_RADIUS2, ("[%s] RADIUS: Dropping vendor %d attribute: %d",
1.1 misho 1995: auth->info.lnkname, vendor, res));
1996: break;
1997: }
1998: break;
1999:
2000: default:
1.1.1.2 ! misho 2001: Log(LG_RADIUS2, ("[%s] RADIUS: Dropping attribute: %d",
1.1 misho 2002: auth->info.lnkname, res));
2003: break;
2004: }
2005: }
2006:
2007: if (auth->acct_type == 0) {
2008:
2009: /* sanity check, this happens when FreeRADIUS has no msoft-dictionary loaded */
2010: if (auth->proto == PROTO_CHAP && auth->alg == CHAP_ALG_MSOFTv2
2011: && auth->mschapv2resp == NULL && auth->status == AUTH_STATUS_SUCCESS) {
2012: Log(LG_RADIUS, ("[%s] RADIUS: PANIC no MS-CHAP2-Success received from server!",
2013: auth->info.lnkname));
2014: return RAD_NACK;
2015: }
2016:
2017: /* MPPE allowed or required, but no MPPE keys returned */
2018: /* print warning, because MPPE doesen't work */
2019: if (!(auth->params.msoft.has_keys || auth->params.msoft.has_nt_hash || auth->params.msoft.has_lm_hash) &&
2020: auth->params.msoft.policy != MPPE_POLICY_NONE) {
2021: Log(LG_RADIUS, ("[%s] RADIUS: WARNING no MPPE-Keys received, MPPE will not work",
2022: auth->info.lnkname));
2023: }
2024:
2025: /* If no MPPE-Infos are returned by the RADIUS server, then allow all */
2026: /* MSoft IAS sends no Infos if all MPPE-Types are enabled and if encryption is optional */
2027: if (auth->params.msoft.policy == MPPE_POLICY_NONE &&
2028: auth->params.msoft.types == MPPE_TYPE_0BIT &&
2029: (auth->params.msoft.has_keys || auth->params.msoft.has_nt_hash || auth->params.msoft.has_lm_hash)) {
2030: auth->params.msoft.policy = MPPE_POLICY_ALLOWED;
2031: auth->params.msoft.types = MPPE_TYPE_40BIT | MPPE_TYPE_128BIT | MPPE_TYPE_56BIT;
2032: Log(LG_RADIUS, ("[%s] RADIUS: MPPE-Keys present, but no MPPE-Infos received => allowing MPPE with all types",
2033: auth->info.lnkname));
2034: }
2035:
2036: /* If Framed-IP-Address is present and Framed-Netmask != 32 add route */
2037: if (auth->params.range_valid && auth->params.range.width == 32 &&
2038: auth->params.netmask != 0 && auth->params.netmask != 32) {
2039: struct in_addr tmpmask;
2040: widthtoin_addr(auth->params.netmask, &tmpmask);
2041: r = Malloc(MB_AUTH, sizeof(struct ifaceroute));
2042: r->dest.addr = auth->params.range.addr;
2043: r->dest.addr.u.ip4.s_addr &= tmpmask.s_addr;
2044: r->dest.width = auth->params.netmask;
2045: r->ok = 0;
2046: j = 0;
2047: SLIST_FOREACH(r1, &auth->params.routes, next) {
2048: if (!u_rangecompare(&r->dest, &r1->dest)) {
2049: Log(LG_RADIUS, ("[%s] RADIUS: Duplicate route", auth->info.lnkname));
2050: j = 1;
2051: }
2052: };
2053: if (j == 0) {
2054: SLIST_INSERT_HEAD(&auth->params.routes, r, next);
2055: } else {
2056: Freee(r);
2057: }
2058: }
2059: }
2060:
2061: return (RAD_ACK);
2062: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>