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

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

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