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