Annotation of embedaddon/mpd/src/radius.c, revision 1.1

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

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