File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / pap.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (11 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    1: 
    2: /*
    3:  * pap.c
    4:  *
    5:  * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
    6:  * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
    7:  * See ``COPYRIGHT.iij''
    8:  * 
    9:  * Rewritten by Archie Cobbs <archie@freebsd.org>
   10:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
   11:  * See ``COPYRIGHT.whistle''
   12:  */
   13: 
   14: #include "ppp.h"
   15: #include "auth.h"
   16: #include "util.h"
   17: 
   18: /*
   19:  * INTERNAL FUNCTIONS
   20:  */
   21: 
   22:   static void	PapSendRequest(Link l);
   23:   static void	PapTimeout(void *ptr);
   24: 
   25: /*
   26:  * PapStart()
   27:  */
   28: 
   29: void
   30: PapStart(Link l, int which)
   31: {
   32:   PapInfo pap = &l->lcp.auth.pap;
   33: 
   34:   switch (which) {
   35:     case AUTH_PEER_TO_SELF:	/* Just wait for peer's request */
   36:       break;
   37: 
   38:     case AUTH_SELF_TO_PEER:
   39: 
   40:       /* Initialize retry counter and timer */
   41:       pap->next_id = 1;
   42:       pap->retry = AUTH_RETRIES;
   43: 
   44:       TimerInit(&pap->timer, "PapTimer",
   45: 	l->conf.retry_timeout * SECONDS, PapTimeout, l);
   46:       TimerStart(&pap->timer);
   47: 
   48:       /* Send first request */
   49:       PapSendRequest(l);
   50:       break;
   51: 
   52:     default:
   53:       assert(0);
   54:   }
   55: }
   56: 
   57: /*
   58:  * PapStop()
   59:  */
   60: 
   61: void
   62: PapStop(PapInfo pap)
   63: {
   64:   TimerStop(&pap->timer);
   65: }
   66: 
   67: /*
   68:  * PapSendRequest()
   69:  *
   70:  * Send a PAP packet to peer.
   71:  */
   72: 
   73: static void
   74: PapSendRequest(Link l)
   75: {
   76:     PapInfo		pap = &l->lcp.auth.pap;
   77:     char		password[AUTH_MAX_PASSWORD];
   78:     int			name_len, pass_len;
   79:     u_char		*pkt;
   80: 
   81:     /* Get password corresponding to my authname */
   82:     Log(LG_AUTH, ("[%s] PAP: using authname \"%s\"", 
   83: 	l->name, l->lcp.auth.conf.authname));
   84:     if (l->lcp.auth.conf.password[0] != 0) {
   85: 	strlcpy(password, l->lcp.auth.conf.password, sizeof(password));
   86:     } else if (AuthGetData(l->lcp.auth.conf.authname, password, 
   87: 	    sizeof(password), NULL, NULL) < 0) {
   88: 	Log(LG_AUTH, ("[%s] PAP: Warning: no secret for \"%s\" found", 
   89: 	    l->name, l->lcp.auth.conf.authname));
   90:     }
   91: 
   92:     /* Build response packet */
   93:     name_len = strlen(l->lcp.auth.conf.authname);
   94:     pass_len = strlen(password);
   95: 
   96:     pkt = Malloc(MB_AUTH, 1 + name_len + 1 + pass_len);
   97:     pkt[0] = name_len;
   98:     memcpy(pkt + 1, l->lcp.auth.conf.authname, name_len);
   99:     pkt[1 + name_len] = pass_len;
  100:     memcpy(pkt + 1 + name_len + 1, password, pass_len);
  101: 
  102:     /* Send it off */
  103:     AuthOutput(l, PROTO_PAP, PAP_REQUEST, pap->next_id++, pkt,
  104: 	1 + name_len + 1 + pass_len, 0, 0);
  105:     Freee(pkt);
  106: }
  107: 
  108: /*
  109:  * PapInput()
  110:  *
  111:  * Accept an incoming PAP packet
  112:  */
  113: 
  114: void
  115: PapInput(Link l, AuthData auth, const u_char *pkt, u_short len)
  116: {
  117:     Auth		const a = &l->lcp.auth;
  118:     PapInfo		const pap = &a->pap;
  119:     PapParams		const pp = &auth->params.pap;
  120:     char		failMesg[64];
  121:     char		buf[16];
  122: 
  123:   switch (auth->code) {
  124:     case PAP_REQUEST:
  125:       {
  126: 	char		*name_ptr, name[256];
  127: 	char		*pass_ptr, pass[256];
  128: 	int		name_len, pass_len;
  129: 
  130: 	/* Is this appropriate? */
  131: 	if (a->peer_to_self != PROTO_PAP) {
  132: 	    if (l->lcp.want_auth == PROTO_PAP && a->peer_to_self == 0) {
  133: 		Log(LG_AUTH, ("[%s] PAP: retransmitting ACK",
  134: 		    l->name));
  135: 		AuthOutput(l, PROTO_PAP, PAP_ACK, auth->id,
  136: 		    (u_char *) AUTH_MSG_WELCOME, strlen(AUTH_MSG_WELCOME), 1, 0);
  137: 		break;
  138: 	    }
  139: 	    Log(LG_AUTH, ("[%s] PAP: %s not expected",
  140: 		l->name, PapCode(auth->code, buf, sizeof(buf))));
  141: 	    auth->why_fail = AUTH_FAIL_NOT_EXPECTED;
  142: 	    PapInputFinish(l, auth);
  143: 	    return;
  144: 	}
  145: 
  146: 	/* Sanity check packet and extract fields */
  147: 	if (len < 1)
  148: 	    goto error;
  149: 
  150: 	name_len = pkt[0];
  151: 	name_ptr = (char *)pkt + 1;
  152: 
  153: 	if (1 + name_len >= len)
  154: 	    goto error;
  155: 
  156: 	pass_len = pkt[1 + name_len];
  157: 	pass_ptr = (char *)pkt + 1 + name_len + 1;
  158: 
  159: 	if (name_len + 1 + pass_len + 1 > len)
  160: 	    goto error;
  161: 
  162: 	memcpy(name, name_ptr, name_len);
  163: 	name[name_len] = 0;
  164: 	memcpy(pass, pass_ptr, pass_len);
  165: 	pass[pass_len] = 0;
  166: 
  167: 	strlcpy(pp->peer_name, name, sizeof(pp->peer_name));
  168: 	strlcpy(pp->peer_pass, pass, sizeof(pp->peer_pass));
  169: 	strlcpy(auth->params.authname, name, sizeof(auth->params.authname));
  170: 	auth->params.password[0] = 0;
  171: 
  172: 	auth->finish = PapInputFinish;
  173: 	AuthAsyncStart(l, auth);
  174: 	return;
  175:       }
  176:       break;
  177: 
  178:     case PAP_ACK:
  179:     case PAP_NAK:
  180:       {
  181: 	/* Is this appropriate? */
  182: 	if (a->self_to_peer != PROTO_PAP) {
  183: 	    Log(LG_AUTH, ("[%s] PAP: %s not expected",
  184: 		l->name, PapCode(auth->code, buf, sizeof(buf))));
  185: 	    break;
  186: 	}
  187: 
  188: 	/* Stop resend timer */
  189: 	TimerStop(&pap->timer);
  190: 
  191: 	/* Show reply message */
  192: 	if (len > 0) {
  193: 	    int		msg_len = pkt[0];
  194: 	    char	*msg = (char *) &pkt[1];
  195: 	    if (msg_len < len - 1)
  196: 		msg_len = len - 1;
  197: 	    ShowMesg(LG_AUTH, l->name, msg, msg_len);
  198: 	}
  199: 
  200: 	/* Done with my auth to peer */
  201: 	AuthFinish(l, AUTH_SELF_TO_PEER, auth->code == PAP_ACK);	
  202:       }
  203:       break;
  204: 
  205:     default:
  206:       Log(LG_AUTH, ("[%s] PAP: unknown code", l->name));
  207:       break;
  208:   }
  209:     AuthDataDestroy(auth);
  210:     return;
  211: 
  212: error:
  213:     Log(LG_AUTH, ("[%s] PAP: Bad PAP packet", l->name));
  214:     auth->why_fail = AUTH_FAIL_INVALID_PACKET;
  215:     AuthFailMsg(auth, failMesg, sizeof(failMesg));
  216:     AuthOutput(l, PROTO_PAP, PAP_NAK, auth->id, (u_char *)failMesg, strlen(failMesg), 1, 0);
  217:     AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
  218:     AuthDataDestroy(auth);
  219: }
  220: 
  221: /*
  222:  * PapInputFinish()
  223:  *
  224:  * Possible return point from the asynch auth handler.
  225:  * 
  226:  */
  227:  
  228: void PapInputFinish(Link l, AuthData auth)
  229: {
  230:   Auth		const a = &l->lcp.auth;
  231:   PapParams	pap = &a->params.pap;
  232:   const char	*Mesg;
  233:   
  234:     Log(LG_AUTH, ("[%s] PAP: Auth return status: %s", 
  235: 	l->name, AuthStatusText(auth->status)));
  236: 
  237:     if (auth->status == AUTH_STATUS_BUSY) {
  238: 	AuthDataDestroy(auth);  
  239: 	return;
  240:     } else if (auth->status == AUTH_STATUS_FAIL)
  241: 	goto badRequest;
  242:     else if (auth->status == AUTH_STATUS_SUCCESS)
  243: 	goto goodRequest;
  244:   
  245:     /* Do name & password match? */
  246:     if (strcmp(a->params.authname, pap->peer_name) ||
  247:         strcmp(a->params.password, pap->peer_pass)) {
  248: 	Log(LG_AUTH, ("[%s] PAP: Invalid response", l->name));
  249: 	auth->why_fail = AUTH_FAIL_INVALID_LOGIN;
  250: 	goto badRequest;
  251:     }
  252: 
  253: goodRequest:
  254:     /* Login accepted */
  255:     Log(LG_AUTH, ("[%s] PAP: Response is valid", l->name));
  256:     if (auth->reply_message) {
  257: 	Mesg = auth->reply_message;
  258:     } else {
  259: 	Mesg = AUTH_MSG_WELCOME;
  260:     }
  261:     Log(LG_AUTH, ("[%s] PAP: Reply message: %s", l->name, Mesg));
  262:     AuthOutput(l, PROTO_PAP, PAP_ACK, auth->id, (u_char *) Mesg, strlen(Mesg), 1, 0);
  263:     AuthFinish(l, AUTH_PEER_TO_SELF, TRUE);  
  264:     AuthDataDestroy(auth);
  265:     return;
  266: 
  267: badRequest:
  268:   {
  269:     char        failMesg[64];
  270: 
  271:     Mesg = AuthFailMsg(auth, failMesg, sizeof(failMesg));
  272:     Log(LG_AUTH, ("[%s] PAP: Reply message: %s", l->name, Mesg));
  273:     AuthOutput(l, PROTO_PAP, PAP_NAK, auth->id, (u_char *) Mesg, strlen(Mesg), 1, 0);
  274:     AuthFinish(l, AUTH_PEER_TO_SELF, FALSE);
  275:     AuthDataDestroy(auth);  
  276:   }
  277: }
  278: 
  279: /*
  280:  * PapTimeout()
  281:  *
  282:  * Timer expired for reply to our request
  283:  */
  284: 
  285: static void
  286: PapTimeout(void *ptr)
  287: {
  288:   Link		const l = (Link) ptr;
  289:   PapInfo	const pap = &l->lcp.auth.pap;
  290: 
  291:   if (--pap->retry > 0) {
  292:     TimerStart(&pap->timer);
  293:     PapSendRequest(l);
  294:   }
  295: }
  296: 
  297: /*
  298:  * PapCode()
  299:  */
  300: 
  301: const char *
  302: PapCode(int code, char *buf, size_t len)
  303: {
  304:   switch (code) {
  305:     case PAP_REQUEST:
  306:       strlcpy(buf, "REQUEST", len);
  307:       break;
  308:     case PAP_ACK:
  309:       strlcpy(buf, "ACK", len);
  310:       break;
  311:     case PAP_NAK:
  312:       strlcpy(buf, "NAK", len);
  313:       break;
  314:     default:
  315:       snprintf(buf, len, "code%d", code);
  316:   }
  317:   return(buf);
  318: }
  319: 

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