File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / radius.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (3 years, 3 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

    1: /*
    2:  * See ``COPYRIGHT.mpd''
    3:  *
    4:  * $Id: radius.c,v 1.1.1.6 2021/03/17 00:39:23 misho 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, const char *const av[], const 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:   static void	RadiusLogError(AuthData auth, const char *errmsg);
   49: 
   50: /* Set menu options */
   51: 
   52:   enum {
   53: 	UNSET_SERVER,
   54:     SET_SERVER,
   55: #ifdef HAVE_RAD_BIND
   56:     SET_SRC_ADDR,
   57: #endif
   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:  */
   71:   const struct cmdtab RadiusUnSetCmds[] = {
   72: 	  { "server {name} [{auth port}] [{acct port}]", "Unset (remove) radius server" ,
   73: 		  RadiusSetCommand, NULL, 2, (void *) UNSET_SERVER },
   74: 	  { NULL, NULL, NULL, NULL, 0, NULL },
   75:   };
   76:   
   77:   const struct cmdtab RadiusSetCmds[] = {
   78:     { "server {name} {secret} [{auth port}] [{acct port}]", "Set radius server parameters" ,
   79: 	RadiusSetCommand, NULL, 2, (void *) SET_SERVER },
   80: #ifdef HAVE_RAD_BIND
   81:     { "src-addr {ip}",			"Set source address for request" ,
   82: 	RadiusSetCommand, NULL, 2, (void *) SET_SRC_ADDR },
   83: #endif
   84:     { "me {ip}",			"Set NAS IP address" ,
   85: 	RadiusSetCommand, NULL, 2, (void *) SET_ME },
   86:     { "v6me {ip}",			"Set NAS IPv6 address" ,
   87: 	RadiusSetCommand, NULL, 2, (void *) SET_MEV6 },
   88:     { "identifier {name}",		"Set NAS identifier string" ,
   89: 	RadiusSetCommand, NULL, 2, (void *) SET_IDENTIFIER },
   90:     { "timeout {seconds}",		"Set timeout in seconds",
   91: 	RadiusSetCommand, NULL, 2, (void *) SET_TIMEOUT },
   92:     { "retries {# retries}",		"set number of retries",
   93: 	RadiusSetCommand, NULL, 2, (void *) SET_RETRIES },
   94:     { "config {path to radius.conf}",	"set path to config file for libradius",
   95: 	RadiusSetCommand, NULL, 2, (void *) SET_CONFIG },
   96:     { "enable [opt ...]",		"Enable option",
   97: 	RadiusSetCommand, NULL, 2, (void *) SET_ENABLE },
   98:     { "disable [opt ...]",		"Disable option",
   99: 	RadiusSetCommand, NULL, 2, (void *) SET_DISABLE },
  100:     { NULL, NULL, NULL, NULL, 0, NULL },
  101:   };
  102: 
  103: /*
  104:  * INTERNAL VARIABLES
  105:  */
  106: 
  107:   static const struct confinfo	gConfList[] = {
  108:     { 0,	RADIUS_CONF_MESSAGE_AUTHENTIC,	"message-authentic"	},
  109:     { 0,	0,				NULL			},
  110:   };
  111: 
  112:   #define RAD_NACK		0
  113:   #define RAD_ACK		1
  114: 
  115: static int
  116: rad_put_string_tag(struct rad_handle *h, int type, u_char tag, const char *str);
  117: 
  118: static int
  119: rad_put_string_tag(struct rad_handle *h, int type, u_char tag, const char *str)
  120: {
  121:     char *tmp;
  122:     int res;
  123:     int len = strlen(str);
  124:     
  125:     if (tag == 0) {
  126: 	res = rad_put_attr(h, type, str, len);
  127:     } else if (tag <= 0x1F) {
  128: 	tmp = Malloc(MB_RADIUS, len + 1);
  129: 	tmp[0] = tag;
  130: 	memcpy(tmp + 1, str, len);
  131: 	res = rad_put_attr(h, type, tmp, len + 1);
  132: 	Freee(tmp);
  133:     } else {
  134: 	res = -1;
  135:     }
  136:     return (res);
  137: }
  138: 
  139: /*
  140:  * RadiusInit()
  141:  */
  142: 
  143: void
  144: RadiusInit(Link l)
  145: {
  146:     RadConf       const conf = &l->lcp.auth.conf.radius;
  147: 
  148:     memset(conf, 0, sizeof(*conf));
  149:     conf->radius_retries = 3;
  150:     conf->radius_timeout = 5;
  151: }
  152: 
  153: int
  154: RadiusAuthenticate(AuthData auth) 
  155: {
  156:     Log(LG_RADIUS, ("[%s] RADIUS: Authenticating user '%s'", 
  157: 	auth->info.lnkname, auth->params.authname));
  158: 
  159:     if ((RadiusStart(auth, RAD_ACCESS_REQUEST) == RAD_NACK) ||
  160: 	(RadiusPutAuth(auth) == RAD_NACK) ||
  161: 	(RadiusSendRequest(auth) == RAD_NACK)) {
  162: 	    return (-1);
  163:     }
  164:   
  165:     return (0);
  166: }
  167: 
  168: /*
  169:  * RadiusAccount()
  170:  *
  171:  * Do RADIUS accounting
  172:  * NOTE: thread-safety is needed here
  173:  */
  174:  
  175: int 
  176: RadiusAccount(AuthData auth) 
  177: {
  178:     Log(auth->acct_type != AUTH_ACCT_UPDATE ? LG_RADIUS : LG_RADIUS2,
  179: 	("[%s] RADIUS: Accounting user '%s' (Type: %d)",
  180: 	auth->info.lnkname, auth->params.authname, auth->acct_type));
  181: 
  182:     if ((RadiusStart(auth, RAD_ACCOUNTING_REQUEST) == RAD_NACK) ||
  183: 	(RadiusPutAcct(auth) == RAD_NACK) ||
  184: 	(RadiusSendRequest(auth) == RAD_NACK)) {
  185: 	    return (-1);
  186:     }
  187: 
  188:     return (0);
  189: }
  190: 
  191: /*
  192:  * RadiusEapProxy()
  193:  *
  194:  * paction handler for RADIUS EAP Proxy requests.
  195:  * Thread-Safety is needed here
  196:  * auth->status must be set to AUTH_STATUS_FAIL, if the 
  197:  * request couldn't sent, because for EAP a successful
  198:  * RADIUS request is mandatory
  199:  */
  200:  
  201: void
  202: RadiusEapProxy(void *arg)
  203: {
  204:     AuthData	auth = (AuthData)arg;
  205:     int		pos = 0, mlen = RAD_MAX_ATTR_LEN;
  206: 
  207:     Log(LG_RADIUS, ("[%s] RADIUS: EAP proxying user '%s'",
  208: 	auth->info.lnkname, auth->params.authname));
  209: 
  210:     if (RadiusStart(auth, RAD_ACCESS_REQUEST) == RAD_NACK) {
  211: 	auth->status = AUTH_STATUS_FAIL;
  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) {
  218: 	RadiusLogError(auth, "Put RAD_USER_NAME failed");
  219: 	auth->status = AUTH_STATUS_FAIL;
  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) {
  233:     	    RadiusLogError(auth, "Put RAD_EAP_MESSAGE failed");
  234:     	    auth->status = AUTH_STATUS_FAIL;
  235:     	    return;
  236: 	}
  237:     }
  238: 
  239:     if (RadiusSendRequest(auth) == RAD_NACK) {
  240: 	auth->status = AUTH_STATUS_FAIL;
  241: 	return;
  242:     }
  243: 
  244:     return;
  245: }
  246: 
  247: void
  248: RadiusClose(AuthData auth) 
  249: {
  250:     if (auth->radius.handle != NULL)
  251: 	rad_close(auth->radius.handle);  
  252:     auth->radius.handle = NULL;
  253: }
  254: 
  255: int
  256: RadStat(Context ctx, int ac, const char *const av[], const void *arg)
  257: {
  258:   Auth		const a = &ctx->lnk->lcp.auth;
  259:   RadConf	const conf = &a->conf.radius;
  260:   int		i;
  261:   char		*buf;
  262:   RadServe_Conf	server;
  263:   char		buf1[64];
  264: 
  265:   (void)ac;
  266:   (void)av;
  267:   (void)arg;
  268: 
  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"));
  273: #ifdef HAVE_RAD_BIND
  274:   Printf("\tSrc address  : %s\r\n", inet_ntoa(conf->src_addr));
  275: #endif
  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:   
  312:   Printf("\tFilter Id      : %s\r\n", (a->params.filter_id ? a->params.filter_id : ""));
  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) {
  336: 		RadiusLogError(auth, "Adding server error");
  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) {
  347: 		RadiusLogError(auth, "Adding server error");
  348: 		return (RAD_NACK);
  349:         }
  350:     }
  351: 
  352:     s = s->next;
  353:   }
  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
  358: 
  359:   return (RAD_ACK);
  360: }
  361:   
  362: /* Set menu options */
  363: static int
  364: RadiusSetCommand(Context ctx, int ac, const char *const av[], const void *arg) 
  365: {
  366:   RadConf	const conf = &ctx->lnk->lcp.auth.conf.radius;
  367:   RadServe_Conf	server;
  368:   RadServe_Conf	t_server;
  369:   RadServe_Conf	next, prev;
  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: 
  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: 
  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: 
  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: 
  463:       case SET_ME:
  464:         if (ParseAddr(*av, &t, ALLOW_IPV4)) {
  465: 	    u_addrtoin_addr(&t, &conf->radius_me);
  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) {
  535:     	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_open failed",
  536:     	        auth->info.lnkname));
  537:     	    return (RAD_NACK);
  538: 	}
  539:     } else { /* RAD_ACCOUNTING_REQUEST */
  540:   
  541: 	if ((auth->radius.handle = rad_acct_open()) == NULL) {
  542:     	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_acct_open failed",
  543:     	        auth->info.lnkname));
  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) {
  551:     	    RadiusLogError(auth, "rad_config");
  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) {
  584: 	    Log(LG_ERR|LG_RADIUS,
  585: 		("[%s] RADIUS: gethostname() for RAD_NAS_IDENTIFIER failed",
  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)  {
  594: 	RadiusLogError(auth, "Put RAD_NAS_IDENTIFIER failed");
  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) {
  602: 	RadiusLogError(auth, "Put RAD_NAS_IP_ADDRESS failed");
  603: 	return (RAD_NACK);
  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))));
  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
  613:     if (rad_put_attr(auth->radius.handle, RAD_NAS_IPV6_ADDRESS, &conf->radius_mev6.u.ip6, sizeof(conf->radius_mev6.u.ip6)) == -1) {
  614: #endif
  615: 	RadiusLogError(auth, "Put RAD_NAS_IPV6_ADDRESS failed");
  616: 	return (RAD_NACK);
  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) {
  628: 	RadiusLogError(auth, "Put message_authentic failed");
  629: 	return (RAD_NACK);
  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) {
  636: 	RadiusLogError(auth, "Put RAD_ACCT_SESSION_ID failed");
  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)  {
  643: 	RadiusLogError(auth, "Put RAD_NAS_PORT failed");
  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) {
  668: 	RadiusLogError(auth, "Put RAD_NAS_PORT_TYPE failed");
  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) {
  675: 	RadiusLogError(auth, "Put RAD_SERVICE_TYPE failed");
  676: 	return (RAD_NACK);
  677:     }
  678:  
  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) {
  682: 	RadiusLogError(auth, "Put RAD_FRAMED_PROTOCOL failed");
  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) {
  691: 	    RadiusLogError(auth, "Put RAD_STATE failed");
  692: 	    return (RAD_NACK);
  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) {
  701: 	    RadiusLogError(auth, "Put RAD_CLASS failed");
  702: 	    return (RAD_NACK);
  703: 	}
  704:     }
  705: 
  706:     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_CALLING_STATION_ID: %s",
  707: 	auth->info.lnkname, auth->params.callingnum));
  708:     if (rad_put_string(auth->radius.handle, RAD_CALLING_STATION_ID,
  709: 	    auth->params.callingnum) == -1) {
  710: 	RadiusLogError(auth, "Put RAD_CALLING_STATION_ID failed");
  711: 	return (RAD_NACK);
  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,
  716: 	    auth->params.callednum) == -1) {
  717: 	RadiusLogError(auth, "Put RAD_CALLED_STATION_ID failed");
  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) {
  726: 	    RadiusLogError(auth, "Put RAD_NAS_PORT_ID failed");
  727: 	    return (RAD_NACK);
  728: 	}
  729:     }
  730: 
  731:     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_LINK: %s", 
  732: 	auth->info.lnkname, auth->info.lnkname));
  733:     if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_LINK, auth->info.lnkname) != 0) {
  734: 	RadiusLogError(auth, "Put RAD_MPD_LINK failed");
  735: 	return (RAD_NACK);
  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) {
  742: 	RadiusLogError(auth, "Put RAD_MPD_PEER_IDENT failed");
  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) {
  778: 	    RadiusLogError(auth, "Put RAD_TUNNEL_TYPE failed");
  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) {
  796: 	    RadiusLogError(auth, "Put RAD_TUNNEL_MEDIUM_TYPE failed");
  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",
  806: 		auth->info.lnkname, tmpval));
  807: 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_ENDPOINT,
  808: 		    0, tmpval) == -1) {
  809: 		RadiusLogError(auth, "Put RAD_TUNNEL_SERVER_ENDPOINT failed");
  810: 		return (RAD_NACK);
  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",
  820: 		auth->info.lnkname, tmpval));
  821: 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_ENDPOINT,
  822: 		    0, tmpval) == -1) {
  823: 		RadiusLogError(auth, "Put RAD_TUNNEL_CLIENT_ENDPOINT failed");
  824: 		return (RAD_NACK);
  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",
  834: 		auth->info.lnkname, tmpval));
  835: 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_SERVER_AUTH_ID,
  836: 		    0, tmpval) == -1) {
  837: 		RadiusLogError(auth, "Put RAD_TUNNEL_SERVER_AUTH_ID failed");
  838: 		return (RAD_NACK);
  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",
  848: 		auth->info.lnkname, tmpval));
  849: 	    if (rad_put_string_tag(auth->radius.handle, RAD_TUNNEL_CLIENT_AUTH_ID,
  850: 		    0, tmpval) == -1) {
  851: 		RadiusLogError(auth, "Put RAD_TUNNEL_CLIENT_AUTH_ID failed");
  852: 		return (RAD_NACK);
  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",
  860: 		auth->info.lnkname, auth->params.selfname));
  861: 	    if (rad_put_vendor_string(auth->radius.handle, 3561, 1,
  862: 		    auth->params.selfname) == -1) {
  863: 		RadiusLogError(auth, "Put ADSL-Agent-Circuit-Id failed");
  864: 		return (RAD_NACK);
  865: 	    }
  866: 	}
  867: 	if (auth->params.peername[0]) {
  868: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put ADSL-Agent-Remote-Id: %s",
  869: 		auth->info.lnkname, auth->params.peername));
  870: 	    if (rad_put_vendor_string(auth->radius.handle, 3561, 2,
  871: 		    auth->params.peername) == -1) {
  872: 		RadiusLogError(auth, "Put ADSL-Agent-Remote-Id failed");
  873: 		return (RAD_NACK);
  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) {
  897:     RadiusLogError(auth, "Put RAD_USER_NAME failed");
  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) {
  906: 	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv1) unrecognised key length %d/%d",
  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)  {
  915: 	  RadiusLogError(auth, "Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed");
  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)  {
  929: 	  RadiusLogError(auth, "Put RAD_MICROSOFT_MS_CHAP_RESPONSE failed");
  930: 	  return (RAD_NACK);
  931: 	}
  932: 	break;
  933: 
  934:       case CHAP_ALG_MSOFTv2:
  935: 	if (cp->value_len != sizeof(*mschapv2val)) {
  936: 	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: RADIUS_CHAP (MSOFTv2) unrecognised key length %d/%d",
  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) {
  945: 	  RadiusLogError(auth, "Put RAD_MICROSOFT_MS_CHAP_CHALLENGE failed");
  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)  {
  963: 	  RadiusLogError(auth, "Put vendor_attr(RAD_MICROSOFT_MS_CHAP2_RESPONSE failed");
  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) {
  975: 	  RadiusLogError(auth, "Put RAD_CHAP_CHALLENGE failed");
  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) {
  981: 	  RadiusLogError(auth, "Put RAD_CHAP_PASSWORD failed");
  982: 	  return (RAD_NACK);
  983: 	}
  984: 	break;
  985:       
  986:       default:
  987: 	Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: RADIUS unkown CHAP ALG: %d", 
  988: 	  auth->info.lnkname, auth->alg));
  989: 	return (RAD_NACK);
  990:     }
  991:   } else if (auth->proto == PROTO_PAP) {
  992:     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_USER_PASSWORD", auth->info.lnkname));
  993:     if (rad_put_string(auth->radius.handle, RAD_USER_PASSWORD, pp->peer_pass) == -1) {
  994:       RadiusLogError(auth, "Put RAD_USER_PASSWORD failed");
  995:       return (RAD_NACK);
  996:     }
  997:   } else {
  998:     Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: RADIUS unkown Proto: %d", 
  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;
 1012:     char buf[64];
 1013: 
 1014:     if (auth->acct_type == AUTH_ACCT_START) {
 1015: 	Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_STATUS_TYPE: RAD_START", 
 1016: 	    auth->info.lnkname));
 1017: 	if (rad_put_int(auth->radius.handle, RAD_ACCT_STATUS_TYPE, RAD_START)) {
 1018: 	    RadiusLogError(auth, "Put STATUS_TYPE failed");
 1019: 	    return (RAD_NACK);
 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)) {
 1026: 	RadiusLogError(auth, "Put RAD_FRAMED_IP_ADDRESS failed");
 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)) {
 1036: 	    RadiusLogError(auth, "Put RAD_FRAMED_IP_NETMASK failed");
 1037: 	    return (RAD_NACK);
 1038: 	}
 1039:     }
 1040: 
 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: 
 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) {
 1055: 	RadiusLogError(auth, "Put RAD_USER_NAME failed");
 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) {
 1062: 	RadiusLogError(auth, "Put RAD_ACCT_MULTI_SESSION_ID failed");
 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) {
 1069: 	RadiusLogError(auth, "Put RAD_MPD_BUNDLE failed");
 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) {
 1076: 	RadiusLogError(auth, "Put RAD_MPD_IFACE failed");
 1077: 	return (RAD_NACK);
 1078:     }
 1079: 
 1080:     Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_MPD_IFACE_INDEX: %u", 
 1081:         auth->info.lnkname, auth->info.ifindex));
 1082:     if (rad_put_vendor_int(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_IFACE_INDEX, auth->info.ifindex) != 0) {
 1083: 	RadiusLogError(auth, "Put RAD_MPD_IFACE_INDEX failed");
 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) {
 1090: 	RadiusLogError(auth, "Put RAD_MPD_PEER_IDENT failed");
 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) {
 1097: 	RadiusLogError(auth, "Put RAD_ACCT_LINK_COUNT failed");
 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) {
 1109: 	RadiusLogError(auth, "Put RAD_ACCT_AUTHENTIC failed");
 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)) {
 1125: 	    RadiusLogError(auth, "Put RAD_ACCT_STATUS_TYPE failed");
 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) {
 1158: 	    RadiusLogError(auth, "Put RAD_ACCT_TERMINATE_CAUSE failed");
 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)) {
 1165: 	    RadiusLogError(auth, "Put RAD_ACCT_STATUS_TYPE failed");
 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) {
 1173:         RadiusLogError(auth, "Put RAD_ACCT_SESSION_TIME failed");
 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) {
 1189:     		RadiusLogError(auth, "Put input stats failed");
 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) {
 1205:     		RadiusLogError(auth, "Put output stats failed");
 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", 
 1215: 	    auth->info.lnkname, str));
 1216: 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_OCTETS, str) != 0) {
 1217: 	    RadiusLogError(auth, "Put RAD_MPD_INPUT_OCTETS failed");
 1218: 	    return (RAD_NACK);
 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", 
 1223: 	    auth->info.lnkname, str));
 1224: 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_INPUT_PACKETS, str) != 0) {
 1225: 	    RadiusLogError(auth, "Put RAD_MPD_INPUT_PACKETS failed");
 1226: 	    return (RAD_NACK);
 1227: 	}
 1228: 	if (strcmp(ssr->name,auth->params.std_acct[0]) == 0) {
 1229: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_OCTETS: %lu", 
 1230: 		auth->info.lnkname, (long unsigned int)(ssr->Octets % MAX_U_INT32)));
 1231: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_GIGAWORDS: %lu", 
 1232: 		auth->info.lnkname, (long unsigned int)(ssr->Octets / MAX_U_INT32)));
 1233: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_INPUT_PACKETS: %lu", 
 1234: 		auth->info.lnkname, (long unsigned int)(ssr->Packets)));
 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) {
 1238: 		    RadiusLogError(auth, "Put input stats failed");
 1239: 		    return (RAD_NACK);
 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", 
 1248: 	    auth->info.lnkname, str));
 1249: 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_OCTETS, str) != 0) {
 1250: 	    RadiusLogError(auth, "Put RAD_MPD_OUTPUT_OCTETS failed");
 1251: 	    return (RAD_NACK);
 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", 
 1256: 	    auth->info.lnkname, str));
 1257: 	if (rad_put_vendor_string(auth->radius.handle, RAD_VENDOR_MPD, RAD_MPD_OUTPUT_PACKETS, str) != 0) {
 1258: 	    RadiusLogError(auth, "Put RAD_MPD_OUTPUT_PACKETS failed");
 1259: 	    return (RAD_NACK);
 1260: 	}
 1261: 	if (strcmp(ssr->name,auth->params.std_acct[1]) == 0) {
 1262: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_OCTETS: %lu", 
 1263: 		auth->info.lnkname, (long unsigned int)(ssr->Octets % MAX_U_INT32)));
 1264: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_GIGAWORDS: %lu", 
 1265: 		auth->info.lnkname, (long unsigned int)(ssr->Octets / MAX_U_INT32)));
 1266: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Put RAD_ACCT_OUTPUT_PACKETS: %lu", 
 1267: 		auth->info.lnkname, (long unsigned int)(ssr->Packets)));
 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) {
 1271: 		    RadiusLogError(auth, "Put output stats failed");
 1272: 		    return (RAD_NACK);
 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) {
 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);
 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) {
 1311: 	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: poll failed %s",
 1312: 	        auth->info.lnkname, strerror(errno)));
 1313: 	    return (RAD_NACK);
 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:
 1366:     	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: rad_send_request: unexpected return value: %d", 
 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;
 1384:   struct in6_addr	ipv6;
 1385:   char		buf[64];
 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);
 1452:         Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IP_ADDRESS: %s",
 1453:           auth->info.lnkname, inet_ntoa(ip)));
 1454: 
 1455: 	if (ip.s_addr == INADDR_BROADCAST) {
 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: 
 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: 
 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);
 1487: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_USER_NAME: %s",
 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);
 1494: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IP_NETMASK: %s (/%d)",
 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);
 1500: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: %s",
 1501: 	  auth->info.lnkname, route));
 1502: 	if (!ParseRange(route, &range, ALLOW_IPV4)) {
 1503: 	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_ROUTE: Bad route \"%s\"",
 1504: 	    auth->info.lnkname, route));
 1505: 	  free(route);
 1506: 	  break;
 1507: 	}
 1508: 	r = Malloc(MB_AUTH, sizeof(struct ifaceroute));
 1509: 	r->dest = range;
 1510: 	r->ok = 0;
 1511: 	j = 0;
 1512: 	SLIST_FOREACH(r1, &auth->params.routes, next) {
 1513: 	  if (!u_rangecompare(&r->dest, &r1->dest)) {
 1514: 	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
 1515: 		auth->info.lnkname, route));
 1516: 	    j = 1;
 1517: 	  }
 1518: 	};
 1519: 	free(route);
 1520: 	if (j == 0) {
 1521: 	    SLIST_INSERT_HEAD(&auth->params.routes, r, next);
 1522: 	} else {
 1523: 	    Freee(r);
 1524: 	}
 1525: 	break;
 1526: 
 1527:       case RAD_FRAMED_IPV6_ROUTE:
 1528: 	route = rad_cvt_string(data, len);
 1529: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: %s",
 1530: 	  auth->info.lnkname, route));
 1531: 	if (!ParseRange(route, &range, ALLOW_IPV6)) {
 1532: 	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_IPV6_ROUTE: Bad route \"%s\"", auth->info.lnkname, route));
 1533: 	  free(route);
 1534: 	  break;
 1535: 	}
 1536: 	r = Malloc(MB_AUTH, sizeof(struct ifaceroute));
 1537: 	r->dest = range;
 1538: 	r->ok = 0;
 1539: 	j = 0;
 1540: 	SLIST_FOREACH(r1, &auth->params.routes, next) {
 1541: 	  if (!u_rangecompare(&r->dest, &r1->dest)) {
 1542: 	    Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Duplicate route %s",
 1543: 		auth->info.lnkname, route));
 1544: 	    j = 1;
 1545: 	  }
 1546: 	};
 1547: 	free(route);
 1548: 	if (j == 0) {
 1549: 	    SLIST_INSERT_HEAD(&auth->params.routes, r, next);
 1550: 	} else {
 1551: 	    Freee(r);
 1552: 	}
 1553: 	break;
 1554: 
 1555:       case RAD_SESSION_TIMEOUT:
 1556:         auth->params.session_timeout = rad_cvt_int(data);
 1557:         Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_SESSION_TIMEOUT: %u",
 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);
 1563:         Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_IDLE_TIMEOUT: %u",
 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);
 1569:         Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_ACCT_INTERIM_INTERVAL: %u",
 1570:           auth->info.lnkname, auth->params.acct_update));
 1571: 	break;
 1572: 
 1573:       case RAD_FRAMED_MTU:
 1574: 	i = rad_cvt_int(data);
 1575: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_MTU: %u",
 1576: 	  auth->info.lnkname, i));
 1577: 	if (i < IFACE_MIN_MTU || i > IFACE_MAX_MTU) {
 1578: 	  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Get RAD_FRAMED_MTU: invalid MTU: %u",
 1579: 	    auth->info.lnkname, i));
 1580: 	  auth->params.mtu = 0;
 1581: 	  break;
 1582: 	}
 1583: 	auth->params.mtu = i;
 1584:         break;
 1585: 
 1586:       case RAD_FRAMED_COMPRESSION:
 1587:         i = rad_cvt_int(data);
 1588: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_COMPRESSION: %d",
 1589: 	  auth->info.lnkname, i));
 1590: 	if (i == RAD_COMP_VJ)
 1591: 	    auth->params.vjc_enable = 1;
 1592:         break;
 1593: 
 1594:       case RAD_FRAMED_PROTOCOL:
 1595: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_FRAMED_PROTOCOL: %d)",
 1596: 	  auth->info.lnkname, rad_cvt_int(data)));
 1597:         break;
 1598: 
 1599:       case RAD_FRAMED_ROUTING:
 1600: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get (RAD_FRAMED_ROUTING: %d)",
 1601: 	  auth->info.lnkname, rad_cvt_int(data)));
 1602:         break;
 1603: 
 1604:       case RAD_FILTER_ID:
 1605: 	Freee(auth->params.filter_id);
 1606: 	auth->params.filter_id = NULL;
 1607: 	if (len == 0)
 1608: 	    break;
 1609: 	tmpval = rad_cvt_string(data, len);
 1610: 	auth->params.filter_id = Mdup(MB_AUTH, tmpval, len + 1);
 1611: 	free(tmpval);
 1612: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FILTER_ID: %s",
 1613: 	  auth->info.lnkname, auth->params.filter_id));
 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:
 1622: 	Freee(auth->reply_message);
 1623: 	auth->reply_message = NULL;
 1624: 	if (len == 0)
 1625: 	    break;
 1626: 	tmpval = rad_cvt_string(data, len);
 1627: 	auth->reply_message = Mdup(MB_AUTH, tmpval, len + 1);
 1628: 	free(tmpval);
 1629: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_REPLY_MESSAGE: %s",
 1630: 	  auth->info.lnkname, auth->reply_message));
 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);
 1638: 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_POOL: %s",
 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) {
 1644: 	  Log(LG_RADIUS, ("[%s] RADIUS: Get vendor attr failed: %s",
 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);
 1703: 		auth->params.msdomain = NULL;
 1704: 		if (len == 0)
 1705: 		    break;
 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) {
 1720: 		  RadiusLogError(auth, "rad_demangle_mppe_key failed");
 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) {
 1734: 		  RadiusLogError(auth, "rad_demangle_mppe_key failed");
 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) {
 1748: 		  Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Server returned garbage %d of expected %d Bytes",
 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) {
 1755: 		  RadiusLogError(auth, "rad_demangle failed");
 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:
 1806: 		Log(LG_RADIUS2, ("[%s] RADIUS: Dropping MICROSOFT vendor specific attribute: %d",
 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, "#");
 1892: 	      i = atoi(acl2);
 1893: 	      if (i <= 0 || i > ACL_FILTERS) {
 1894: 	        Log(LG_ERR|LG_RADIUS, ("[%s] RADIUS: Wrong filter number: %i",
 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 {
 1910: 	        Log(LG_ERR|LG_ERR, ("[%s] RADIUS: Wrong limit direction: '%s'",
 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) {
 1941: 	      Log(LG_ERR, ("[%s] RADIUS: Incorrect acl!", auth->info.lnkname));
 1942: 	      free(acl);
 1943: 	      break;
 1944: 	    }
 1945: 
 1946: 	    acl3 = acl1;
 1947: 	    strsep(&acl3, "=");
 1948: 	    acl2 = acl1;
 1949: 	    strsep(&acl2, "#");
 1950: 	    i = atoi(acl1);
 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)) {
 1981: 	      Log(LG_ERR, ("[%s] RADIUS: Duplicate acl", auth->info.lnkname));
 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:
 1995: 	    Log(LG_RADIUS2, ("[%s] RADIUS: Dropping vendor %d attribute: %d",
 1996: 	      auth->info.lnkname, vendor, res));
 1997: 	    break;
 1998: 	}
 1999: 	break;
 2000: 
 2001:       default:
 2002: 	Log(LG_RADIUS2, ("[%s] RADIUS: Dropping attribute: %d",
 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) {
 2013: 	    Log(LG_ERR|LG_RADIUS, 
 2014: 		("[%s] RADIUS: PANIC no MS-CHAP2-Success received from server!",
 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) {
 2023: 	    Log(LG_ERR|LG_RADIUS, 
 2024: 		("[%s] RADIUS: WARNING no MPPE-Keys received, MPPE will not work",
 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;
 2035: 		Log(LG_ERR|LG_RADIUS, 
 2036: 		    ("[%s] RADIUS: MPPE-Keys present, but no MPPE-Infos received => allowing MPPE with all types",
 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)) {
 2053: 		    Log(LG_ERR|LG_RADIUS, 
 2054: 			("[%s] RADIUS: Duplicate route", auth->info.lnkname));
 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);
 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)));
 2074: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>