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