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

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

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