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

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

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