/*****************************************************************************
* pap.c - Network Password Authentication Protocol program file.
*
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
* portions Copyright (c) 1997 by Global Election Systems Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any 
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
* REVISION HISTORY
*
* 03-01-01 Marc Boucher <marc@mbsi.ca>
*   Ported to lwIP.
* 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
*	Original.
*****************************************************************************/
/*
 * upap.c - User/Password Authentication Protocol.
 *
 * Copyright (c) 1989 Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Carnegie Mellon University.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "ppp.h"
#include "auth.h"
#include "pap.h"
#include "pppdebug.h"


#if PAP_SUPPORT > 0

/***********************************/
/*** LOCAL FUNCTION DECLARATIONS ***/
/***********************************/
/*
 * Protocol entry points.
 */
static void upap_init (int);
static void upap_lowerup (int);
static void upap_lowerdown (int);
static void upap_input (int, u_char *, int);
static void upap_protrej (int);

static void upap_timeout (void *);
static void upap_reqtimeout (void *);
static void upap_rauthreq (upap_state *, u_char *, int, int);
static void upap_rauthack (upap_state *, u_char *, int, int);
static void upap_rauthnak (upap_state *, u_char *, int, int);
static void upap_sauthreq (upap_state *);
static void upap_sresp (upap_state *, u_char, u_char, char *, int);




/******************************/
/*** PUBLIC DATA STRUCTURES ***/
/******************************/
struct protent pap_protent = {
    PPP_PAP,
    upap_init,
    upap_input,
    upap_protrej,
    upap_lowerup,
    upap_lowerdown,
    NULL,
    NULL,
#if 0
    upap_printpkt,
    NULL,
#endif
    1,
    "PAP",
#if 0
    NULL,
    NULL,
    NULL
#endif
};

upap_state upap[NUM_PPP];		/* UPAP state; one for each unit */



/***********************************/
/*** PUBLIC FUNCTION DEFINITIONS ***/
/***********************************/
/*
 *  Set the default login name and password for the pap sessions
 */
void upap_setloginpasswd(int unit, const char *luser, const char *lpassword)
{
	upap_state *u = &upap[unit];
	
	/* Save the username and password we're given */
	u->us_user = luser;
	u->us_userlen = strlen(luser);
	u->us_passwd = lpassword;
	u->us_passwdlen = strlen(lpassword);
}


/*
 * upap_authwithpeer - Authenticate us with our peer (start client).
 *
 * Set new state and send authenticate's.
 */
void upap_authwithpeer(int unit, char *user, char *password)
{
	upap_state *u = &upap[unit];
	
	UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",
				unit, user, password, u->us_clientstate));
	
	upap_setloginpasswd(unit, user, password);

	u->us_transmits = 0;
	
	/* Lower layer up yet? */
	if (u->us_clientstate == UPAPCS_INITIAL ||
			u->us_clientstate == UPAPCS_PENDING) {
		u->us_clientstate = UPAPCS_PENDING;
		return;
	}
	
	upap_sauthreq(u);			/* Start protocol */
}


/*
 * upap_authpeer - Authenticate our peer (start server).
 *
 * Set new state.
 */
void upap_authpeer(int unit)
{
	upap_state *u = &upap[unit];
	
	/* Lower layer up yet? */
	if (u->us_serverstate == UPAPSS_INITIAL ||
			u->us_serverstate == UPAPSS_PENDING) {
		u->us_serverstate = UPAPSS_PENDING;
		return;
	}
	
	u->us_serverstate = UPAPSS_LISTEN;
	if (u->us_reqtimeout > 0)
		TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
}



/**********************************/
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/*
 * upap_init - Initialize a UPAP unit.
 */
static void upap_init(int unit)
{
	upap_state *u = &upap[unit];

	UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit));	
	u->us_unit = unit;
	u->us_user = NULL;
	u->us_userlen = 0;
	u->us_passwd = NULL;
	u->us_passwdlen = 0;
	u->us_clientstate = UPAPCS_INITIAL;
	u->us_serverstate = UPAPSS_INITIAL;
	u->us_id = 0;
	u->us_timeouttime = UPAP_DEFTIMEOUT;
	u->us_maxtransmits = 10;
	u->us_reqtimeout = UPAP_DEFREQTIME;
}

/*
 * upap_timeout - Retransmission timer for sending auth-reqs expired.
 */
static void upap_timeout(void *arg)
{
	upap_state *u = (upap_state *) arg;
	
	UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", 
				u->us_unit, u->us_timeouttime, u->us_clientstate));
	
	if (u->us_clientstate != UPAPCS_AUTHREQ)
		return;
	
	if (u->us_transmits >= u->us_maxtransmits) {
		/* give up in disgust */
		UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));
		u->us_clientstate = UPAPCS_BADAUTH;
		auth_withpeer_fail(u->us_unit, PPP_PAP);
		return;
	}
	
	upap_sauthreq(u);		/* Send Authenticate-Request */
}


