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