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

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

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