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

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

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