File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / eap.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (4 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

    1: /*
    2:  * See ``COPYRIGHT.mpd''
    3:  *
    4:  * $Id: eap.c,v 1.1.1.4 2021/03/17 00:39:23 misho 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, const char *const av[], const 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, NULL, NULL, NULL, 0, NULL },
   56:   };
   57: 
   58: /*
   59:  * INTERNAL VARIABLES
   60:  */
   61: 
   62:   static const 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:   (void)type;
  229:   for (i = 0; i < EAP_NUM_TYPES; i++) {
  230:     if (eap->peer_types[i] != 0) {
  231:       nak_type = eap->peer_types[i];
  232:       break;
  233:     }
  234:   }
  235: 
  236:   if (nak_type == 0) {
  237:     Log(LG_AUTH, ("[%s] EAP: ran out of EAP Types", l->name));
  238:     AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
  239:     return;
  240:   }
  241: 
  242:   /* don't nak this proto again */
  243:   eap->peer_types[i] = 0;
  244: 
  245:   AuthOutput(l, PROTO_EAP, EAP_RESPONSE, id, &nak_type, 1, 0, EAP_TYPE_NAK);
  246:   return;
  247: }
  248: 
  249: /*
  250:  * EapSendIdentRequest()
  251:  *
  252:  * Send an Ident Request to the peer.
  253:  */
  254: 
  255: static void
  256: EapSendIdentRequest(Link l)
  257: {
  258:   EapInfo	const eap = &l->lcp.auth.eap;
  259: 
  260:   /* Send the initial Identity request */
  261:   AuthOutput(l, PROTO_EAP, EAP_REQUEST,  eap->next_id++, NULL, 0, 0, EAP_TYPE_IDENT);
  262: }
  263: 
  264: /*
  265:  * EapInput()
  266:  *
  267:  * Accept an incoming EAP packet
  268:  */
  269: 
  270: void
  271: EapInput(Link l, AuthData auth, const u_char *pkt, u_short len)
  272: {
  273:   Auth		const a = &l->lcp.auth;
  274:   EapInfo	const eap = &a->eap;
  275:   int		data_len = len - 1, i, acc_type;
  276:   const u_char	*data = NULL;
  277:   u_char	type = 0;
  278:   
  279:   if (pkt != NULL) {
  280:     data = data_len > 0 ? &pkt[1] : NULL;
  281:     type = pkt[0];
  282:   }
  283:   
  284:   if (Enabled(&eap->conf.options, EAP_CONF_RADIUS)) {
  285: 	EapRadiusProxy(l, auth, pkt, len);
  286: 	return;
  287:   }
  288: 
  289:   switch (auth->code) {
  290:     case EAP_REQUEST:
  291:       switch (type) {
  292: 	case EAP_TYPE_IDENT:
  293: 	  AuthOutput(l, PROTO_EAP, EAP_RESPONSE, auth->id, (u_char *) auth->conf.authname,
  294: 	    strlen(auth->conf.authname), 0, EAP_TYPE_IDENT);
  295: 	  break;
  296: 
  297: 	case EAP_TYPE_NAK:
  298: 	case EAP_TYPE_NOTIF:
  299: 	  Log(LG_AUTH, ("[%s] EAP: Type %s is invalid in Request messages",
  300: 	    l->name, EapType(type)));
  301: 	  AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
  302: 	  break;
  303: 
  304: 	/* deal with Auth Types */
  305: 	default:
  306: 	  acc_type = 0;
  307: 	  if (EapTypeSupported(type)) {
  308: 	    for (i = 0; i < EAP_NUM_TYPES; i++) {
  309: 	      if (eap->peer_types[i] == type) {
  310: 		acc_type = eap->peer_types[i];
  311: 		break;
  312: 	      }
  313: 	    }
  314: 
  315: 	    if (acc_type == 0) {
  316: 	      Log(LG_AUTH, ("[%s] EAP: Type %s not acceptable", l->name,
  317: 	        EapType(type)));
  318: 	      EapSendNak(l, auth->id, type);
  319: 	      break;
  320: 	    }
  321: 
  322: 	    switch (type) {
  323: 	      case EAP_TYPE_MD5CHAL:
  324: 		a->self_to_peer_alg = CHAP_ALG_MD5;
  325: 		auth->code = CHAP_CHALLENGE;
  326: 		ChapInput(l, auth, &pkt[1], len - 1);
  327: 		return;
  328: 
  329: 	      default:
  330: 		assert(0);
  331: 	    }
  332: 	  } else {
  333: 	    Log(LG_AUTH, ("[%s] EAP: Type %s not supported", l->name, EapType(type)));
  334: 	    EapSendNak(l, auth->id, type);
  335: 	  }
  336:       }
  337:       break;
  338: 
  339:     case EAP_RESPONSE:
  340:       switch (type) {
  341: 	case EAP_TYPE_IDENT:
  342: 	  TimerStop(&eap->identTimer);
  343: 	  Log(LG_AUTH, ("[%s] EAP: Identity:%*.*s",
  344: 	    l->name, data_len, data_len, data));
  345: 	  EapSendRequest(l, 0);
  346: 	  break;
  347: 
  348: 	case EAP_TYPE_NOTIF:
  349: 	  Log(LG_AUTH, ("[%s] EAP: Notify:%*.*s ", l->name,
  350: 	    data_len, data_len, data));
  351: 	  break;
  352: 
  353: 	case EAP_TYPE_NAK:
  354: 	  Log(LG_AUTH, ("[%s] EAP: Nak desired Type %s ", l->name,
  355: 	    EapType(data[0])));
  356: 	  if (EapTypeSupported(data[0]))
  357: 	    EapSendRequest(l, data[0]);
  358: 	  else
  359: 	    EapSendRequest(l, 0);
  360: 	  break;
  361: 
  362: 	case EAP_TYPE_MD5CHAL:
  363: 	  auth->code = CHAP_RESPONSE;
  364: 	  ChapInput(l, auth, &pkt[1], len - 1);
  365: 	  return;
  366: 
  367: 	default:
  368: 	  Log(LG_AUTH, ("[%s] EAP: unknown type %d", l->name, type));
  369: 	  AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
  370:       }
  371:       break;
  372: 
  373:     case EAP_SUCCESS:
  374:       AuthFinish(l, AUTH_SELF_TO_PEER, TRUE);
  375:       break;
  376: 
  377:     case EAP_FAILURE:
  378:       AuthFinish(l, AUTH_SELF_TO_PEER, FALSE);
  379:       break;
  380: 
  381:     default:
  382:       Log(LG_AUTH, ("[%s] EAP: unknown code %d", l->name, auth->code));
  383:       AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
  384:   }
  385:   AuthDataDestroy(auth);
  386: }
  387: 
  388: /*
  389:  * EapRadiusProxy()
  390:  *
  391:  * Proxy EAP Requests from/to the RADIUS server
  392:  */
  393: 
  394: static void
  395: EapRadiusProxy(Link l, AuthData auth, const u_char *pkt, u_short len)
  396: {
  397:   int		data_len = len - 1;
  398:   const u_char	*data = NULL;
  399:   u_char	type = 0;
  400:   Auth		const a = &l->lcp.auth;
  401:   EapInfo	const eap = &a->eap;
  402:   struct fsmheader	lh;
  403: 
  404:   Log(LG_AUTH, ("[%s] EAP: Proxying packet to RADIUS", l->name));
  405: 
  406:   if (pkt != NULL) {
  407:     data = data_len > 0 ? &pkt[1] : NULL;
  408:     type = pkt[0];
  409:   }
  410: 
  411:   if (auth->code == EAP_RESPONSE && type == EAP_TYPE_IDENT) {
  412:     TimerStop(&eap->identTimer);
  413:     if (data_len >= AUTH_MAX_AUTHNAME) {
  414:       Log(LG_AUTH, ("[%s] EAP: Identity to big (%d), truncating",
  415: 	l->name, data_len));
  416:         data_len = AUTH_MAX_AUTHNAME - 1;
  417:     }
  418:     memset(eap->identity, 0, sizeof(eap->identity));
  419:     strncpy(eap->identity, (const char *)data, data_len);
  420:     Log(LG_AUTH, ("[%s] EAP: Identity: %s", l->name, eap->identity));
  421:   }
  422: 
  423:   TimerStop(&eap->reqTimer);
  424: 
  425:   /* prepare packet */
  426:   lh.code = auth->code;
  427:   lh.id = auth->id;
  428:   lh.length = htons(len + sizeof(lh));
  429: 
  430:   auth->params.eapmsg = Malloc(MB_AUTH, len + sizeof(lh));
  431:   memcpy(auth->params.eapmsg, &lh, sizeof(lh));
  432:   memcpy(&auth->params.eapmsg[sizeof(lh)], pkt, len);
  433: 
  434:   auth->params.eapmsg_len = len + sizeof(lh);
  435:   strlcpy(auth->params.authname, eap->identity, sizeof(auth->params.authname));
  436: 
  437:   auth->eap_radius = TRUE;
  438: 
  439:   auth->finish = EapRadiusProxyFinish;
  440:   AuthAsyncStart(l, auth);
  441:   
  442: }
  443: 
  444: /*
  445:  * RadiusEapProxyFinish()
  446:  *
  447:  * Return point from the asynch RADIUS EAP Proxy Handler.
  448:  * 
  449:  */
  450:  
  451: static void
  452: EapRadiusProxyFinish(Link l, AuthData auth)
  453: {
  454:   Auth		const a = &l->lcp.auth;
  455:   EapInfo	eap = &a->eap;
  456:   
  457:   Log(LG_AUTH, ("[%s] EAP: RADIUS return status: %s", 
  458:     l->name, AuthStatusText(auth->status)));
  459: 
  460:   /* this shouldn't happen normally, however be liberal */
  461:   if (a->params.eapmsg == NULL) {
  462:     struct fsmheader	lh;
  463: 
  464:     Log(LG_AUTH, ("[%s] EAP: Warning, rec'd empty EAP-Message", 
  465:       l->name));
  466:     /* prepare packet */
  467:     lh.code = auth->status == AUTH_STATUS_SUCCESS ? EAP_SUCCESS : EAP_FAILURE;
  468:     lh.id = auth->id;
  469:     lh.length = htons(sizeof(lh));
  470: 
  471:     a->params.eapmsg = Mdup(MB_AUTH, &lh, sizeof(lh));
  472:     a->params.eapmsg_len = sizeof(lh);
  473:   }
  474: 
  475:   if (a->params.eapmsg != NULL) {
  476:     eap->retry = AUTH_RETRIES;
  477:     
  478:     EapRadiusSendMsg(l);
  479:     if (auth->status == AUTH_STATUS_UNDEF)
  480:       TimerStart(&eap->reqTimer);
  481:   }
  482: 
  483:   if (auth->status == AUTH_STATUS_FAIL) {
  484:     AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
  485:   } else if (auth->status == AUTH_STATUS_SUCCESS) {
  486:     AuthFinish(l, AUTH_PEER_TO_SELF, TRUE);
  487:   } 
  488: 
  489:   AuthDataDestroy(auth);  
  490: }
  491: 
  492: /*
  493:  * EapRadiusSendMsg()
  494:  *
  495:  * Send an EAP Message to the peer
  496:  */
  497: 
  498: static void
  499: EapRadiusSendMsg(void *ptr)
  500: {
  501:   Mbuf		bp;
  502:   Link		l = (Link)ptr;
  503:   Auth		const a = &l->lcp.auth;
  504:   FsmHeader	const f = (FsmHeader)(void *)a->params.eapmsg;
  505:   char		buf[32];
  506: 
  507:   if (a->params.eapmsg_len > 4) {
  508:     Log(LG_AUTH, ("[%s] EAP: send %s #%d len: %d, type: %s",
  509:       l->name, EapCode(f->code, buf, sizeof(buf)), f->id, htons(f->length),
  510:       EapType(a->params.eapmsg[4])));
  511:   } else {
  512:     Log(LG_AUTH, ("[%s] EAP: send %s #%d len: %d",
  513:       l->name, EapCode(f->code, buf, sizeof(buf)), f->id, htons(f->length)));
  514:   } 
  515: 
  516:   bp = mbcopyback(NULL, 0, a->params.eapmsg, a->params.eapmsg_len);
  517:   NgFuncWritePppFrameLink(l, PROTO_EAP, bp);
  518: }
  519: 
  520: /*
  521:  * EapRadiusSendMsgTimeout()
  522:  *
  523:  * Timer expired for reply to our request
  524:  */
  525: 
  526: static void
  527: EapRadiusSendMsgTimeout(void *ptr)
  528: {
  529:     Link	l = (Link)ptr;
  530:     EapInfo	const eap = &l->lcp.auth.eap;
  531: 
  532:     if (--eap->retry > 0) {
  533: 	TimerStart(&eap->reqTimer);
  534: 	EapRadiusSendMsg(l);
  535:     }
  536: }
  537: 
  538: /*
  539:  * EapIdentTimeout()
  540:  *
  541:  * Timer expired for reply to our request
  542:  */
  543: 
  544: static void
  545: EapIdentTimeout(void *ptr)
  546: {
  547:     Link	l = (Link)ptr;
  548:     EapInfo	const eap = &l->lcp.auth.eap;
  549: 
  550:     if (--eap->retry > 0) {
  551: 	TimerStart(&eap->identTimer);
  552: 	EapSendIdentRequest(l);
  553:     }
  554: }
  555: 
  556: /*
  557:  * EapStat()
  558:  */
  559: 
  560: int
  561: EapStat(Context ctx, int ac, const char *const av[], const void *arg)
  562: {
  563:   EapInfo	const eap = &ctx->lnk->lcp.auth.eap;
  564: 
  565:   (void)ac;
  566:   (void)av;
  567:   (void)arg;
  568: 
  569:   Printf("\tIdentity     : %s\r\n", eap->identity);
  570:   Printf("EAP options\r\n");
  571:   OptStat(ctx, &eap->conf.options, gConfList);
  572: 
  573:   return (0);
  574: }
  575: 
  576: /*
  577:  * EapCode()
  578:  */
  579: 
  580: const char *
  581: EapCode(u_char code, char *buf, size_t len)
  582: {
  583:   switch (code) {
  584:     case EAP_REQUEST:
  585: 	strlcpy(buf, "REQUEST", len);
  586: 	break;
  587:     case EAP_RESPONSE:
  588: 	strlcpy(buf, "RESPONSE", len);
  589: 	break;
  590:     case EAP_SUCCESS:
  591: 	strlcpy(buf, "SUCCESS", len);
  592: 	break;
  593:     case EAP_FAILURE:
  594: 	strlcpy(buf, "FAILURE", len);
  595: 	break;
  596:     default:
  597: 	snprintf(buf, len, "code%d", code);
  598:   }
  599:   return(buf);
  600: }
  601: 
  602: /*
  603:  * EapType()
  604:  */
  605: 
  606: const char *
  607: EapType(u_char type)
  608: {
  609:   switch (type) {
  610:     case EAP_TYPE_IDENT:
  611:       return("Identity");
  612:     case EAP_TYPE_NOTIF:
  613:       return("Notification");
  614:     case EAP_TYPE_NAK:
  615:       return("Nak");
  616:     case EAP_TYPE_MD5CHAL:
  617:       return("MD5 Challenge");
  618:     case EAP_TYPE_OTP:
  619:       return("One Time Password");
  620:     case EAP_TYPE_GTC:
  621:       return("Generic Token Card");
  622:     case EAP_TYPE_EAP_TLS:
  623:       return("TLS");
  624:     case EAP_TYPE_MSCHAP_V2:
  625:       return("MS-CHAPv2");
  626:     case EAP_TYPE_EAP_TTLS:
  627:       return("TTLS");
  628:     default:
  629:       return("UNKNOWN");
  630:   }
  631: }
  632: 
  633: /*
  634:  * EapTypeSupported()
  635:  */
  636: 
  637: static char
  638: EapTypeSupported(u_char type)
  639: {
  640:   switch (type) {
  641:     case EAP_TYPE_IDENT:
  642:     case EAP_TYPE_NOTIF:
  643:     case EAP_TYPE_NAK:
  644:     case EAP_TYPE_MD5CHAL:
  645:       return 1;
  646: 
  647:     default:
  648:       return 0;
  649:   }
  650: }
  651: 
  652: /*
  653:  * EapSetCommand()
  654:  */
  655: 
  656: static int
  657: EapSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
  658: {
  659:   EapInfo	const eap = &ctx->lnk->lcp.auth.eap;
  660: 
  661:   if (ac == 0)
  662:     return(-1);
  663: 
  664:   switch ((intptr_t)arg) {
  665: 
  666:     case SET_ACCEPT:
  667:       AcceptCommand(ac, av, &eap->conf.options, gConfList);
  668:       break;
  669: 
  670:     case SET_DENY:
  671:       DenyCommand(ac, av, &eap->conf.options, gConfList);
  672:       break;
  673: 
  674:     case SET_ENABLE:
  675:       EnableCommand(ac, av, &eap->conf.options, gConfList);
  676:       break;
  677: 
  678:     case SET_DISABLE:
  679:       DisableCommand(ac, av, &eap->conf.options, gConfList);
  680:       break;
  681: 
  682:     case SET_YES:
  683:       YesCommand(ac, av, &eap->conf.options, gConfList);
  684:       break;
  685: 
  686:     case SET_NO:
  687:       NoCommand(ac, av, &eap->conf.options, gConfList);
  688:       break;
  689: 
  690:     default:
  691:       assert(0);
  692:   }
  693: 
  694:   return(0);
  695: }

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