File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / radius.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 09:50:34 2016 UTC (7 years, 8 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p1_cross, v5_8p1, HEAD
mpd 5.8rc1

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

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