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