/*
 * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
 */
static void upap_reqtimeout(void *arg)
{
	upap_state *u = (upap_state *) arg;
	
	if (u->us_serverstate != UPAPSS_LISTEN)
		return;			/* huh?? */
	
	auth_peer_fail(u->us_unit, PPP_PAP);
	u->us_serverstate = UPAPSS_BADAUTH;
}


/*
 * upap_lowerup - The lower layer is up.
 *
 * Start authenticating if pending.
 */
static void upap_lowerup(int unit)
{
	upap_state *u = &upap[unit];
	
	UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));
	
	if (u->us_clientstate == UPAPCS_INITIAL)
		u->us_clientstate = UPAPCS_CLOSED;
	else if (u->us_clientstate == UPAPCS_PENDING) {
		upap_sauthreq(u);	/* send an auth-request */
	}
	
	if (u->us_serverstate == UPAPSS_INITIAL)
		u->us_serverstate = UPAPSS_CLOSED;
	else if (u->us_serverstate == UPAPSS_PENDING) {
		u->us_serverstate = UPAPSS_LISTEN;
		if (u->us_reqtimeout > 0)
			TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
	}
}


/*
 * upap_lowerdown - The lower layer is down.
 *
 * Cancel all timeouts.
 */
static void upap_lowerdown(int unit)
{
	upap_state *u = &upap[unit];
	
	UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
	
	if (u->us_clientstate == UPAPCS_AUTHREQ)	/* Timeout pending? */
		UNTIMEOUT(upap_timeout, u);		/* Cancel timeout */
	if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0)
		UNTIMEOUT(upap_reqtimeout, u);
	
	u->us_clientstate = UPAPCS_INITIAL;
	u->us_serverstate = UPAPSS_INITIAL;
}


/*
 * upap_protrej - Peer doesn't speak this protocol.
 *
 * This shouldn't happen.  In any case, pretend lower layer went down.
 */
static void upap_protrej(int unit)
{
	upap_state *u = &upap[unit];
	
	if (u->us_clientstate == UPAPCS_AUTHREQ) {
		UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));
		auth_withpeer_fail(unit, PPP_PAP);
	}
	if (u->us_serverstate == UPAPSS_LISTEN) {
		UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));
		auth_peer_fail(unit, PPP_PAP);
	}
	upap_lowerdown(unit);
}


/*
 * upap_input - Input UPAP packet.
 */
static void upap_input(int unit, u_char *inpacket, int l)
{
	upap_state *u = &upap[unit];
	u_char *inp;
	u_char code, id;
	int len;
	
	/*
	 * Parse header (code, id and length).
	 * If packet too short, drop it.
	 */
	inp = inpacket;
	if (l < UPAP_HEADERLEN) {
		UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));
		return;
	}
	GETCHAR(code, inp);
	GETCHAR(id, inp);
	GETSHORT(len, inp);
	if (len < UPAP_HEADERLEN) {
		UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));
		return;
	}
	if (len > l) {
		UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));
		return;
	}
	len -= UPAP_HEADERLEN;
	
	/*
	 * Action depends on code.
	 */
	switch (code) {
	case UPAP_AUTHREQ:
		upap_rauthreq(u, inp, id, len);
		break;
	
	case UPAP_AUTHACK:
		upap_rauthack(u, inp, id, len);
		break;
	
	case UPAP_AUTHNAK:
		upap_rauthnak(u, inp, id, len);
		break;
	
	default:				/* XXX Need code reject */
		break;
	}
}


/*
 * upap_rauth - Receive Authenticate.
 */
