Annotation of embedaddon/mpd/src/radsrv.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * radsrv.c
                      4:  *
                      5:  * Written by Alexander Motin <mav@FreeBSD.org>
                      6:  */
                      7: 
                      8: #include "ppp.h"
                      9: #include "radsrv.h"
                     10: #include "util.h"
                     11: #include <radlib.h>
                     12: #include <radlib_vs.h>
                     13: 
                     14: #ifdef RAD_COA_REQUEST
                     15: 
                     16: /*
                     17:  * DEFINITIONS
                     18:  */
                     19: 
                     20:   /* Set menu options */
                     21:   enum {
                     22:     SET_OPEN,
                     23:     SET_CLOSE,
                     24:     SET_SELF,
                     25:     SET_PEER,
                     26:     SET_DISABLE,
                     27:     SET_ENABLE
                     28:   };
                     29: 
                     30: 
                     31: /*
                     32:  * INTERNAL FUNCTIONS
                     33:  */
                     34: 
                     35:   static int   RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg);
                     36: 
                     37: /*
                     38:  * GLOBAL VARIABLES
                     39:  */
                     40: 
                     41:   const struct cmdtab RadsrvSetCmds[] = {
                     42:     { "open",                  "Open the radsrv" ,
                     43:        RadsrvSetCommand, NULL, 2, (void *) SET_OPEN },
                     44:     { "close",                 "Close the radsrv" ,
                     45:        RadsrvSetCommand, NULL, 2, (void *) SET_CLOSE },
                     46:     { "self {ip} [{port}]",    "Set radsrv ip and port" ,
                     47:        RadsrvSetCommand, NULL, 2, (void *) SET_SELF },
                     48:     { "peer {ip} {secret}",    "Set peer ip and secret" ,
                     49:        RadsrvSetCommand, NULL, 2, (void *) SET_PEER },
                     50:     { "enable [opt ...]",      "Enable radsrv option" ,
                     51:        RadsrvSetCommand, NULL, 2, (void *) SET_ENABLE },
                     52:     { "disable [opt ...]",     "Disable radsrv option" ,
                     53:        RadsrvSetCommand, NULL, 2, (void *) SET_DISABLE },
                     54:     { NULL },
                     55:   };
                     56: 
                     57: 
                     58: /*
                     59:  * INTERNAL VARIABLES
                     60:  */
                     61: 
                     62:   static const struct confinfo gConfList[] = {
                     63:     { 0,       RADSRV_DISCONNECT,      "disconnect"    },
                     64:     { 0,       RADSRV_COA,     "coa"   },
                     65:     { 0,       0,              NULL    },
                     66:   };
                     67: 
                     68: /*
                     69:  * RadsrvInit()
                     70:  */
                     71: 
                     72: int
                     73: RadsrvInit(Radsrv w)
                     74: {
                     75:     /* setup radsrv-defaults */
                     76:     memset(w, 0, sizeof(*w));
                     77: 
                     78:     Enable(&w->options, RADSRV_DISCONNECT);
                     79:     Enable(&w->options, RADSRV_COA);
                     80: 
                     81:     ParseAddr(DEFAULT_RADSRV_IP, &w->addr, ALLOW_IPV4);
                     82:     w->port = DEFAULT_RADSRV_PORT;
                     83: 
                     84:     return (0);
                     85: }
                     86: 
                     87: static void
                     88: RadsrvEvent(int type, void *cookie)
                     89: {
                     90:     Radsrv     w = (Radsrv)cookie;
                     91:     const void *data;
                     92:     size_t     len;
                     93:     int                res, result, found, err, anysesid, l;
                     94:     Bund       B;
                     95:     Link       L;
                     96:     char        *tmpval;
                     97:     char       *username = NULL, *called = NULL, *calling = NULL, *sesid = NULL;
                     98:     char       *msesid = NULL, *link = NULL, *bundle = NULL, *iface = NULL;
                     99:     int                nasport = -1, serv_type = 0, ifindex = -1, i;
                    100:     u_int      session_timeout = -1, idle_timeout = -1, acct_update = -1;
                    101:     struct in_addr ip = { -1 };
                    102:     struct in_addr nas_ip = { -1 };
                    103:     char       buf[64];
                    104:     u_int32_t  vendor;
                    105:     u_char     *state = NULL;
                    106:     int                state_len = 0;
                    107:     int                authentic = 0;
                    108: #if defined(USE_NG_BPF) || defined(USE_IPFW)
                    109:     struct acl **acls, *acls1;
                    110:     char       *acl, *acl1, *acl2, *acl3;
                    111: #endif
                    112: #ifdef USE_IPFW
                    113:     struct acl         *acl_rule = NULL;       /* ipfw rules */
                    114:     struct acl         *acl_pipe = NULL;       /* ipfw pipes */
                    115:     struct acl         *acl_queue = NULL;      /* ipfw queues */
                    116:     struct acl         *acl_table = NULL;      /* ipfw tables */
                    117: #endif
                    118: #ifdef USE_NG_BPF
                    119:     struct acl         *acl_filters[ACL_FILTERS]; /* mpd's internal bpf filters */
                    120:     struct acl         *acl_limits[ACL_DIRS];  /* traffic limits based on mpd's filters */
                    121:     char               std_acct[ACL_DIRS][ACL_NAME_LEN]; /* Names of ACL returned in standard accounting */
                    122: 
                    123:     bzero(acl_filters, sizeof(acl_filters));
                    124:     bzero(acl_limits, sizeof(acl_limits));
                    125:     bzero(std_acct, sizeof(std_acct));
                    126: #endif
                    127:     result = rad_receive_request(w->handle);
                    128:     if (result < 0) {
                    129:        Log(LG_ERR, ("radsrv: request receive error: %d", result));
                    130:        return;
                    131:     }
                    132:     switch (result) {
                    133:        case RAD_DISCONNECT_REQUEST:
                    134:            if (!Enabled(&w->options, RADSRV_DISCONNECT)) {
                    135:                Log(LG_ERR, ("radsrv: DISCONNECT request, support disabled"));
                    136:                rad_create_response(w->handle, RAD_DISCONNECT_NAK);
                    137:                rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
                    138:                rad_send_response(w->handle);
                    139:                return;
                    140:            }
                    141:            Log(LG_ERR, ("radsrv: DISCONNECT request"));
                    142:            break;
                    143:        case RAD_COA_REQUEST:
                    144:            if (!Enabled(&w->options, RADSRV_COA)) {
                    145:                Log(LG_ERR, ("radsrv: CoA request, support disabled"));
                    146:                rad_create_response(w->handle, RAD_COA_NAK);
                    147:                rad_put_int(w->handle, RAD_ERROR_CAUSE, 501);
                    148:                rad_send_response(w->handle);
                    149:                return;
                    150:            }
                    151:            Log(LG_ERR, ("radsrv: CoA request"));
                    152:            break;
                    153:        default:
                    154:            Log(LG_ERR, ("radsrv: unsupported request: %d", result));
                    155:            return;
                    156:     }
                    157:     anysesid = 0;
                    158:     while ((res = rad_get_attr(w->handle, &data, &len)) > 0) {
                    159:        switch (res) {
                    160:            case RAD_USER_NAME:
                    161:                anysesid = 1;
                    162:                username = rad_cvt_string(data, len);
                    163:                Log(LG_RADIUS2, ("radsrv: Got RAD_USER_NAME: %s",
                    164:                    username));
                    165:                break;
                    166:            case RAD_NAS_IP_ADDRESS:
                    167:                nas_ip = rad_cvt_addr(data);
                    168:                Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_IP_ADDRESS: %s ",
                    169:                    inet_ntoa(nas_ip)));
                    170:                break;
                    171:            case RAD_SERVICE_TYPE:
                    172:                serv_type = rad_cvt_int(data);
                    173:                Log(LG_RADIUS2, ("radsrv: Got RAD_SERVICE_TYPE: %d",
                    174:                    serv_type));
                    175:                break;
                    176:            case RAD_STATE:
                    177:                tmpval = Bin2Hex(data, len);
                    178:                Log(LG_RADIUS2, ("radsrv: Get RAD_STATE: 0x%s", tmpval));
                    179:                Freee(tmpval);
                    180:                state_len = len;
                    181:                if (state != NULL)
                    182:                    Freee(state);
                    183:                state = Mdup(MB_RADSRV, data, len);
                    184:                break;
                    185:            case RAD_CALLED_STATION_ID:
                    186:                anysesid = 1;
                    187:                called = rad_cvt_string(data, len);
                    188:                Log(LG_RADIUS2, ("radsrv: Got RAD_CALLED_STATION_ID: %s ",
                    189:                    called));
                    190:                break;
                    191:            case RAD_CALLING_STATION_ID:
                    192:                anysesid = 1;
                    193:                calling = rad_cvt_string(data, len);
                    194:                Log(LG_RADIUS2, ("radsrv: Got RAD_CALLING_STATION_ID: %s ",
                    195:                    calling));
                    196:                break;
                    197:            case RAD_ACCT_SESSION_ID:
                    198:                anysesid = 1;
                    199:                sesid = rad_cvt_string(data, len);
                    200:                Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_SESSION_ID: %s ",
                    201:                    sesid));
                    202:                break;
                    203:            case RAD_ACCT_MULTI_SESSION_ID:
                    204:                anysesid = 1;
                    205:                msesid = rad_cvt_string(data, len);
                    206:                Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_MULTI_SESSION_ID: %s ",
                    207:                    msesid));
                    208:                break;
                    209:            case RAD_FRAMED_IP_ADDRESS:
                    210:                anysesid = 1;
                    211:                ip = rad_cvt_addr(data);
                    212:                Log(LG_RADIUS2, ("radsrv: Got RAD_FRAMED_IP_ADDRESS: %s ",
                    213:                    inet_ntoa(ip)));
                    214:                break;
                    215:            case RAD_NAS_PORT:
                    216:                anysesid = 1;
                    217:                nasport = rad_cvt_int(data);
                    218:                Log(LG_RADIUS2, ("radsrv: Got RAD_NAS_PORT: %d ",
                    219:                    nasport));
                    220:                break;
                    221:            case RAD_SESSION_TIMEOUT:
                    222:                session_timeout = rad_cvt_int(data);
                    223:                Log(LG_RADIUS2, ("radsrv: Got RAD_SESSION_TIMEOUT: %u ",
                    224:                    session_timeout));
                    225:                break;
                    226:            case RAD_IDLE_TIMEOUT:
                    227:                idle_timeout = rad_cvt_int(data);
                    228:                Log(LG_RADIUS2, ("radsrv: Got RAD_IDLE_TIMEOUT: %u ",
                    229:                    idle_timeout));
                    230:                break;
                    231:            case RAD_ACCT_INTERIM_INTERVAL:
                    232:                acct_update = rad_cvt_int(data);
                    233:                Log(LG_RADIUS2, ("radsrv: Got RAD_ACCT_INTERIM_INTERVAL: %u ",
                    234:                    acct_update));
                    235:                break;
                    236:            case RAD_MESSAGE_AUTHENTIC:
                    237:                Log(LG_RADIUS2, ("radsrv: Got RAD_MESSAGE_AUTHENTIC"));
                    238:                authentic = 1;
                    239:                break;
                    240:            case RAD_VENDOR_SPECIFIC:
                    241:                if ((res = rad_get_vendor_attr(&vendor, &data, &len)) == -1) {
                    242:                    Log(LG_RADIUS, ("radsrv: Get vendor attr failed: %s ",
                    243:                        rad_strerror(w->handle)));
                    244:                    break;
                    245:                }
                    246:                switch (vendor) {
                    247:                    case RAD_VENDOR_MPD:
                    248:                        if (res == RAD_MPD_LINK) {
                    249:                            if (link)
                    250:                                free(link);
                    251:                            link = rad_cvt_string(data, len);
                    252:                            Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LINK: %s",
                    253:                                link));
                    254:                            anysesid = 1;
                    255:                            break;
                    256:                        } else if (res == RAD_MPD_BUNDLE) {
                    257:                            if (bundle)
                    258:                                free(bundle);
                    259:                            bundle = rad_cvt_string(data, len);
                    260:                            Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_BINDLE: %s",
                    261:                                bundle));
                    262:                            anysesid = 1;
                    263:                            break;
                    264:                        } else if (res == RAD_MPD_IFACE) {
                    265:                            if (iface)
                    266:                                free(iface);
                    267:                            iface = rad_cvt_string(data, len);
                    268:                            Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE: %s",
                    269:                                iface));
                    270:                            anysesid = 1;
                    271:                            break;
                    272:                        } else if (res == RAD_MPD_IFACE_INDEX) {
                    273:                            ifindex = rad_cvt_int(data);
                    274:                            Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_IFACE_INDEX: %d",
                    275:                                ifindex));
                    276:                            anysesid = 1;
                    277:                            break;
                    278:                        } else 
                    279: #ifdef USE_IPFW
                    280:                        if (res == RAD_MPD_RULE) {
                    281:                          acl1 = acl = rad_cvt_string(data, len);
                    282:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_RULE: %s",
                    283:                            acl));
                    284:                          acls = &acl_rule;
                    285:                        } else if (res == RAD_MPD_PIPE) {
                    286:                          acl1 = acl = rad_cvt_string(data, len);
                    287:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_PIPE: %s",
                    288:                            acl));
                    289:                          acls = &acl_pipe;
                    290:                        } else if (res == RAD_MPD_QUEUE) {
                    291:                          acl1 = acl = rad_cvt_string(data, len);
                    292:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_QUEUE: %s",
                    293:                            acl));
                    294:                          acls = &acl_queue;
                    295:                        } else if (res == RAD_MPD_TABLE) {
                    296:                          acl1 = acl = rad_cvt_string(data, len);
                    297:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE: %s",
                    298:                            acl));
                    299:                          acls = &acl_table;
                    300:                        } else if (res == RAD_MPD_TABLE_STATIC) {
                    301:                          acl1 = acl = rad_cvt_string(data, len);
                    302:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_TABLE_STATIC: %s",
                    303:                            acl));
                    304:                          acls = &acl_table;
                    305:                        } else
                    306: #endif /* USE_IPFW */
                    307: #ifdef USE_NG_BPF
                    308:                        if (res == RAD_MPD_FILTER) {
                    309:                          acl1 = acl = rad_cvt_string(data, len);
                    310:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_FILTER: %s",
                    311:                            acl));
                    312:                          acl2 = strsep(&acl1, "#");
                    313:                          i = atol(acl2);
                    314:                          if (i <= 0 || i > ACL_FILTERS) {
                    315:                            Log(LG_RADIUS, ("radsrv: Wrong filter number: %i", i));
                    316:                            free(acl);
                    317:                            break;
                    318:                          }
                    319:                          acls = &(acl_filters[i - 1]);
                    320:                        } else if (res == RAD_MPD_LIMIT) {
                    321:                          acl1 = acl = rad_cvt_string(data, len);
                    322:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_LIMIT: %s",
                    323:                            acl));
                    324:                          acl2 = strsep(&acl1, "#");
                    325:                          if (strcasecmp(acl2, "in") == 0) {
                    326:                            i = 0;
                    327:                          } else if (strcasecmp(acl2, "out") == 0) {
                    328:                            i = 1;
                    329:                          } else {
                    330:                            Log(LG_ERR, ("radsrv: Wrong limit direction: '%s'",
                    331:                                acl2));
                    332:                            free(acl);
                    333:                            break;
                    334:                          }
                    335:                          acls = &(acl_limits[i]);
                    336:                        } else if (res == RAD_MPD_INPUT_ACCT) {
                    337:                          tmpval = rad_cvt_string(data, len);
                    338:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_INPUT_ACCT: %s",
                    339:                            tmpval));
                    340:                          strlcpy(std_acct[0], tmpval, sizeof(std_acct[0]));
                    341:                          free(tmpval);
                    342:                          break;
                    343:                        } else if (res == RAD_MPD_OUTPUT_ACCT) {
                    344:                          tmpval = rad_cvt_string(data, len);
                    345:                          Log(LG_RADIUS2, ("radsrv: Get RAD_MPD_OUTPUT_ACCT: %s",
                    346:                            tmpval));
                    347:                          strlcpy(std_acct[1], tmpval, sizeof(std_acct[1]));
                    348:                          free(tmpval);
                    349:                          break;
                    350:                        } else
                    351: #endif /* USE_NG_BPF */
                    352:                        {
                    353:                          Log(LG_RADIUS2, ("radsrv: Dropping MPD vendor specific attribute: %d",
                    354:                            res));
                    355:                          break;
                    356:                        }
                    357: #if defined(USE_NG_BPF) || defined(USE_IPFW)
                    358:                    if (acl1 == NULL) {
                    359:                      Log(LG_ERR, ("radsrv: Incorrect acl!"));
                    360:                      free(acl);
                    361:                      break;
                    362:                    }
                    363:            
                    364:                    acl3 = acl1;
                    365:                    strsep(&acl3, "=");
                    366:                    acl2 = acl1;
                    367:                    strsep(&acl2, "#");
                    368:                    i = atol(acl1);
                    369:                    if (i <= 0) {
                    370:                      Log(LG_ERR, ("radsrv: Wrong acl number: %i", i));
                    371:                      free(acl);
                    372:                      break;
                    373:                    }
                    374:                    if ((acl3 == NULL) || (acl3[0] == 0)) {
                    375:                      Log(LG_ERR, ("radsrv: Wrong acl"));
                    376:                      free(acl);
                    377:                      break;
                    378:                    }
                    379:                    acls1 = Malloc(MB_AUTH, sizeof(struct acl) + strlen(acl3));
                    380:                    if (res != RAD_MPD_TABLE_STATIC) {
                    381:                            acls1->number = i;
                    382:                            acls1->real_number = 0;
                    383:                    } else {
                    384:                            acls1->number = 0;
                    385:                            acls1->real_number = i;
                    386:                    }
                    387:                    if (acl2)
                    388:                        strlcpy(acls1->name, acl2, sizeof(acls1->name));
                    389:                    strcpy(acls1->rule, acl3);
                    390:                    while ((*acls != NULL) && ((*acls)->number < acls1->number))
                    391:                      acls = &((*acls)->next);
                    392: 
                    393:                    if (*acls == NULL) {
                    394:                      acls1->next = NULL;
                    395:                    } else if (((*acls)->number == acls1->number) &&
                    396:                        (res != RAD_MPD_TABLE) &&
                    397:                        (res != RAD_MPD_TABLE_STATIC)) {
                    398:                      Log(LG_ERR, ("radsrv: Duplicate acl"));
                    399:                      Freee(acls1);
                    400:                      free(acl);
                    401:                      break;
                    402:                    } else {
                    403:                      acls1->next = *acls;
                    404:                    }
                    405:                    *acls = acls1;
                    406: 
                    407:                    free(acl);
                    408:                    break;
                    409: #endif /* USE_NG_BPF or USE_IPFW */
                    410: 
                    411:                  default:
                    412:                    Log(LG_RADIUS2, ("radsrv: Dropping vendor %d attribute: %d ", 
                    413:                      vendor, res));
                    414:                    break;
                    415:                }
                    416:                break;
                    417:            default:
                    418:                Log(LG_RADIUS2, ("radsrv: Unknown attribute: %d ", 
                    419:                    res));
                    420:                break;
                    421:        }
                    422:     }
                    423:     err = 0;
                    424:     if (w->addr.u.ip4.s_addr != 0 && nas_ip.s_addr != -1 && w->addr.u.ip4.s_addr != nas_ip.s_addr) {
                    425:         Log(LG_ERR, ("radsrv: incorrect NAS-IP-Address"));
                    426:        err = 403;
                    427:     } else if (anysesid == 0) {
                    428:         Log(LG_ERR, ("radsrv: request without session identification"));
                    429:        err = 402;
                    430:     } else if (serv_type != 0) {
                    431:         Log(LG_ERR, ("radsrv: Service-Type attribute not supported"));
                    432:        err = 405;
                    433:     }
                    434:     if (err) {
                    435:        if (result == RAD_DISCONNECT_REQUEST)
                    436:            rad_create_response(w->handle, RAD_DISCONNECT_NAK);
                    437:        else
                    438:            rad_create_response(w->handle, RAD_COA_NAK);
                    439:         rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
                    440:        if (state != NULL)
                    441:            rad_put_attr(w->handle, RAD_STATE, state, state_len);
                    442:        if (authentic)
                    443:            rad_put_message_authentic(w->handle);
                    444:        rad_send_response(w->handle);
                    445:        goto cleanup;
                    446:     }
                    447:     found = 0;
                    448:     err = 503;
                    449:     for (l = 0; l < gNumLinks; l++) {
                    450:        if ((L = gLinks[l]) != NULL) {
                    451:            B = L->bund;
                    452:            if (nasport != -1 && nasport != l)
                    453:                continue;
                    454:            if (sesid && strcmp(sesid, L->session_id))
                    455:                continue;
                    456:            if (link && strcmp(link, L->name))
                    457:                continue;
                    458:            if (msesid && strcmp(msesid, L->msession_id))
                    459:                continue;
                    460:            if (username && strcmp(username, L->lcp.auth.params.authname))
                    461:                continue;
                    462:            if (called && !PhysGetCalledNum(L, buf, sizeof(buf)) &&
                    463:                    strcmp(called, buf))
                    464:                continue;
                    465:            if (calling && !PhysGetCallingNum(L, buf, sizeof(buf)) &&
                    466:                    strcmp(calling, buf))
                    467:                continue;
                    468:            if (bundle && (!B || strcmp(bundle, B->name)))
                    469:                continue;
                    470:            if (iface && (!B || strcmp(iface, B->iface.ifname)))
                    471:                continue;
                    472:            if (ifindex >= 0 && (!B || ifindex != B->iface.ifindex))
                    473:                continue;
                    474:            if (ip.s_addr != -1 && (!B ||
                    475:                    ip.s_addr != B->iface.peer_addr.u.ip4.s_addr))
                    476:                continue;
                    477:                
                    478:            Log(LG_RADIUS2, ("radsrv: Matched link: %s",
                    479:                L->name));
                    480:            if (L->tmpl) {
                    481:                Log(LG_ERR, ("radsrv: Impossible to affect template"));
                    482:                err = 504;
                    483:                continue;
                    484:            }
                    485:            found++;
                    486:            
                    487:            if (result == RAD_DISCONNECT_REQUEST) {
                    488:                RecordLinkUpDownReason(NULL, L, 0, STR_MANUALLY, NULL);
                    489:                LinkClose(L);
                    490:            } else { /* CoA */
                    491:                if (B && B->iface.up && !B->iface.dod) {
                    492:                    if (B->iface.ip_up)
                    493:                        IfaceIpIfaceDown(B);
                    494:                    if (B->iface.ipv6_up)
                    495:                        IfaceIpv6IfaceDown(B);
                    496:                    IfaceDown(B);
                    497:                }
                    498: #ifdef USE_IPFW
                    499:                ACLDestroy(L->lcp.auth.params.acl_rule);
                    500:                ACLDestroy(L->lcp.auth.params.acl_pipe);
                    501:                ACLDestroy(L->lcp.auth.params.acl_queue);
                    502:                ACLDestroy(L->lcp.auth.params.acl_table);
                    503:                L->lcp.auth.params.acl_rule = NULL;
                    504:                L->lcp.auth.params.acl_pipe = NULL;
                    505:                L->lcp.auth.params.acl_queue = NULL;
                    506:                L->lcp.auth.params.acl_table = NULL;
                    507:                ACLCopy(acl_rule, &L->lcp.auth.params.acl_rule);
                    508:                ACLCopy(acl_pipe, &L->lcp.auth.params.acl_pipe);
                    509:                ACLCopy(acl_queue, &L->lcp.auth.params.acl_queue);
                    510:                ACLCopy(acl_table, &L->lcp.auth.params.acl_table);
                    511: #endif /* USE_IPFW */
                    512: #ifdef USE_NG_BPF
                    513:                for (i = 0; i < ACL_FILTERS; i++) {
                    514:                    ACLDestroy(L->lcp.auth.params.acl_filters[i]);
                    515:                    L->lcp.auth.params.acl_filters[i] = NULL;
                    516:                    ACLCopy(acl_filters[i], &L->lcp.auth.params.acl_filters[i]);
                    517:                }
                    518:                for (i = 0; i < ACL_DIRS; i++) {
                    519:                    ACLDestroy(L->lcp.auth.params.acl_limits[i]);
                    520:                    L->lcp.auth.params.acl_limits[i] = NULL;
                    521:                    ACLCopy(acl_limits[i], &L->lcp.auth.params.acl_limits[i]);
                    522:                }
                    523:                strcpy(L->lcp.auth.params.std_acct[0], std_acct[0]);
                    524:                strcpy(L->lcp.auth.params.std_acct[1], std_acct[1]);
                    525: #endif
                    526:                if (session_timeout != -1)
                    527:                    L->lcp.auth.params.session_timeout = session_timeout;
                    528:                if (idle_timeout != -1)
                    529:                    L->lcp.auth.params.idle_timeout = idle_timeout;
                    530:                if (acct_update != -1) {
                    531:                    L->lcp.auth.params.acct_update = acct_update;
                    532:                    /* Stop accounting update timer if running. */
                    533:                    TimerStop(&L->lcp.auth.acct_timer);
                    534:                    if (B) {
                    535:                        /* Start accounting update timer if needed. */
                    536:                        u_int   updateInterval;
                    537:                        if (L->lcp.auth.params.acct_update > 0)
                    538:                            updateInterval = L->lcp.auth.params.acct_update;
                    539:                        else
                    540:                            updateInterval = L->lcp.auth.conf.acct_update;
                    541:                        if (updateInterval > 0) {
                    542:                            TimerInit(&L->lcp.auth.acct_timer, "AuthAccountTimer",
                    543:                                updateInterval * SECONDS, AuthAccountTimeout, L);
                    544:                            TimerStartRecurring(&L->lcp.auth.acct_timer);
                    545:                        }
                    546:                    }
                    547:                }
                    548:                if (B && B->iface.up && !B->iface.dod) {
                    549:                    authparamsDestroy(&B->params);
                    550:                    authparamsCopy(&L->lcp.auth.params,&B->params);
                    551:                    if (B->iface.ip_up)
                    552:                        IfaceIpIfaceUp(B, 1);
                    553:                    if (B->iface.ipv6_up)
                    554:                        IfaceIpv6IfaceUp(B, 1);
                    555:                    IfaceUp(B, 1);
                    556:                }
                    557:            }
                    558:        }
                    559:     }
                    560:     if (result == RAD_DISCONNECT_REQUEST) {
                    561:        if (found) {
                    562:            rad_create_response(w->handle, RAD_DISCONNECT_ACK);
                    563:        } else {
                    564:            rad_create_response(w->handle, RAD_DISCONNECT_NAK);
                    565:            rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
                    566:        }
                    567:     } else {
                    568:        if (found) {
                    569:            rad_create_response(w->handle, RAD_COA_ACK);
                    570:        } else {
                    571:            rad_create_response(w->handle, RAD_COA_NAK);
                    572:            rad_put_int(w->handle, RAD_ERROR_CAUSE, err);
                    573:        }
                    574:     }
                    575:     if (state != NULL)
                    576:         rad_put_attr(w->handle, RAD_STATE, state, state_len);
                    577:     if (authentic)
                    578:        rad_put_message_authentic(w->handle);
                    579:     rad_send_response(w->handle);
                    580: 
                    581: cleanup:
                    582:     if (username)
                    583:        free(username);
                    584:     if (called)
                    585:        free(called);
                    586:     if (calling)
                    587:        free(calling);
                    588:     if (sesid)
                    589:        free(sesid);
                    590:     if (msesid)
                    591:        free(msesid);
                    592:     if (link)
                    593:        free(link);
                    594:     if (bundle)
                    595:        free(bundle);
                    596:     if (iface)
                    597:        free(iface);
                    598:     if (state != NULL)
                    599:        Freee(state);
                    600: #ifdef USE_IPFW
                    601:     ACLDestroy(acl_rule);
                    602:     ACLDestroy(acl_pipe);
                    603:     ACLDestroy(acl_queue);
                    604:     ACLDestroy(acl_table);
                    605: #endif /* USE_IPFW */
                    606: #ifdef USE_NG_BPF
                    607:     for (i = 0; i < ACL_FILTERS; i++)
                    608:        ACLDestroy(acl_filters[i]);
                    609:     for (i = 0; i < ACL_DIRS; i++)
                    610:        ACLDestroy(acl_limits[i]);
                    611: #endif /* USE_NG_BPF */
                    612: }
                    613: 
                    614: /*
                    615:  * RadsrvOpen()
                    616:  */
                    617: 
                    618: int
                    619: RadsrvOpen(Radsrv w)
                    620: {
                    621:     char               addrstr[INET6_ADDRSTRLEN];
                    622:     struct sockaddr_in sin;
                    623:     struct radiusclient_conf *s;
                    624: 
                    625:     if (w->handle) {
                    626:        Log(LG_ERR, ("radsrv: radsrv already running"));
                    627:        return (-1);
                    628:     }
                    629: 
                    630:     if ((w->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
                    631:        Perror("%s: Cannot create socket", __FUNCTION__);
                    632:        return (-1);
                    633:     }
                    634:     memset(&sin, 0, sizeof sin);
                    635:     sin.sin_len = sizeof sin;
                    636:     sin.sin_family = AF_INET;
                    637:     sin.sin_addr = w->addr.u.ip4;
                    638:     sin.sin_port = htons(w->port);
                    639:     if (bind(w->fd, (const struct sockaddr *)&sin,
                    640:            sizeof sin) == -1) {
                    641:        Log(LG_ERR, ("%s: bind: %s", __FUNCTION__, strerror(errno)));
                    642:        close(w->fd);
                    643:        w->fd = -1;
                    644:        return (-1);
                    645:     }
                    646: 
                    647:     if (!(w->handle = rad_server_open(w->fd))) {
                    648:        Log(LG_ERR, ("%s: rad_server_open error", __FUNCTION__));
                    649:        close(w->fd);
                    650:        w->fd = -1;
                    651:        return(-1);
                    652:     }
                    653: 
                    654:     EventRegister(&w->event, EVENT_READ, w->fd,
                    655:        EVENT_RECURRING, RadsrvEvent, w);
                    656: 
                    657:     s = w->clients;
                    658:     while (s) {
                    659:        Log(LG_RADIUS2, ("radsrv: Adding client %s", s->hostname));
                    660:        if (rad_add_server (w->handle, s->hostname,
                    661:                0, s->sharedsecret, 0, 0) == -1) {
                    662:                Log(LG_RADIUS, ("radsrv: Adding client error: %s",
                    663:                    rad_strerror(w->handle)));
                    664:        }
                    665:        s = s->next;
                    666:     }
                    667: 
                    668:     Log(LG_ERR, ("radsrv: listening on %s %d", 
                    669:        u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port));
                    670:     return (0);
                    671: }
                    672: 
                    673: /*
                    674:  * RadsrvClose()
                    675:  */
                    676: 
                    677: int
                    678: RadsrvClose(Radsrv w)
                    679: {
                    680: 
                    681:     if (!w->handle) {
                    682:        Log(LG_ERR, ("radsrv: radsrv is not running"));
                    683:        return (-1);
                    684:     }
                    685:     EventUnRegister(&w->event);
                    686:     rad_close(w->handle);
                    687:     w->handle = NULL;
                    688: 
                    689:     Log(LG_ERR, ("radsrv: stop listening"));
                    690:     return (0);
                    691: }
                    692: 
                    693: /*
                    694:  * RadsrvStat()
                    695:  */
                    696: 
                    697: int
                    698: RadsrvStat(Context ctx, int ac, char *av[], void *arg)
                    699: {
                    700:     Radsrv     w = &gRadsrv;
                    701:     char       addrstr[64];
                    702:     struct radiusclient_conf *client;
                    703: 
                    704:     Printf("Radsrv configuration:\r\n");
                    705:     Printf("\tState         : %s\r\n", w->handle ? "OPENED" : "CLOSED");
                    706:     Printf("\tSelf          : %s %d\r\n",
                    707:        u_addrtoa(&w->addr,addrstr,sizeof(addrstr)), w->port);
                    708:     Printf("\tPeer:\r\n");
                    709:     client = w->clients;
                    710:     while (client) {
                    711:       Printf("\t  %s ********\r\n", client->hostname);
                    712:       client = client->next;
                    713:     }
                    714:     Printf("Radsrv options:\r\n");
                    715:     OptStat(ctx, &w->options, gConfList);
                    716: 
                    717:     return (0);
                    718: }
                    719: 
                    720: /*
                    721:  * RadsrvSetCommand()
                    722:  */
                    723: 
                    724: static int
                    725: RadsrvSetCommand(Context ctx, int ac, char *av[], void *arg) 
                    726: {
                    727:     Radsrv      w = &gRadsrv;
                    728:     int                port, count;
                    729:     struct radiusclient_conf *peer, *t_peer;
                    730: 
                    731:   switch ((intptr_t)arg) {
                    732: 
                    733:     case SET_OPEN:
                    734:       RadsrvOpen(w);
                    735:       break;
                    736: 
                    737:     case SET_CLOSE:
                    738:       RadsrvClose(w);
                    739:       break;
                    740: 
                    741:     case SET_ENABLE:
                    742:        EnableCommand(ac, av, &w->options, gConfList);
                    743:       break;
                    744: 
                    745:     case SET_DISABLE:
                    746:        DisableCommand(ac, av, &w->options, gConfList);
                    747:       break;
                    748: 
                    749:     case SET_SELF:
                    750:       if (ac < 1 || ac > 2)
                    751:        return(-1);
                    752: 
                    753:       if (!ParseAddr(av[0],&w->addr, ALLOW_IPV4)) 
                    754:        Error("Bogus IP address given %s", av[0]);
                    755: 
                    756:       if (ac == 2) {
                    757:         port =  strtol(av[1], NULL, 10);
                    758:         if (port < 1 || port > 65535)
                    759:            Error("Bogus port given %s", av[1]);
                    760:         w->port=port;
                    761:       }
                    762:       break;
                    763: 
                    764:     case SET_PEER:
                    765:        if (ac != 2)
                    766:          return(-1);
                    767: 
                    768:        count = 0;
                    769:        for ( t_peer = w->clients ; t_peer ;
                    770:          t_peer = t_peer->next) {
                    771:          count++;
                    772:        }
                    773:        if (count > RADSRV_MAX_SERVERS) {
                    774:          Error("cannot configure more than %d peers",
                    775:            RADSRV_MAX_SERVERS);
                    776:        }
                    777:        if (strlen(av[0]) > MAXHOSTNAMELEN-1)
                    778:            Error("Hostname too long. > %d char.", MAXHOSTNAMELEN-1);
                    779:        if (strlen(av[1]) > 127)
                    780:            Error("Shared Secret too long. > 127 char.");
                    781: 
                    782:        peer = Malloc(MB_RADSRV, sizeof(*peer));
                    783:        peer->hostname = Mstrdup(MB_RADSRV, av[0]);
                    784:        peer->sharedsecret = Mstrdup(MB_RADSRV, av[1]);
                    785:        peer->next = w->clients;
                    786:        w->clients = peer;
                    787:        break;
                    788: 
                    789:     default:
                    790:       return(-1);
                    791: 
                    792:   }
                    793: 
                    794:   return 0;
                    795: }
                    796: 
                    797: #endif

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