Annotation of embedaddon/mpd/src/radius.c, revision 1.1.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>