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

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

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