Annotation of embedaddon/mpd/src/eap.c, revision 1.1
1.1 ! misho 1: /*
! 2: * See ``COPYRIGHT.mpd''
! 3: *
! 4: * $Id: eap.c,v 1.34 2008/10/30 11:41:39 amotin Exp $
! 5: *
! 6: */
! 7:
! 8: #include "ppp.h"
! 9: #include "radius.h"
! 10: #include "auth.h"
! 11: #include "ngfunc.h"
! 12:
! 13: /*
! 14: * INTERNAL FUNCTIONS
! 15: */
! 16:
! 17: static void EapSendRequest(Link l, u_char type);
! 18: static void EapSendNak(Link l, u_char id, u_char type);
! 19: static void EapSendIdentRequest(Link l);
! 20: static void EapIdentTimeout(void *ptr);
! 21: static char EapTypeSupported(u_char type);
! 22: static void EapRadiusProxy(Link l, AuthData auth, const u_char *pkt, u_short len);
! 23: static void EapRadiusProxyFinish(Link l, AuthData auth);
! 24: static void EapRadiusSendMsg(void *ptr);
! 25: static void EapRadiusSendMsgTimeout(void *ptr);
! 26: static int EapSetCommand(Context ctx, int ac, char *av[], void *arg);
! 27:
! 28: /* Set menu options */
! 29: enum {
! 30: SET_ACCEPT,
! 31: SET_DENY,
! 32: SET_ENABLE,
! 33: SET_DISABLE,
! 34: SET_YES,
! 35: SET_NO
! 36: };
! 37:
! 38: /*
! 39: * GLOBAL VARIABLES
! 40: */
! 41:
! 42: const struct cmdtab EapSetCmds[] = {
! 43: { "accept [opt ...]", "Accept option",
! 44: EapSetCommand, NULL, 2, (void *) SET_ACCEPT },
! 45: { "deny [opt ...]", "Deny option",
! 46: EapSetCommand, NULL, 2, (void *) SET_DENY },
! 47: { "enable [opt ...]", "Enable option",
! 48: EapSetCommand, NULL, 2, (void *) SET_ENABLE },
! 49: { "disable [opt ...]", "Disable option",
! 50: EapSetCommand, NULL, 2, (void *) SET_DISABLE },
! 51: { "yes [opt ...]", "Enable and accept option",
! 52: EapSetCommand, NULL, 2, (void *) SET_YES },
! 53: { "no [opt ...]", "Disable and deny option",
! 54: EapSetCommand, NULL, 2, (void *) SET_NO },
! 55: { NULL },
! 56: };
! 57:
! 58: /*
! 59: * INTERNAL VARIABLES
! 60: */
! 61:
! 62: static struct confinfo gConfList[] = {
! 63: { 0, EAP_CONF_RADIUS, "radius-proxy" },
! 64: { 1, EAP_CONF_MD5, "md5" },
! 65: { 0, 0, NULL },
! 66: };
! 67:
! 68:
! 69:
! 70: /*
! 71: * EapInit()
! 72: */
! 73:
! 74: void
! 75: EapInit(Link l)
! 76: {
! 77: EapInfo eap = &l->lcp.auth.eap;
! 78:
! 79: Disable(&eap->conf.options, EAP_CONF_MD5);
! 80: Accept(&eap->conf.options, EAP_CONF_MD5);
! 81: }
! 82:
! 83: /*
! 84: * EapStart()
! 85: */
! 86:
! 87: void
! 88: EapStart(Link l, int which)
! 89: {
! 90: Auth a = &l->lcp.auth;
! 91: EapInfo eap = &l->lcp.auth.eap;
! 92: int i;
! 93:
! 94: for (i = 0; i < EAP_NUM_TYPES; i++)
! 95: eap->peer_types[i] = eap->want_types[i] = 0;
! 96:
! 97: /* fill a list of requestable auth types */
! 98: if (Enabled(&eap->conf.options, EAP_CONF_MD5))
! 99: eap->want_types[0] = EAP_TYPE_MD5CHAL;
! 100:
! 101: /* fill a list of acceptable auth types */
! 102: if (Acceptable(&eap->conf.options, EAP_CONF_MD5))
! 103: eap->peer_types[0] = EAP_TYPE_MD5CHAL;
! 104:
! 105: if (l->originate == LINK_ORIGINATE_LOCAL)
! 106: a->params.msoft.chap_alg = a->self_to_peer_alg;
! 107: else
! 108: a->params.msoft.chap_alg = a->peer_to_self_alg;
! 109:
! 110: switch (which) {
! 111: case AUTH_PEER_TO_SELF:
! 112:
! 113: /* Initialize retry counter and timer */
! 114: eap->next_id = 1;
! 115: eap->retry = AUTH_RETRIES;
! 116:
! 117: TimerInit(&eap->reqTimer, "EapRadiusSendMsgTimer",
! 118: l->conf.retry_timeout * SECONDS, EapRadiusSendMsgTimeout, (void *) l);
! 119:
! 120: TimerInit(&eap->identTimer, "EapTimer",
! 121: l->conf.retry_timeout * SECONDS, EapIdentTimeout, (void *) l);
! 122: TimerStart(&eap->identTimer);
! 123:
! 124: /* Send first request
! 125: * Send the request even, if the Radius-Eap-Proxy feature is active,
! 126: * this saves on roundtrip.
! 127: */
! 128: EapSendIdentRequest(l);
! 129: break;
! 130:
! 131: case AUTH_SELF_TO_PEER: /* Just wait for authenitcaor's request */
! 132: break;
! 133:
! 134: default:
! 135: assert(0);
! 136: }
! 137: }
! 138:
! 139: /*
! 140: * EapStop()
! 141: */
! 142:
! 143: void
! 144: EapStop(EapInfo eap)
! 145: {
! 146: TimerStop(&eap->identTimer);
! 147: TimerStop(&eap->reqTimer);
! 148: }
! 149:
! 150: /*
! 151: * EapSendRequest()
! 152: *
! 153: * Send an EAP request to peer.
! 154: */
! 155:
! 156: static void
! 157: EapSendRequest(Link l, u_char type)
! 158: {
! 159: Auth const a = &l->lcp.auth;
! 160: EapInfo const eap = &a->eap;
! 161: ChapInfo const chap = &a->chap;
! 162: ChapParams const cp = &a->params.chap;
! 163: int i = 0;
! 164: u_char req_type = 0;
! 165:
! 166: if (type == 0) {
! 167: for (i = 0; i < EAP_NUM_TYPES; i++) {
! 168: if (eap->want_types[i] != 0) {
! 169: req_type = eap->want_types[i];
! 170: break;
! 171: }
! 172: }
! 173: } else {
! 174: req_type = type;
! 175: }
! 176:
! 177: if (req_type == 0) {
! 178: Log(LG_AUTH, ("[%s] EAP: ran out of EAP Types", l->name));
! 179: AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
! 180: return;
! 181: }
! 182:
! 183: /* don't request this type again */
! 184: eap->want_types[i] = 0;
! 185:
! 186: switch (req_type) {
! 187: case EAP_TYPE_MD5CHAL:
! 188:
! 189: /* Invalidate any old challenge data */
! 190: cp->chal_len = 0;
! 191: /* Initialize retry counter and timer */
! 192: chap->next_id = 1;
! 193: chap->retry = AUTH_RETRIES;
! 194: chap->proto = PROTO_EAP;
! 195: a->peer_to_self_alg = CHAP_ALG_MD5;
! 196:
! 197: TimerInit(&chap->chalTimer, "ChalTimer",
! 198: l->conf.retry_timeout * SECONDS, ChapChalTimeout, l);
! 199: TimerStart(&chap->chalTimer);
! 200:
! 201: /* Send first challenge */
! 202: ChapSendChallenge(l);
! 203: break;
! 204:
! 205: default:
! 206: Log(LG_AUTH, ("[%s] EAP: Type %d is currently un-implemented",
! 207: l->name, eap->want_types[i]));
! 208: AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
! 209: }
! 210:
! 211: return;
! 212: }
! 213:
! 214: /*
! 215: * EapSendNak()
! 216: *
! 217: * Send an EAP Nak to peer.
! 218: */
! 219:
! 220: static void
! 221: EapSendNak(Link l, u_char id, u_char type)
! 222: {
! 223: Auth const a = &l->lcp.auth;
! 224: EapInfo const eap = &a->eap;
! 225: int i = 0;
! 226: u_char nak_type = 0;
! 227:
! 228: for (i = 0; i < EAP_NUM_TYPES; i++) {
! 229: if (eap->peer_types[i] != 0) {
! 230: nak_type = eap->peer_types[i];
! 231: break;
! 232: }
! 233: }
! 234:
! 235: if (nak_type == 0) {
! 236: Log(LG_AUTH, ("[%s] EAP: ran out of EAP Types", l->name));
! 237: AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
! 238: return;
! 239: }
! 240:
! 241: /* don't nak this proto again */
! 242: eap->peer_types[i] = 0;
! 243:
! 244: AuthOutput(l, PROTO_EAP, EAP_RESPONSE, id, &nak_type, 1, 0, EAP_TYPE_NAK);
! 245: return;
! 246: }
! 247:
! 248: /*
! 249: * EapSendIdentRequest()
! 250: *
! 251: * Send an Ident Request to the peer.
! 252: */
! 253:
! 254: static void
! 255: EapSendIdentRequest(Link l)
! 256: {
! 257: EapInfo const eap = &l->lcp.auth.eap;
! 258:
! 259: /* Send the initial Identity request */
! 260: AuthOutput(l, PROTO_EAP, EAP_REQUEST, eap->next_id++, NULL, 0, 0, EAP_TYPE_IDENT);
! 261: }
! 262:
! 263: /*
! 264: * EapInput()
! 265: *
! 266: * Accept an incoming EAP packet
! 267: */
! 268:
! 269: void
! 270: EapInput(Link l, AuthData auth, const u_char *pkt, u_short len)
! 271: {
! 272: Auth const a = &l->lcp.auth;
! 273: EapInfo const eap = &a->eap;
! 274: int data_len = len - 1, i, acc_type;
! 275: u_char *data = NULL, type = 0;
! 276:
! 277: if (pkt != NULL) {
! 278: data = data_len > 0 ? (u_char *) &pkt[1] : NULL;
! 279: type = pkt[0];
! 280: }
! 281:
! 282: if (Enabled(&eap->conf.options, EAP_CONF_RADIUS)) {
! 283: EapRadiusProxy(l, auth, pkt, len);
! 284: return;
! 285: }
! 286:
! 287: switch (auth->code) {
! 288: case EAP_REQUEST:
! 289: switch (type) {
! 290: case EAP_TYPE_IDENT:
! 291: AuthOutput(l, PROTO_EAP, EAP_RESPONSE, auth->id, (u_char *) auth->conf.authname,
! 292: strlen(auth->conf.authname), 0, EAP_TYPE_IDENT);
! 293: break;
! 294:
! 295: case EAP_TYPE_NAK:
! 296: case EAP_TYPE_NOTIF:
! 297: Log(LG_AUTH, ("[%s] EAP: Type %s is invalid in Request messages",
! 298: l->name, EapType(type)));
! 299: AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
! 300: break;
! 301:
! 302: /* deal with Auth Types */
! 303: default:
! 304: acc_type = 0;
! 305: if (EapTypeSupported(type)) {
! 306: for (i = 0; i < EAP_NUM_TYPES; i++) {
! 307: if (eap->peer_types[i] == type) {
! 308: acc_type = eap->peer_types[i];
! 309: break;
! 310: }
! 311: }
! 312:
! 313: if (acc_type == 0) {
! 314: Log(LG_AUTH, ("[%s] EAP: Type %s not acceptable", l->name,
! 315: EapType(type)));
! 316: EapSendNak(l, auth->id, type);
! 317: break;
! 318: }
! 319:
! 320: switch (type) {
! 321: case EAP_TYPE_MD5CHAL:
! 322: a->self_to_peer_alg = CHAP_ALG_MD5;
! 323: auth->code = CHAP_CHALLENGE;
! 324: ChapInput(l, auth, &pkt[1], len - 1);
! 325: return;
! 326:
! 327: default:
! 328: assert(0);
! 329: }
! 330: } else {
! 331: Log(LG_AUTH, ("[%s] EAP: Type %s not supported", l->name, EapType(type)));
! 332: EapSendNak(l, auth->id, type);
! 333: }
! 334: }
! 335: break;
! 336:
! 337: case EAP_RESPONSE:
! 338: switch (type) {
! 339: case EAP_TYPE_IDENT:
! 340: TimerStop(&eap->identTimer);
! 341: Log(LG_AUTH, ("[%s] EAP: Identity:%*.*s",
! 342: l->name, data_len, data_len, data));
! 343: EapSendRequest(l, 0);
! 344: break;
! 345:
! 346: case EAP_TYPE_NOTIF:
! 347: Log(LG_AUTH, ("[%s] EAP: Notify:%*.*s ", l->name,
! 348: data_len, data_len, data));
! 349: break;
! 350:
! 351: case EAP_TYPE_NAK:
! 352: Log(LG_AUTH, ("[%s] EAP: Nak desired Type %s ", l->name,
! 353: EapType(data[0])));
! 354: if (EapTypeSupported(data[0]))
! 355: EapSendRequest(l, data[0]);
! 356: else
! 357: EapSendRequest(l, 0);
! 358: break;
! 359:
! 360: case EAP_TYPE_MD5CHAL:
! 361: auth->code = CHAP_RESPONSE;
! 362: ChapInput(l, auth, &pkt[1], len - 1);
! 363: return;
! 364:
! 365: default:
! 366: Log(LG_AUTH, ("[%s] EAP: unknown type %d", l->name, type));
! 367: AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
! 368: }
! 369: break;
! 370:
! 371: case EAP_SUCCESS:
! 372: AuthFinish(l, AUTH_SELF_TO_PEER, TRUE);
! 373: break;
! 374:
! 375: case EAP_FAILURE:
! 376: AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
! 377: break;
! 378:
! 379: default:
! 380: Log(LG_AUTH, ("[%s] EAP: unknown code %d", l->name, auth->code));
! 381: AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
! 382: }
! 383: AuthDataDestroy(auth);
! 384: }
! 385:
! 386: /*
! 387: * EapRadiusProxy()
! 388: *
! 389: * Proxy EAP Requests from/to the RADIUS server
! 390: */
! 391:
! 392: static void
! 393: EapRadiusProxy(Link l, AuthData auth, const u_char *pkt, u_short len)
! 394: {
! 395: int data_len = len - 1;
! 396: u_char *data = NULL, type = 0;
! 397: Auth const a = &l->lcp.auth;
! 398: EapInfo const eap = &a->eap;
! 399: struct fsmheader lh;
! 400:
! 401: Log(LG_AUTH, ("[%s] EAP: Proxying packet to RADIUS", l->name));
! 402:
! 403: if (pkt != NULL) {
! 404: data = data_len > 0 ? (u_char *) &pkt[1] : NULL;
! 405: type = pkt[0];
! 406: }
! 407:
! 408: if (auth->code == EAP_RESPONSE && type == EAP_TYPE_IDENT) {
! 409: TimerStop(&eap->identTimer);
! 410: if (data_len >= AUTH_MAX_AUTHNAME) {
! 411: Log(LG_AUTH, ("[%s] EAP: Identity to big (%d), truncating",
! 412: l->name, data_len));
! 413: data_len = AUTH_MAX_AUTHNAME - 1;
! 414: }
! 415: memset(eap->identity, 0, sizeof(eap->identity));
! 416: strncpy(eap->identity, (char *) data, data_len);
! 417: Log(LG_AUTH, ("[%s] EAP: Identity: %s", l->name, eap->identity));
! 418: }
! 419:
! 420: TimerStop(&eap->reqTimer);
! 421:
! 422: /* prepare packet */
! 423: lh.code = auth->code;
! 424: lh.id = auth->id;
! 425: lh.length = htons(len + sizeof(lh));
! 426:
! 427: auth->params.eapmsg = Malloc(MB_AUTH, len + sizeof(lh));
! 428: memcpy(auth->params.eapmsg, &lh, sizeof(lh));
! 429: memcpy(&auth->params.eapmsg[sizeof(lh)], pkt, len);
! 430:
! 431: auth->params.eapmsg_len = len + sizeof(lh);
! 432: strlcpy(auth->params.authname, eap->identity, sizeof(auth->params.authname));
! 433:
! 434: auth->eap_radius = TRUE;
! 435:
! 436: auth->finish = EapRadiusProxyFinish;
! 437: AuthAsyncStart(l, auth);
! 438:
! 439: }
! 440:
! 441: /*
! 442: * RadiusEapProxyFinish()
! 443: *
! 444: * Return point from the asynch RADIUS EAP Proxy Handler.
! 445: *
! 446: */
! 447:
! 448: static void
! 449: EapRadiusProxyFinish(Link l, AuthData auth)
! 450: {
! 451: Auth const a = &l->lcp.auth;
! 452: EapInfo eap = &a->eap;
! 453:
! 454: Log(LG_AUTH, ("[%s] EAP: RADIUS return status: %s",
! 455: l->name, AuthStatusText(auth->status)));
! 456:
! 457: /* this shouldn't happen normally, however be liberal */
! 458: if (a->params.eapmsg == NULL) {
! 459: struct fsmheader lh;
! 460:
! 461: Log(LG_AUTH, ("[%s] EAP: Warning, rec'd empty EAP-Message",
! 462: l->name));
! 463: /* prepare packet */
! 464: lh.code = auth->status == AUTH_STATUS_SUCCESS ? EAP_SUCCESS : EAP_FAILURE;
! 465: lh.id = auth->id;
! 466: lh.length = htons(sizeof(lh));
! 467:
! 468: a->params.eapmsg = Mdup(MB_AUTH, &lh, sizeof(lh));
! 469: a->params.eapmsg_len = sizeof(lh);
! 470: }
! 471:
! 472: if (a->params.eapmsg != NULL) {
! 473: eap->retry = AUTH_RETRIES;
! 474:
! 475: EapRadiusSendMsg(l);
! 476: if (auth->status == AUTH_STATUS_UNDEF)
! 477: TimerStart(&eap->reqTimer);
! 478: }
! 479:
! 480: if (auth->status == AUTH_STATUS_FAIL) {
! 481: AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
! 482: } else if (auth->status == AUTH_STATUS_SUCCESS) {
! 483: AuthFinish(l, AUTH_PEER_TO_SELF, TRUE);
! 484: }
! 485:
! 486: AuthDataDestroy(auth);
! 487: }
! 488:
! 489: /*
! 490: * EapRadiusSendMsg()
! 491: *
! 492: * Send an EAP Message to the peer
! 493: */
! 494:
! 495: static void
! 496: EapRadiusSendMsg(void *ptr)
! 497: {
! 498: Mbuf bp;
! 499: Link l = (Link)ptr;
! 500: Auth const a = &l->lcp.auth;
! 501: FsmHeader const f = (FsmHeader)a->params.eapmsg;
! 502: char buf[32];
! 503:
! 504: if (a->params.eapmsg_len > 4) {
! 505: Log(LG_AUTH, ("[%s] EAP: send %s #%d len: %d, type: %s",
! 506: l->name, EapCode(f->code, buf, sizeof(buf)), f->id, htons(f->length),
! 507: EapType(a->params.eapmsg[4])));
! 508: } else {
! 509: Log(LG_AUTH, ("[%s] EAP: send %s #%d len: %d",
! 510: l->name, EapCode(f->code, buf, sizeof(buf)), f->id, htons(f->length)));
! 511: }
! 512:
! 513: bp = mbcopyback(NULL, 0, a->params.eapmsg, a->params.eapmsg_len);
! 514: NgFuncWritePppFrameLink(l, PROTO_EAP, bp);
! 515: }
! 516:
! 517: /*
! 518: * EapRadiusSendMsgTimeout()
! 519: *
! 520: * Timer expired for reply to our request
! 521: */
! 522:
! 523: static void
! 524: EapRadiusSendMsgTimeout(void *ptr)
! 525: {
! 526: Link l = (Link)ptr;
! 527: EapInfo const eap = &l->lcp.auth.eap;
! 528:
! 529: if (--eap->retry > 0) {
! 530: TimerStart(&eap->reqTimer);
! 531: EapRadiusSendMsg(l);
! 532: }
! 533: }
! 534:
! 535: /*
! 536: * EapIdentTimeout()
! 537: *
! 538: * Timer expired for reply to our request
! 539: */
! 540:
! 541: static void
! 542: EapIdentTimeout(void *ptr)
! 543: {
! 544: Link l = (Link)ptr;
! 545: EapInfo const eap = &l->lcp.auth.eap;
! 546:
! 547: if (--eap->retry > 0) {
! 548: TimerStart(&eap->identTimer);
! 549: EapSendIdentRequest(l);
! 550: }
! 551: }
! 552:
! 553: /*
! 554: * EapStat()
! 555: */
! 556:
! 557: int
! 558: EapStat(Context ctx, int ac, char *av[], void *arg)
! 559: {
! 560: EapInfo const eap = &ctx->lnk->lcp.auth.eap;
! 561:
! 562: Printf("\tIdentity : %s\r\n", eap->identity);
! 563: Printf("EAP options\r\n");
! 564: OptStat(ctx, &eap->conf.options, gConfList);
! 565:
! 566: return (0);
! 567: }
! 568:
! 569: /*
! 570: * EapCode()
! 571: */
! 572:
! 573: const char *
! 574: EapCode(u_char code, char *buf, size_t len)
! 575: {
! 576: switch (code) {
! 577: case EAP_REQUEST:
! 578: strlcpy(buf, "REQUEST", len);
! 579: break;
! 580: case EAP_RESPONSE:
! 581: strlcpy(buf, "RESPONSE", len);
! 582: break;
! 583: case EAP_SUCCESS:
! 584: strlcpy(buf, "SUCCESS", len);
! 585: break;
! 586: case EAP_FAILURE:
! 587: strlcpy(buf, "FAILURE", len);
! 588: break;
! 589: default:
! 590: snprintf(buf, len, "code%d", code);
! 591: }
! 592: return(buf);
! 593: }
! 594:
! 595: /*
! 596: * EapType()
! 597: */
! 598:
! 599: const char *
! 600: EapType(u_char type)
! 601: {
! 602: switch (type) {
! 603: case EAP_TYPE_IDENT:
! 604: return("Identity");
! 605: case EAP_TYPE_NOTIF:
! 606: return("Notification");
! 607: case EAP_TYPE_NAK:
! 608: return("Nak");
! 609: case EAP_TYPE_MD5CHAL:
! 610: return("MD5 Challenge");
! 611: case EAP_TYPE_OTP:
! 612: return("One Time Password");
! 613: case EAP_TYPE_GTC:
! 614: return("Generic Token Card");
! 615: case EAP_TYPE_EAP_TLS:
! 616: return("TLS");
! 617: case EAP_TYPE_MSCHAP_V2:
! 618: return("MS-CHAPv2");
! 619: case EAP_TYPE_EAP_TTLS:
! 620: return("TTLS");
! 621: default:
! 622: return("UNKNOWN");
! 623: }
! 624: }
! 625:
! 626: /*
! 627: * EapTypeSupported()
! 628: */
! 629:
! 630: static char
! 631: EapTypeSupported(u_char type)
! 632: {
! 633: switch (type) {
! 634: case EAP_TYPE_IDENT:
! 635: case EAP_TYPE_NOTIF:
! 636: case EAP_TYPE_NAK:
! 637: case EAP_TYPE_MD5CHAL:
! 638: return 1;
! 639:
! 640: default:
! 641: return 0;
! 642: }
! 643: }
! 644:
! 645: /*
! 646: * EapSetCommand()
! 647: */
! 648:
! 649: static int
! 650: EapSetCommand(Context ctx, int ac, char *av[], void *arg)
! 651: {
! 652: EapInfo const eap = &ctx->lnk->lcp.auth.eap;
! 653:
! 654: if (ac == 0)
! 655: return(-1);
! 656:
! 657: switch ((intptr_t)arg) {
! 658:
! 659: case SET_ACCEPT:
! 660: AcceptCommand(ac, av, &eap->conf.options, gConfList);
! 661: break;
! 662:
! 663: case SET_DENY:
! 664: DenyCommand(ac, av, &eap->conf.options, gConfList);
! 665: break;
! 666:
! 667: case SET_ENABLE:
! 668: EnableCommand(ac, av, &eap->conf.options, gConfList);
! 669: break;
! 670:
! 671: case SET_DISABLE:
! 672: DisableCommand(ac, av, &eap->conf.options, gConfList);
! 673: break;
! 674:
! 675: case SET_YES:
! 676: YesCommand(ac, av, &eap->conf.options, gConfList);
! 677: break;
! 678:
! 679: case SET_NO:
! 680: NoCommand(ac, av, &eap->conf.options, gConfList);
! 681: break;
! 682:
! 683: default:
! 684: assert(0);
! 685: }
! 686:
! 687: return(0);
! 688: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>