File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / radius.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:32:47 2012 UTC (12 years, 4 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_6, HEAD
mpd

    1: /*
    2:  * See ``COPYRIGHT.mpd''
    3:  *
    4:  * $Id: radius.c,v 1.1.1.1 2012/02/21 23:32:47 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, 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>