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

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

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