static void upap_rauthreq(
	upap_state *u, 
	u_char *inp, 
	int id,
	int len
)
{
	u_char ruserlen, rpasswdlen;
	char *ruser, *rpasswd;
	int retcode;
	char *msg;
	int msglen;
	
	UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));
	
	if (u->us_serverstate < UPAPSS_LISTEN)
		return;
	
	/*
	 * If we receive a duplicate authenticate-request, we are
	 * supposed to return the same status as for the first request.
	 */
	if (u->us_serverstate == UPAPSS_OPEN) {
		upap_sresp(u, UPAP_AUTHACK, id, "", 0);	/* return auth-ack */
		return;
	}
	if (u->us_serverstate == UPAPSS_BADAUTH) {
		upap_sresp(u, UPAP_AUTHNAK, id, "", 0);	/* return auth-nak */
		return;
	}
	
	/*
	 * Parse user/passwd.
	 */
	if (len < sizeof (u_char)) {
		UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
		return;
	}
	GETCHAR(ruserlen, inp);
	len -= sizeof (u_char) + ruserlen + sizeof (u_char);
	if (len < 0) {
		UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
		return;
	}
	ruser = (char *) inp;
	INCPTR(ruserlen, inp);
	GETCHAR(rpasswdlen, inp);
	if (len < rpasswdlen) {
		UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
		return;
	}
	rpasswd = (char *) inp;
	
	/*
	 * Check the username and password given.
	 */
	retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd,
			   rpasswdlen, &msg, &msglen);
	BZERO(rpasswd, rpasswdlen);
	
	upap_sresp(u, retcode, id, msg, msglen);
	
	if (retcode == UPAP_AUTHACK) {
		u->us_serverstate = UPAPSS_OPEN;
		auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
	} else {
		u->us_serverstate = UPAPSS_BADAUTH;
		auth_peer_fail(u->us_unit, PPP_PAP);
	}
	
	if (u->us_reqtimeout > 0)
		UNTIMEOUT(upap_reqtimeout, u);
}


/*
 * upap_rauthack - Receive Authenticate-Ack.
 */
static void upap_rauthack(
	upap_state *u,
	u_char *inp,
	int id,
	int len
)
{
	u_char msglen;
	char *msg;
	
	UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
	
	if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
		return;
	
	/*
	 * Parse message.
	 */
	if (len < sizeof (u_char)) {
		UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
		return;
	}
	GETCHAR(msglen, inp);
	len -= sizeof (u_char);
	if (len < msglen) {
		UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
		return;
	}
	msg = (char *) inp;
	PRINTMSG(msg, msglen);
	
	u->us_clientstate = UPAPCS_OPEN;
	
	auth_withpeer_success(u->us_unit, PPP_PAP);
}


/*
 * upap_rauthnak - Receive Authenticate-Nakk.
 */
static void upap_rauthnak(
	upap_state *u,
	u_char *inp,
	int id,
	int len
)
{
	u_char msglen;
	char *msg;
	
	UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
	
	if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */
		return;
	
	/*
	 * Parse message.
	 */
	if (len < sizeof (u_char)) {
		UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
		return;
	}
	GETCHAR(msglen, inp);
	len -= sizeof (u_char);
	if (len < msglen) {
		UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
		return;
	}
	msg = (char *) inp;
	PRINTMSG(msg, msglen);
	
	u->us_clientstate = UPAPCS_BADAUTH;
	
	UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));
	auth_withpeer_fail(u->us_unit, PPP_PAP);
}


/*
 * upap_sauthreq - Send an Authenticate-Request.
 */
static void upap_sauthreq(upap_state *u)
{
	u_char *outp;
	int outlen;
	
	outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) 
			+ u->us_userlen + u->us_passwdlen;
	outp = outpacket_buf[u->us_unit];
	
	MAKEHEADER(outp, PPP_PAP);
	
	PUTCHAR(UPAP_AUTHREQ, outp);
	PUTCHAR(++u->us_id, outp);
	PUTSHORT(outlen, outp);
	PUTCHAR(u->us_userlen, outp);
	BCOPY(u->us_user, outp, u->us_userlen);
	INCPTR(u->us_userlen, outp);
	PUTCHAR(u->us_passwdlen, outp);
	BCOPY(u->us_passwd, outp, u->us_passwdlen);
	
	pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
	
	UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));
	
	TIMEOUT(upap_timeout, u, u->us_timeouttime);
	++u->us_transmits;
	u->us_clientstate = UPAPCS_AUTHREQ;
}


/*
 * upap_sresp - Send a response (ack or nak).
 */
static void upap_sresp(
	upap_state *u,
	u_char code, 
	u_char id,
	char *msg,
	int msglen
)
{
	u_char *outp;
	int outlen;
	
	outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
	outp = outpacket_buf[u->us_unit];
	MAKEHEADER(outp, PPP_PAP);
	
	PUTCHAR(code, outp);
	PUTCHAR(id, outp);
	PUTSHORT(outlen, outp);
	PUTCHAR(msglen, outp);
	BCOPY(msg, outp, msglen);
	pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
	
	UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", 
				code, id, u->us_clientstate));
}

#if 0
/*
 * upap_printpkt - print the contents of a PAP packet.
 */
static int upap_printpkt(
	u_char *p,
	int plen,
	void (*printer) (void *, char *, ...),
	void *arg
)
{
	(void)p;
	(void)plen;
	(void)printer;
	(void)arg;
	return 0;
}
#endif

#endif /* PAP_SUPPORT */

