xref: /openbsd-src/usr.sbin/npppd/npppd/lcp.c (revision bcb159dabaec0c8e55089ec3f1ffbd233e95b4b7)
1 /*	$OpenBSD: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */
2 
3 /*-
4  * Copyright (c) 2009 Internet Initiative Japan Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /* $Id: lcp.c,v 1.18 2019/02/27 04:52:19 denis Exp $ */
29 /**@file
30  * This file provides LCP related functions.
31  *<pre>
32  * RFC1661: The Point-to-Point Protocol (PPP)
33  * RFC1570:  PPP LCP Extensions
34  *</pre>
35  */
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/time.h>
39 #include <netinet/in.h>
40 #include <net/if_dl.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <syslog.h>
44 #include <string.h>
45 #include <event.h>
46 #include <ctype.h>
47 
48 #include "npppd.h"
49 #include "ppp.h"
50 #include "psm-opt.h"
51 
52 #define	SPACE	" \t\r\n"
53 
54 #include "debugutil.h"
55 
56 #ifdef	LCP_DEBUG
57 #define	LCP_DBG(x)	fsm_log x
58 #define	LCP_ASSERT(x)	ASSERT(x)
59 #else
60 #define	LCP_DBG(x)
61 #define	LCP_ASSERT(x)
62 #endif
63 
64 #define	PROTREJ			0x08
65 #define	ECHOREQ			0x09
66 #define	ECHOREP			0x0a
67 #define	IDENTIFICATION		0x0c
68 
69 static void  lcp_resetci(fsm *);
70 static void  lcp_addci(fsm *, u_char *, int *);
71 static int   lcp_reqci(fsm *, u_char *, int *, int);
72 static int   lcp_ackci(fsm *, u_char *, int);
73 static int   lcp_nakci(fsm *, u_char *, int);
74 static int   lcp_rejci(fsm *, u_char *, int);
75 static int   lcp_cilen(fsm *);
76 static void  lcp_open(fsm *);
77 static void  lcp_down(fsm *);
78 static void  lcp_finished(fsm *);
79 static int   lcp_ext(fsm *, int, int, u_char *, int);
80 static void  lcp_timeout(void *);
81 static void  lcp_reset_timeout(void *);
82 static int   lcp_proxy_recv_ci(fsm *, u_char *, int);
83 static int   lcp_proxy_sent_ci(fsm *, u_char *, int);
84 static void  lcp_load_authconfig(fsm *f);
85 
86 static struct fsm_callbacks lcp_callbacks = {
87 	lcp_resetci,	/* Reset our Configuration Information */
88 	lcp_cilen,	/* Length of our Configuration Information */
89 	lcp_addci,	/* Add our Configuration Information */
90 	lcp_ackci,	/* ACK our Configuration Information */
91 	lcp_nakci,	/* NAK our Configuration Information */
92 	lcp_rejci,	/* Reject our Configuration Information */
93 	lcp_reqci,	/* Request peer's Configuration Information */
94 	lcp_open,	/* Called when fsm reaches OPENED state */
95 	lcp_down,	/* Called when fsm leaves OPENED state */
96 	NULL,		/* Called when we want the lower layer up */
97 	lcp_finished,	/* Called when we want the lower layer down */
98 	NULL,		/* Called when Protocol-Reject received */
99 	NULL,		/* Retransmission is necessary */
100 	lcp_ext,	/* Called to handle LCP-specific codes */
101 	"lcp"		/* String name of protocol */
102 };
103 #define	NO_AUTH_AGREEABLE(lcp)	\
104     (!psm_opt_is_enabled(lcp, pap) || psm_opt_is_rejected(lcp, pap)) &&	    \
105     (!psm_opt_is_enabled(lcp, chap) || psm_opt_is_rejected(lcp, chap)) &&   \
106     (!psm_opt_is_enabled(lcp, chapms) || psm_opt_is_rejected(lcp, chapms)) &&\
107     (!psm_opt_is_enabled(lcp, chapms_v2) || psm_opt_is_rejected(lcp, chapms_v2)) && \
108     (!psm_opt_is_enabled(lcp, eap) || psm_opt_is_rejected(lcp, eap))
109 
110 
111 /** initializing context for LCP. */
112 void
lcp_init(lcp * _this,npppd_ppp * ppp)113 lcp_init(lcp *_this, npppd_ppp *ppp)
114 {
115 	struct tunnconf *conf;
116 
117 	fsm_init(&_this->fsm);
118 
119 	_this->fsm.ppp = ppp;
120 	_this->fsm.callbacks = &lcp_callbacks;
121 	_this->fsm.protocol = PPP_PROTO_LCP;
122 	_this->fsm.flags |= OPT_SILENT;
123 	_this->timerctx.ctx = _this;
124 
125 	_this->recv_ress = 0;
126 	_this->recv_reqs = 0;
127 	_this->magic_number = arc4random();
128 
129 	conf = ppp_get_tunnconf(ppp);
130 	PPP_FSM_CONFIG(&_this->fsm, timeouttime, conf->lcp_timeout);
131 	PPP_FSM_CONFIG(&_this->fsm, maxconfreqtransmits,
132 	    conf->lcp_max_configure);
133 	PPP_FSM_CONFIG(&_this->fsm, maxtermtransmits,
134 	    conf->lcp_max_terminate);
135 	PPP_FSM_CONFIG(&_this->fsm, maxnakloops,
136 	    conf->lcp_max_nak_loop);
137 
138 	_this->echo_failures = 0;
139 	if (!conf->lcp_keepalive)
140 		_this->echo_interval = 0;
141 	else {
142 		_this->echo_interval = conf->lcp_keepalive_interval;
143 		_this->echo_retry_interval = conf->lcp_keepalive_retry_interval;
144 		_this->echo_max_retries = conf->lcp_keepalive_max_retries;
145 	}
146 	_this->auth_order[0] = -1;
147 }
148 
149 
150 /**
151  * This function is called when HDLC as LCP's lower layer is up.
152  */
153 void
lcp_lowerup(lcp * _this)154 lcp_lowerup(lcp *_this)
155 {
156 	fsm_lowerup(&_this->fsm);
157 	fsm_open(&_this->fsm);
158 
159 	if (_this->dialin_proxy != 0 &&
160 	    _this->dialin_proxy_lcp_renegotiation == 0) {
161 		_this->fsm.state = OPENED;
162 		lcp_open(&_this->fsm);
163 	}
164 }
165 
166 /**
167  * sending Protocol-Reject.
168  */
169 void
lcp_send_protrej(lcp * _this,u_char * pktp,int lpktp)170 lcp_send_protrej(lcp *_this, u_char *pktp, int lpktp)
171 {
172 	LCP_ASSERT(_this != NULL);
173 	LCP_ASSERT(pktp != NULL);
174 
175 	fsm_sdata(&_this->fsm, PROTREJ, _this->fsm.id++, pktp, lpktp);
176 }
177 
178 static const char *
lcp_auth_string(int auth)179 lcp_auth_string(int auth)
180 {
181 	switch (auth) {
182 	case PPP_AUTH_PAP:		return "PAP";
183 	case PPP_AUTH_CHAP_MD5:		return "MD5-CHAP";
184 	case PPP_AUTH_CHAP_MS:		return "MS-CHAP";
185 	case PPP_AUTH_CHAP_MS_V2:	return "MS-CHAP-V2";
186 	case PPP_AUTH_EAP:		return "EAP";
187 	case 0:				return "none";
188 	default:			return "ERROR";
189 	}
190 }
191 
192 static void
lcp_open(fsm * f)193 lcp_open(fsm *f)
194 {
195 	lcp *_this;
196 	int peer_auth = 0;
197 
198 	LCP_ASSERT(f != NULL);
199 	_this = &f->ppp->lcp;
200 
201 	if (psm_opt_is_accepted(_this, pap))
202 		peer_auth = PPP_AUTH_PAP;
203 	else if (psm_opt_is_accepted(_this, chap))
204 		peer_auth = PPP_AUTH_CHAP_MD5;
205 	else if (psm_opt_is_accepted(_this, chapms))
206 		peer_auth = PPP_AUTH_CHAP_MS;
207 	else if (psm_opt_is_accepted(_this, chapms_v2))
208 		peer_auth = PPP_AUTH_CHAP_MS_V2;
209 	else if (psm_opt_is_accepted(_this, eap))
210 		peer_auth = PPP_AUTH_EAP;
211 	else {
212 		if (_this->auth_order[0] > 0) {
213 			fsm_log(f, LOG_INFO,
214 			    "failed to negotiate a auth protocol.");
215 			fsm_close(f, "Authentication is required");
216 			ppp_set_disconnect_cause(f->ppp,
217 			    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
218 			    _this->auth_order[0] /* first one */,
219 			    1 /* peer refused */, NULL);
220 			ppp_stop(f->ppp, "Authentication is required");
221 			return;
222 		}
223 	}
224 	f->ppp->peer_auth = peer_auth;
225 
226 	if (_this->xxxmru > 0 && f->ppp->peer_mru <= 0)
227 		f->ppp->peer_mru = _this->xxxmru;
228 	if (f->ppp->peer_mru <= 0)
229 		f->ppp->peer_mru = f->ppp->mru;
230 
231 	/* checking the size of ppp->peer_mru. */
232 	LCP_ASSERT(f->ppp->peer_mru > 500);
233 
234 	fsm_log(f, LOG_INFO, "logtype=Opened mru=%d/%d auth=%s magic=%08x/%08x"
235 	    , f->ppp->mru, f->ppp->peer_mru
236 	    , lcp_auth_string(peer_auth)
237 	    , f->ppp->lcp.magic_number, f->ppp->lcp.peer_magic_number
238 	);
239 	lcp_reset_timeout(_this);
240 
241 	ppp_lcp_up(f->ppp);
242 }
243 
244 static void
lcp_down(fsm * f)245 lcp_down(fsm *f)
246 {
247 	lcp *_this;
248 
249 	if (f->ppp->disconnect_code == PPP_DISCON_NO_INFORMATION) {
250 		/*
251 		 * disconnect code is set when we are closing the lcp, so
252 		 * 'no info' means the lcp is going down by peer's termreq.
253 		 */
254 		ppp_set_disconnect_cause(f->ppp, PPP_DISCON_NORMAL, 0,
255 		    1 /* peer */, NULL);
256 #ifdef USE_NPPPD_RADIUS
257 		ppp_set_radius_terminate_cause(f->ppp,
258 		    RADIUS_TERMNATE_CAUSE_USER_REQUEST);
259 #endif
260 	}
261 
262 	_this = &f->ppp->lcp;
263 	UNTIMEOUT(lcp_timeout, _this);
264 }
265 
266 static void
lcp_finished(fsm * f)267 lcp_finished(fsm *f)
268 {
269 	ppp_lcp_finished(f->ppp);
270 }
271 
272 /**
273  * resetting ConfReq.
274  */
275 static void
lcp_resetci(fsm * f)276 lcp_resetci(fsm *f)
277 {
278 	LCP_ASSERT(f != NULL);
279 
280 	/* Unless doing dialin-proxy without re-negotiation */
281 	if (!(f->ppp->lcp.dialin_proxy != 0 &&
282 	    f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0)) {
283 
284 		/* Reset the LCP options' state */
285 		memset(&f->ppp->lcp.opt, 0, sizeof(f->ppp->lcp.opt));
286 		f->ppp->lcp.auth_order[0] = -1;
287 	}
288 }
289 
290 /**
291  * The length of ConfReq.
292  */
293 static int
lcp_cilen(fsm * f)294 lcp_cilen(fsm *f)
295 {
296 	LCP_ASSERT(f != NULL);
297 	return f->ppp->mru;
298 }
299 
300 /**
301  * selecting authentication protocols which is not rejected yet in order
302  * of auth_order, and adding Authentication-Protocol options in ConfReq
303  * packet area.
304  */
305 static int
lcp_add_auth(fsm * f,u_char ** ucpp)306 lcp_add_auth(fsm *f, u_char **ucpp)
307 {
308 	int i;
309 	u_char *ucp;
310 	lcp *_this;
311 
312 	ucp = *ucpp;
313 	_this = &f->ppp->lcp;
314 
315 	for (i = 0; _this->auth_order[i] > 0 &&
316 	    i < countof(_this->auth_order); i++) {
317 		switch (_this->auth_order[i]) {
318 		case PPP_AUTH_PAP:
319 			if (psm_opt_is_rejected(_this, pap))
320 				break;
321 			PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
322 			PUTCHAR(4, ucp);
323 			PUTSHORT(PPP_AUTH_PAP, ucp);
324 			psm_opt_set_requested(_this, pap, 1);
325 			_this->lastauth = PPP_AUTH_PAP;
326 			goto end_loop;
327 		case PPP_AUTH_CHAP_MD5:
328 			if (psm_opt_is_rejected(_this, chap))
329 				break;
330 			PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
331 			PUTCHAR(5, ucp);
332 			PUTSHORT(PPP_AUTH_CHAP, ucp);
333 			PUTCHAR(PPP_AUTH_CHAP_MD5, ucp);
334 			psm_opt_set_requested(_this, chap, 1);
335 			_this->lastauth = PPP_AUTH_CHAP_MD5;
336 			goto end_loop;
337 		case PPP_AUTH_CHAP_MS:
338 			if (psm_opt_is_rejected(_this, chapms))
339 				break;
340 			PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
341 			PUTCHAR(5, ucp);
342 			PUTSHORT(PPP_AUTH_CHAP, ucp);
343 			PUTCHAR(PPP_AUTH_CHAP_MS, ucp);
344 			psm_opt_set_requested(_this, chapms, 1);
345 			_this->lastauth = PPP_AUTH_CHAP_MS;
346 			goto end_loop;
347 		case PPP_AUTH_CHAP_MS_V2:
348 			if (psm_opt_is_rejected(_this, chapms_v2))
349 				break;
350 			PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
351 			PUTCHAR(5, ucp);
352 			PUTSHORT(PPP_AUTH_CHAP, ucp);
353 			PUTCHAR(PPP_AUTH_CHAP_MS_V2, ucp);
354 			psm_opt_set_requested(_this, chapms_v2,1);
355 			_this->lastauth = PPP_AUTH_CHAP_MS_V2;
356 			goto end_loop;
357                 case PPP_AUTH_EAP:
358                         if (psm_opt_is_rejected(_this, eap))
359                                 break;
360                         PUTCHAR(PPP_LCP_AUTH_PROTOCOL, ucp);
361                         PUTCHAR(4, ucp);
362                         PUTSHORT(PPP_AUTH_EAP, ucp);
363                         psm_opt_set_requested(_this, eap, 1);
364                         _this->lastauth = PPP_AUTH_EAP;
365                         goto end_loop;
366 		}
367 	}
368 	_this->lastauth = -1;
369 	return -1;
370 end_loop:
371 	*ucpp = ucp;
372 
373 	return 0;
374 }
375 
376 /**
377  * making ConfReq.
378  */
379 static void
lcp_addci(fsm * f,u_char * ucp,int * lenp)380 lcp_addci(fsm *f, u_char *ucp, int *lenp)
381 {
382 	lcp *_this;
383 	u_char *start_ucp = ucp;
384 
385 	LCP_ASSERT(f != NULL);
386 
387 	_this = &f->ppp->lcp;
388 	if (!psm_opt_is_rejected(_this, mru)) {
389 		PUTCHAR(PPP_LCP_MRU, ucp);
390 		PUTCHAR(4, ucp);
391 
392 		if (_this->xxxmru > 0) {	/* this value is got by Nak. */
393 			PUTSHORT(_this->xxxmru, ucp);
394 		} else {
395 			PUTSHORT(f->ppp->mru, ucp);
396 		}
397 		psm_opt_set_requested(_this, mru, 1);
398 	}
399 	if (f->ppp->has_acf == 1) {
400 		if (!psm_opt_is_rejected(_this, pfc)) {
401 			PUTCHAR(PPP_LCP_PFC, ucp);
402 			PUTCHAR(2, ucp);
403 			psm_opt_set_requested(_this, pfc, 1);
404 		}
405 		if (!psm_opt_is_rejected(_this, acfc)) {
406 			PUTCHAR(PPP_LCP_ACFC, ucp);
407 			PUTCHAR(2, ucp);
408 			psm_opt_set_requested(_this, acfc, 1);
409 		}
410 	}
411 	PUTCHAR(PPP_LCP_MAGICNUMBER, ucp);
412 	PUTCHAR(6, ucp);
413 	PUTLONG(_this->magic_number, ucp);
414 
415 	if (f->ppp->peer_auth != 0) {
416 		_this->auth_order[0] = f->ppp->peer_auth;
417 		_this->auth_order[1] = -1;
418 	} else if (_this->auth_order[0] < 0) {
419 		lcp_load_authconfig(f);
420 	}
421 
422 	lcp_add_auth(f, &ucp);
423 	*lenp = ucp - start_ucp;
424 }
425 
426 static int
lcp_reqci(fsm * f,u_char * inp,int * lenp,int reject_if_disagree)427 lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree)
428 {
429 	uint32_t magic;
430 	int type, len, rcode, mru, lrej;
431 	u_char *inp0, *rejbuf, *nakbuf, *nakbuf0;
432 	lcp *_this;
433 
434 	_this = &f->ppp->lcp;
435 	rejbuf = NULL;
436 	rcode = -1;
437 	inp0 = inp;
438 	lrej = 0;
439 
440 	if ((rejbuf = malloc(*lenp)) == NULL)
441 		return -1;
442 	if ((nakbuf0 = malloc(*lenp)) == NULL) {
443 		free(rejbuf);
444 		return -1;
445 	}
446 	nakbuf = nakbuf0;
447 
448 #define	remlen()	(*lenp - (inp - inp0))
449 #define	LCP_OPT_PEER_ACCEPTED(opt)				\
450 	psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1);
451 
452 	f->ppp->lcp.recv_reqs++;
453 
454 	while (remlen() >= 2) {
455 		GETCHAR(type, inp);
456 		GETCHAR(len, inp);
457 		if (len <= 0 || remlen() + 2 < len)
458 			goto fail;
459 
460 		switch (type) {
461 		case PPP_LCP_MRU:
462 			if (len != 4)
463 				goto fail;
464 			GETSHORT(mru, inp);
465 			f->ppp->peer_mru = mru;
466 			if (mru < NPPPD_MIN_MRU) {
467 				if (reject_if_disagree) {
468 					inp -= 2;
469 					goto reject;
470 				}
471 				if (lrej > 0) {
472 				/* if there is a reject, will send Rej, not send Nak. */
473 				} else {
474 					inp -= 2;
475 					memcpy(nakbuf, inp, len);
476 					nakbuf += len;
477 					inp += 2;
478 					PUTSHORT(f->ppp->mru, nakbuf);
479 
480 					rcode = CONFNAK;
481 				}
482 			} else
483 				LCP_OPT_PEER_ACCEPTED(mru);
484 			break;
485 		case PPP_LCP_MAGICNUMBER:
486 			if (len != 6)
487 				goto fail;
488 			GETLONG(magic, inp);
489 			if (magic == _this->magic_number) {
490 				inp -= 4;
491 				goto reject;
492 			}
493 			_this->peer_magic_number = magic;
494 			break;
495 		case PPP_LCP_PFC:
496 			if (len != 2)
497 				goto fail;
498 			LCP_OPT_PEER_ACCEPTED(pfc);
499 			break;
500 		case PPP_LCP_ACFC:
501 			if (len != 2)
502 				goto fail;
503 			LCP_OPT_PEER_ACCEPTED(acfc);
504 			break;
505 		case PPP_LCP_AUTH_PROTOCOL:
506 			/* currently never authenticate. */
507 		case PPP_LCP_QUALITY_PROTOCOL:	/* not used */
508 		default:
509 reject:
510 			inp -= 2;
511 			memcpy(rejbuf + lrej, inp, len);
512 			lrej += len;
513 			inp += len;
514 			rcode = CONFREJ;
515 		}
516 		continue;
517 	}
518 	if (rcode == -1)
519 		rcode = CONFACK;
520 fail:
521 	switch (rcode) {
522 	case CONFREJ:
523 		memcpy(inp0, rejbuf, lrej);
524 		*lenp = lrej;
525 		break;
526 	case CONFNAK:
527 		memcpy(inp0, nakbuf0, nakbuf - nakbuf0);
528 		*lenp = nakbuf - nakbuf0;
529 		break;
530 	}
531 	if (rcode != CONFACK) {
532 		psm_peer_opt_set_accepted(&f->ppp->lcp, mru, 0);
533 		psm_peer_opt_set_accepted(&f->ppp->lcp, pfc, 0);
534 		psm_peer_opt_set_accepted(&f->ppp->lcp, acfc, 0);
535 	}
536 	free(rejbuf);
537 	free(nakbuf0);
538 
539 	return rcode;
540 #undef	remlen
541 #undef LCP_OPT_PEER_ACCEPTED
542 }
543 
544 /** receiving ConfAck. */
545 static int
lcp_ackci(fsm * f,u_char * inp,int inlen)546 lcp_ackci(fsm *f, u_char *inp, int inlen)
547 {
548 	int chapalg, authproto, type, len, mru, magic;
549 	u_char *inp0;
550 
551 #define	remlen()	(inlen - (inp - inp0))
552 #define	LCP_OPT_ACCEPTED(opt)				\
553 	if (!psm_opt_is_requested(&f->ppp->lcp, opt))	\
554 		goto fail;				\
555 	psm_opt_set_accepted(&f->ppp->lcp, opt, 1);
556 
557 	f->ppp->lcp.recv_ress++;
558 	inp0 = inp;
559 	while (remlen() >= 2) {
560 		GETCHAR(type, inp);
561 		GETCHAR(len, inp);
562 
563 		if (len <= 0 || remlen() + 2 < len)
564 			goto fail;
565 
566 		switch (type) {
567 		case PPP_LCP_MAGICNUMBER:
568 			if (len != 6)
569 				goto fail;
570 			GETLONG(magic, inp);
571 			if (f->ppp->lcp.magic_number != magic)
572 				goto fail;
573 			break;
574 		case PPP_LCP_MRU:
575 			if (len != 4)
576 				goto fail;
577 			LCP_OPT_ACCEPTED(mru);
578 			GETSHORT(mru, inp);
579 			break;
580 		case PPP_LCP_AUTH_PROTOCOL:
581 			if (len < 4)
582 				goto fail;
583 			GETSHORT(authproto, inp);
584 			switch (authproto) {
585 			case PPP_AUTH_PAP:
586 				if (len != 4)
587 					goto fail;
588 				LCP_OPT_ACCEPTED(pap);
589 				break;
590 			case PPP_AUTH_CHAP:
591 				if (len != 5)
592 					goto fail;
593 				GETCHAR(chapalg, inp);
594 				switch (chapalg) {
595 				case PPP_AUTH_CHAP_MD5:
596 					LCP_OPT_ACCEPTED(chap);
597 					break;
598 				case PPP_AUTH_CHAP_MS:
599 					LCP_OPT_ACCEPTED(chapms);
600 					break;
601 				case PPP_AUTH_CHAP_MS_V2:
602 					LCP_OPT_ACCEPTED(chapms_v2);
603 					break;
604 				}
605 				break;
606                         case PPP_AUTH_EAP:
607                                 if (len != 4)
608                                      goto fail;
609                                 LCP_OPT_ACCEPTED(eap);
610                                 break;
611 			}
612 			break;
613 
614 		/*
615 		 * As RFC1661, ConfRej must be used for boolean options, but
616 		 * at least RouterTester uses ConfNak for them.
617 		 */
618 		case PPP_LCP_PFC:
619 			if (len != 2)
620 				goto fail;
621 			LCP_OPT_ACCEPTED(pfc);
622 			break;
623 		case PPP_LCP_ACFC:
624 			if (len != 2)
625 				goto fail;
626 			LCP_OPT_ACCEPTED(acfc);
627 			break;
628 
629 		default:
630 			goto fail;
631 		}
632 	}
633 	return 1;
634 fail:
635 	fsm_log(f, LOG_ERR, "Received unexpected ConfAck.");
636 	if (debug_get_debugfp() != NULL)
637 		show_hd(debug_get_debugfp(), inp, remlen());
638 	return 0;
639 #undef	LCP_OPT_ACCEPTED
640 }
641 
642 /** receiving ConfNak. */
643 static int
lcp_nakci(fsm * f,u_char * inp,int inlen)644 lcp_nakci(fsm *f, u_char *inp, int inlen)
645 {
646 	int chapalg, authproto, type, len, mru;
647 	u_char *inp0;
648 	lcp *_this;
649 	const char *peer_auth = "unknown";
650 
651 #define	remlen()	(inlen - (inp - inp0))
652 #define	LCP_OPT_REJECTED(opt)				\
653 	if (!psm_opt_is_requested(&f->ppp->lcp, opt))	\
654 		goto fail;				\
655 	psm_opt_set_rejected(&f->ppp->lcp, opt, 1);
656 
657 	f->ppp->lcp.recv_ress++;
658 	inp0 = inp;
659 	_this = &f->ppp->lcp;
660 	while (remlen() >= 2) {
661 		GETCHAR(type, inp);
662 		GETCHAR(len, inp);
663 
664 		if (len <= 0 || remlen() + 2 < len)
665 			goto fail;
666 
667 		switch (type) {
668 		case PPP_LCP_MRU:
669 			if (len < 4)
670 				goto fail;
671 			GETSHORT(mru, inp);
672 			fsm_log(f, LOG_NOTICE,
673 			    "ignored ConfNak from the peer: mru=%d", mru);
674 			_this->xxxmru = mru;
675 			break;
676 		case PPP_LCP_AUTH_PROTOCOL:
677 			if (len < 4)
678 				goto fail;
679 			switch (_this->lastauth) {
680 			case PPP_AUTH_PAP:
681 				psm_opt_set_rejected(_this, pap, 1);
682 				break;
683 			case PPP_AUTH_CHAP_MD5:
684 				psm_opt_set_rejected(_this, chap, 1);
685 				break;
686 			case PPP_AUTH_CHAP_MS:
687 				psm_opt_set_rejected(_this, chapms, 1);
688 				break;
689 			case PPP_AUTH_CHAP_MS_V2:
690 				psm_opt_set_rejected(_this, chapms_v2, 1);
691 				break;
692                         case PPP_AUTH_EAP:
693                                 psm_opt_set_rejected(_this, eap, 1);
694                                 break;
695 			}
696 			GETSHORT(authproto, inp);
697 			switch (authproto) {
698 			case PPP_AUTH_PAP:
699 				if (psm_opt_is_requested(_this, pap))
700 					psm_opt_set_accepted(_this, pap, 1);
701 				peer_auth = "pap";
702 				break;
703 			case PPP_AUTH_CHAP:
704 				chapalg = 0;
705 				if (len == 5)
706 					GETCHAR(chapalg, inp);
707 				switch (chapalg) {
708 				case PPP_AUTH_CHAP_MD5:
709 					if (psm_opt_is_requested(_this, chap))
710 						psm_opt_set_accepted(_this,
711 						    chap, 1);
712 					peer_auth = "chap";
713 					break;
714 				case PPP_AUTH_CHAP_MS:
715 					if (psm_opt_is_requested(_this, chapms))
716 						psm_opt_set_accepted(_this,
717 						    chapms, 1);
718 					peer_auth = "mschap";
719 					break;
720 				case PPP_AUTH_CHAP_MS_V2:
721 					if (psm_opt_is_requested(_this,
722 					    chapms_v2))
723 						psm_opt_set_accepted(_this,
724 						    chapms_v2, 1);
725 					peer_auth = "mschap_v2";
726 					break;
727 				default:
728 					fsm_log(f, LOG_INFO,
729 					    "Nacked chap algorithm is "
730 					    "unknown(%d).", chapalg);
731 					peer_auth = "unknown";
732 					break;
733 				}
734 				break;
735                         case PPP_AUTH_EAP:
736                                 if (len != 4)
737                                         goto fail;
738                                 peer_auth = "eap";
739 				if (psm_opt_is_requested(_this, eap))
740 					psm_opt_set_accepted(_this, eap, 1);
741                                 break;
742 			}
743 			if (NO_AUTH_AGREEABLE(_this)) {
744 				fsm_log(f, LOG_INFO, "No authentication "
745 				    "protocols are agreeable.  peer's "
746 				    "auth proto=%s",
747 				    peer_auth);
748 				ppp_set_disconnect_cause(f->ppp,
749 				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
750 				    authproto, 2 /* couldn't accept peer's */,
751 				    NULL);
752 				ppp_stop(f->ppp, "Authentication is required");
753 				return 1;
754 			}
755 			break;
756 		case PPP_LCP_PFC:
757 			if (len != 2)
758 				goto fail;
759 			LCP_OPT_REJECTED(pfc);
760 			break;
761 		case PPP_LCP_ACFC:
762 			if (len != 2)
763 				goto fail;
764 			LCP_OPT_REJECTED(acfc);
765 			break;
766 		default:
767 			goto fail;
768 		}
769 	}
770 	return 1;
771 fail:
772 	log_printf(LOG_ERR, "Received unexpected ConfNak.");
773 	if (debug_get_debugfp() != NULL)
774 		show_hd(debug_get_debugfp(), inp, inlen);
775 	return 0;
776 #undef remlen
777 #undef LCP_OPT_REJECTED
778 }
779 
780 /**
781  * receiving ConfRej.
782  */
783 static int
lcp_rejci(fsm * f,u_char * inp,int inlen)784 lcp_rejci(fsm *f, u_char *inp, int inlen)
785 {
786 	int chapalg, authproto, type, len, mru;
787 	u_char *inp0;
788 	lcp *_this;
789 
790 #define	remlen()	(inlen - (inp - inp0))
791 #define	LCP_OPT_REJECTED(opt)				\
792 	if (!psm_opt_is_requested(&f->ppp->lcp, opt))	\
793 		goto fail;				\
794 	psm_opt_set_rejected(&f->ppp->lcp, opt, 1);
795 
796 	f->ppp->lcp.recv_ress++;
797 	inp0 = inp;
798 	_this = &f->ppp->lcp;
799 	while (remlen() >= 2) {
800 		GETCHAR(type, inp);
801 		GETCHAR(len, inp);
802 
803 		if (len <= 0 || remlen() + 2 < len)
804 			goto fail;
805 
806 		switch (type) {
807 		case PPP_LCP_MAGICNUMBER:
808 			if (f->ppp->lcp.echo_interval > 0)
809 				goto fail;
810 			inp += 4;
811 			break;
812 		case PPP_LCP_MRU:
813 			LCP_OPT_REJECTED(mru);
814 			GETSHORT(mru, inp);
815 			break;
816 		case PPP_LCP_AUTH_PROTOCOL:
817 			if (len < 4)
818 				goto fail;
819 			GETSHORT(authproto, inp);
820 			switch (authproto) {
821 			case PPP_AUTH_PAP:
822                                 if (len != 4)
823                                         goto fail;
824 				LCP_OPT_REJECTED(pap);
825 				break;
826 			case PPP_AUTH_CHAP:
827 				chapalg = 0;
828 				if (len == 5)
829 					GETCHAR(chapalg, inp);
830 				switch (chapalg) {
831 				case PPP_AUTH_CHAP_MD5:
832 					LCP_OPT_REJECTED(chap);
833 					break;
834 				case PPP_AUTH_CHAP_MS:
835 					LCP_OPT_REJECTED(chapms);
836 					break;
837 				case PPP_AUTH_CHAP_MS_V2:
838 					LCP_OPT_REJECTED(chapms_v2);
839 					break;
840 				default:
841 					fsm_log(f, LOG_INFO,
842 					    "Rejected chap algorithm is "
843 					    "unknown(%d).", chapalg);
844 					break;
845 				}
846 				break;
847                          case PPP_AUTH_EAP:
848                                 if (len != 4)
849                                         goto fail;
850                                 LCP_OPT_REJECTED(eap);
851                                 break;
852 			}
853 			if (NO_AUTH_AGREEABLE(_this)) {
854 				fsm_log(f, LOG_INFO, "No authentication "
855 				    "protocols are agreeable.");
856 				ppp_set_disconnect_cause(f->ppp,
857 				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
858 				    authproto, 1 /* rejected by peer */, NULL);
859 				ppp_stop(f->ppp, "Authentication is required");
860 				return 1;
861 			}
862 			break;
863 		case PPP_LCP_PFC:
864 			if (len != 2)
865 				goto fail;
866 			LCP_OPT_REJECTED(pfc);
867 			break;
868 		case PPP_LCP_ACFC:
869 			if (len != 2)
870 				goto fail;
871 			LCP_OPT_REJECTED(acfc);
872 			break;
873 		default:
874 			goto fail;
875 		}
876 	}
877 	return 1;
878 fail:
879 	log_printf(LOG_ERR, "Received unexpected ConfRej.");
880 	if (debug_get_debugfp() != NULL)
881 		show_hd(debug_get_debugfp(), inp, inlen);
882 	return 0;
883 #undef remlen
884 }
885 
886 static void
lcp_rcoderej(fsm * f,u_char * inp,int inlen)887 lcp_rcoderej(fsm *f, u_char *inp, int inlen)
888 {
889 	uint16_t proto;
890 	fsm *rejfsm;
891 
892 	if (inlen < 2) {
893 		fsm_log(f, LOG_WARNING, "Received short ProtRej packet.");
894 		return;
895 	}
896 	GETSHORT(proto, inp);
897 
898 	rejfsm = NULL;
899 
900 	switch (proto) {
901 	case PPP_PROTO_LCP:
902 		rejfsm = &f->ppp->lcp.fsm;
903 		break;
904 	case PPP_PROTO_PAP:
905 		fsm_log(f, LOG_WARNING, "our PAP packet is rejected");
906 		return;
907 	case PPP_PROTO_CHAP:
908 		fsm_log(f, LOG_WARNING, "our CHAP packet is rejected");
909 		return;
910         case PPP_PROTO_EAP:
911                 fsm_log(f, LOG_ERR, "our EAP packet is rejected");
912                 ppp_stop(f->ppp, "Authentication Required");
913                 break;
914 	case PPP_PROTO_NCP | NCP_IPCP:
915 		rejfsm = &f->ppp->ipcp.fsm;
916 		break;
917 	case PPP_PROTO_NCP | NCP_CCP:
918 		rejfsm = &f->ppp->ccp.fsm;
919 		break;
920 	}
921 	if (rejfsm == NULL) {
922 		fsm_log(f, LOG_WARNING,
923 		    "Received ProtRej packet for unknown protocol=(%d/%04x)",
924 		    proto, proto);
925 		return;
926 	}
927 	fsm_protreject(rejfsm);
928 
929 	return;
930 }
931 
932 static void
lcp_reset_timeout(void * ctx)933 lcp_reset_timeout(void *ctx)
934 {
935 	lcp *_this;
936 
937 	_this = ctx;
938 
939 	if (_this->echo_interval > 0) {
940 		if (_this->echo_failures == 0) {
941 			TIMEOUT(lcp_timeout, _this, _this->echo_interval);
942 		} else {
943 			TIMEOUT(lcp_timeout, _this, _this->echo_retry_interval);
944 		}
945 	} else {
946 		UNTIMEOUT(lcp_timeout, _this);
947 	}
948 }
949 
950 static void
lcp_timeout(void * ctx)951 lcp_timeout(void *ctx)
952 {
953 	lcp *_this;
954 	u_char *cp, buf[32];
955 
956 	_this = ctx;
957 	if (_this->echo_failures >= _this->echo_max_retries) {
958 		fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure.");
959 		if (_this->fsm.ppp != NULL) {
960 #ifdef USE_NPPPD_RADIUS
961 			ppp_set_radius_terminate_cause(_this->fsm.ppp,
962 			    RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
963 #endif
964 			ppp_stop(_this->fsm.ppp, NULL);
965 		}
966 		return;
967 	}
968 	cp = buf;
969 	PUTLONG(_this->magic_number, cp);
970 	fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4);
971 	_this->echo_failures++;
972 
973 	lcp_reset_timeout(_this);
974 }
975 
976 static int
lcp_rechoreq(fsm * f,int id,u_char * inp,int inlen)977 lcp_rechoreq(fsm *f, int id, u_char *inp, int inlen)
978 {
979 	u_char *inp0;
980 	lcp *_this;
981 	int len;
982 
983 	if (inlen < 4)
984 		return 0;
985 
986 	_this = &f->ppp->lcp;
987 	inp0 = inp;
988 	PUTLONG(_this->magic_number, inp)
989 
990 	len = MINIMUM(inlen, f->ppp->peer_mru - 8);
991 	fsm_sdata(f, ECHOREP, id, inp0, len);
992 
993 	return 1;
994 }
995 
996 static int
lcp_ext(fsm * f,int code,int id,u_char * inp,int inlen)997 lcp_ext(fsm *f, int code, int id, u_char *inp, int inlen)
998 {
999 	lcp *_this;
1000 	uint32_t magic;
1001 	char buf[256];
1002 	int i, len;
1003 
1004 	_this = &f->ppp->lcp;
1005 
1006 	switch (code) {
1007 	case IDENTIFICATION:
1008 		/* RFC 1570 */
1009 		if (inlen > 4) {
1010 			GETLONG(magic, inp);
1011 			inlen -= 4;
1012 			memset(buf, 0, sizeof(buf));
1013 			len = MINIMUM(inlen, sizeof(buf) - 1);
1014 			memcpy(buf, inp, len);
1015 			buf[len] = '\0';
1016 			for (i = 0; i < len; i++) {
1017 				if (!isprint((unsigned char)buf[i]))
1018 					buf[i] = '.';
1019 			}
1020 			fsm_log(f, LOG_INFO,
1021 			    "RecvId magic=%08x text=%s", magic, buf);
1022 		}
1023 		return 1;
1024 	case PROTREJ:
1025 		lcp_rcoderej(f, inp, inlen);
1026 		return 1;
1027 	case ECHOREP:
1028 		if (f->state == OPENED) {
1029 			if (inlen >= 4) {
1030 				GETLONG(magic, inp);
1031 				if (_this->peer_magic_number == magic) {
1032 					_this->echo_failures = 0;
1033 					lcp_reset_timeout(_this);
1034 				}
1035 			}
1036 		}
1037 		return 1;
1038 	case ECHOREQ:
1039 		if (f->state == OPENED)
1040 			return lcp_rechoreq(f, id, inp, inlen);
1041 		return 1;
1042 	}
1043 
1044 	return 0;
1045 }
1046 
1047 
1048 /*
1049  * reading some authentication settings and storing ppp_order in
1050  * order of settings.
1051  */
1052 static void
lcp_load_authconfig(fsm * f)1053 lcp_load_authconfig(fsm *f)
1054 {
1055 	int              i;
1056 	lcp             *_this;
1057 	struct tunnconf *conf;
1058 
1059 	i = 0;
1060 	_this = &f->ppp->lcp;
1061 	conf = ppp_get_tunnconf(f->ppp);
1062 	if ((conf->auth_methods & NPPPD_AUTH_METHODS_MSCHAPV2) != 0) {
1063 		_this->auth_order[i++] = PPP_AUTH_CHAP_MS_V2;
1064 		psm_opt_set_enabled(_this,chapms_v2, 1);
1065 	}
1066 	if ((conf->auth_methods & NPPPD_AUTH_METHODS_CHAP) != 0) {
1067 		_this->auth_order[i++] = PPP_AUTH_CHAP_MD5;
1068 		psm_opt_set_enabled(_this, chap, 1);
1069 	}
1070 	if ((conf->auth_methods & NPPPD_AUTH_METHODS_PAP) != 0) {
1071 		_this->auth_order[i++] = PPP_AUTH_PAP;
1072 		psm_opt_set_enabled(_this, pap, 1);
1073 	}
1074 
1075 	_this->auth_order[i] = -1;
1076 }
1077 
1078 /***********************************************************************
1079  * related functions of Dialin Proxy
1080  **********************************************************************/
1081 /**
1082  * This function set LCP status following dialin proxy information.
1083  * This returns non-zero value when LCP status is unacceptable.
1084  *
1085  */
1086 int
lcp_dialin_proxy(lcp * _this,dialin_proxy_info * dpi,int renegotiation,int force_renegotiation)1087 lcp_dialin_proxy(lcp *_this, dialin_proxy_info *dpi, int renegotiation,
1088     int force_renegotiation)
1089 {
1090 	int i, authok;
1091 
1092 	_this->dialin_proxy = 1;
1093 	lcp_load_authconfig(&_this->fsm);
1094 
1095 	/* whether authentication type is permitted by configuration or not. */
1096 	authok = 0;
1097 	if (dpi->auth_type != 0) {
1098 		for (i = 0; _this->auth_order[i] > 0; i++) {
1099 			if (_this->auth_order[i] != dpi->auth_type)
1100 				continue;
1101 			authok = 1;
1102 			break;
1103 		}
1104 	}
1105 	if (!authok) {
1106 		if (!renegotiation) {
1107 			fsm_log(&_this->fsm, LOG_NOTICE,
1108 			    "dialin-proxy failed.  auth-method=%s is "
1109 			    "not enabled.  Try 'l2tp.dialin.lcp_renegotion'",
1110 			    lcp_auth_string(dpi->auth_type));
1111 			return 1;
1112 		}
1113 		_this->dialin_proxy_lcp_renegotiation = 1;
1114 	}
1115 	if (force_renegotiation)
1116 		_this->dialin_proxy_lcp_renegotiation = 1;
1117 
1118 	if (_this->dialin_proxy_lcp_renegotiation == 0) {
1119 		_this->fsm.ppp->peer_auth = dpi->auth_type;
1120 		/*
1121 		 * Set the rejected flag to all options here for the moment,
1122 		 * the agreeed options will be handled in lcp_proxy_sent_ci().
1123 		 */
1124 		psm_opt_set_rejected(_this, mru, 1);
1125 		psm_opt_set_rejected(_this, pfc, 1);
1126 		psm_opt_set_rejected(_this, acfc, 1);
1127 		psm_opt_set_rejected(_this, pap, 1);
1128 		psm_opt_set_rejected(_this, chap, 1);
1129 		psm_opt_set_rejected(_this, chapms, 1);
1130 		psm_opt_set_rejected(_this, chapms_v2, 1);
1131 		psm_opt_set_rejected(_this, eap, 1);
1132 
1133 	}
1134 	switch (dpi->auth_type) {
1135 	case PPP_AUTH_PAP:
1136 		pap_proxy_authen_prepare(&_this->fsm.ppp->pap, dpi);
1137 		break;
1138 	case PPP_AUTH_CHAP_MD5:
1139 		chap_proxy_authen_prepare(&_this->fsm.ppp->chap, dpi);
1140 		break;
1141 	}
1142 	if (lcp_proxy_sent_ci(&_this->fsm, dpi->last_sent_lcp.data,
1143 	    dpi->last_sent_lcp.ldata) != 0) {
1144 		fsm_log(&_this->fsm, LOG_NOTICE,
1145 		    "dialin-proxy failed.  couldn't use proxied lcp.");
1146 		return 1;
1147 	}
1148 	if (lcp_proxy_recv_ci(&_this->fsm, dpi->last_recv_lcp.data,
1149 	    dpi->last_recv_lcp.ldata) != 0) {
1150 		fsm_log(&_this->fsm, LOG_NOTICE,
1151 		    "dialin-proxy failed.  couldn't use proxied lcp.");
1152 		return 1;
1153 	}
1154 
1155 	fsm_log(&_this->fsm, LOG_INFO,
1156 	    "dialin-proxy user=%s auth-type=%s renegotiate=%s",
1157 	    dpi->username,
1158 	    (dpi->auth_type == 0)? "none" : lcp_auth_string(dpi->auth_type),
1159 	    (_this->dialin_proxy_lcp_renegotiation != 0)? "yes" : "no");
1160 
1161 
1162 	if (_this->dialin_proxy_lcp_renegotiation == 0)
1163 		_this->fsm.flags |= OPT_SILENT;	/* It's ready to be "Opened" */
1164 	else
1165 		_this->fsm.flags &= ~OPT_SILENT;
1166 
1167 	return 0;
1168 }
1169 
1170 /*
1171  * This function copies from lcp_reqci. It only differs as follows:
1172  *	- changes LCP_OPT_ACCEPTED.
1173  *	- Magic Number and MRU.
1174  */
1175 static int
lcp_proxy_recv_ci(fsm * f,u_char * inp,int inlen)1176 lcp_proxy_recv_ci(fsm *f, u_char *inp, int inlen)
1177 {
1178 	int type, mru, len;
1179 	uint32_t magic;
1180 	u_char *inp0;
1181 	lcp *_this;
1182 
1183 #define	remlen()	(inlen - (inp - inp0))
1184 #define	LCP_OPT_PEER_ACCEPTED(opt)				\
1185 	psm_peer_opt_set_rejected(&f->ppp->lcp, opt, 0);	\
1186 	psm_peer_opt_set_requested(&f->ppp->lcp, opt, 1);	\
1187 	psm_peer_opt_set_accepted(&f->ppp->lcp, opt, 1);
1188 
1189 	_this = &f->ppp->lcp;
1190 	inp0 = inp;
1191 
1192 	while (remlen() >= 2) {
1193 		GETCHAR(type, inp);
1194 		GETCHAR(len, inp);
1195 		if (len <= 0 || remlen() + 2 < len)
1196 			goto fail;
1197 
1198 		switch (type) {
1199 		case PPP_LCP_MRU:
1200 			if (len != 4)
1201 				goto fail;
1202 			GETSHORT(mru, inp);
1203 			f->ppp->peer_mru = mru;
1204 			if (mru < NPPPD_MIN_MRU)
1205 				goto fail;
1206 			else
1207 				LCP_OPT_PEER_ACCEPTED(mru);
1208 			break;
1209 		case PPP_LCP_MAGICNUMBER:
1210 			if (len != 6)
1211 				goto fail;
1212 			GETLONG(magic, inp);
1213 			if (magic == _this->magic_number)
1214 				goto fail;
1215 			_this->peer_magic_number = magic;
1216 			break;
1217 		case PPP_LCP_PFC:
1218 			if (len != 2)
1219 				goto fail;
1220 			LCP_OPT_PEER_ACCEPTED(pfc);
1221 			break;
1222 		case PPP_LCP_ACFC:
1223 			if (len != 2)
1224 				goto fail;
1225 			LCP_OPT_PEER_ACCEPTED(acfc);
1226 			break;
1227 		case PPP_LCP_ACCM:
1228 			if (len != 6)
1229 				goto fail;
1230 			/* we don't use async framing.  ignore this */
1231 			inp += (len - 2);
1232 			break;
1233 		default:
1234 			goto fail;
1235 		}
1236 	}
1237 
1238 #undef remlen
1239 #undef LCP_OPT_PEER_ACCEPTED
1240 	return 0;
1241 fail:
1242 	return 1;
1243 }
1244 
1245 /*
1246  * This function copies from lcp_ackci. It only differs as follows:
1247  *	- Do not recv_reass++.
1248  *	- changes LCP_OPT_ACCEPTED.
1249  *	- Magic Number and MRU.
1250  */
1251 static int
lcp_proxy_sent_ci(fsm * f,u_char * inp,int inlen)1252 lcp_proxy_sent_ci(fsm *f, u_char *inp, int inlen)
1253 {
1254 	int chapalg, authproto, type, len, mru, magic;
1255 	u_char *inp0;
1256 
1257 #define	remlen()	(inlen - (inp - inp0))
1258 #define	LCP_OPT_ACCEPTED(opt)					\
1259 	if (f->ppp->lcp.dialin_proxy_lcp_renegotiation == 0) {	\
1260 		psm_opt_set_rejected(&f->ppp->lcp, opt, 0);	\
1261 		psm_opt_set_requested(&f->ppp->lcp, opt, 1);	\
1262 		psm_opt_set_accepted(&f->ppp->lcp, opt, 1);	\
1263 	}
1264 
1265 	inp0 = inp;
1266 	while (remlen() >= 2) {
1267 		GETCHAR(type, inp);
1268 		GETCHAR(len, inp);
1269 
1270 		if (len <= 0 || remlen() + 2 < len)
1271 			goto fail;
1272 
1273 		switch (type) {
1274 		case PPP_LCP_MAGICNUMBER:
1275 			if (len != 6)
1276 				goto fail;
1277 			GETLONG(magic, inp);
1278 			f->ppp->lcp.magic_number = magic;
1279 			break;
1280 		case PPP_LCP_MRU:
1281 			if (len != 4)
1282 				goto fail;
1283 			LCP_OPT_ACCEPTED(mru);
1284 			GETSHORT(mru, inp);
1285 			f->ppp->lcp.xxxmru = mru;
1286 			break;
1287 		case PPP_LCP_AUTH_PROTOCOL:
1288 			if (len < 4)
1289 				goto fail;
1290 			GETSHORT(authproto, inp);
1291 			switch (authproto) {
1292 			case PPP_AUTH_PAP:
1293 				if (len != 4)
1294 					goto fail;
1295 				LCP_OPT_ACCEPTED(pap);
1296 				break;
1297 			case PPP_AUTH_CHAP:
1298 				if (len != 5)
1299 					goto fail;
1300 				GETCHAR(chapalg, inp);
1301 				switch (chapalg) {
1302 				case PPP_AUTH_CHAP_MD5:
1303 					LCP_OPT_ACCEPTED(chap);
1304 					break;
1305 				case PPP_AUTH_CHAP_MS:
1306 					LCP_OPT_ACCEPTED(chapms);
1307 					break;
1308 				case PPP_AUTH_CHAP_MS_V2:
1309 					LCP_OPT_ACCEPTED(chapms_v2);
1310 					break;
1311 				}
1312 				break;
1313                         case PPP_AUTH_EAP:
1314                                 if (len != 4)
1315                                      goto fail;
1316                                 LCP_OPT_ACCEPTED(eap);
1317                                 break;
1318 			}
1319 			break;
1320 		case PPP_LCP_PFC:
1321 			if (len != 2)
1322 				goto fail;
1323 			LCP_OPT_ACCEPTED(pfc);
1324 			break;
1325 		case PPP_LCP_ACFC:
1326 			if (len != 2)
1327 				goto fail;
1328 			LCP_OPT_ACCEPTED(acfc);
1329 			break;
1330 		case PPP_LCP_ACCM:
1331 			if (len != 6)
1332 				goto fail;
1333 			/* we don't use async framing.  ignore this */
1334 			inp += (len - 2);
1335 			break;
1336 		default:
1337 			goto fail;
1338 		}
1339 	}
1340 	return 0;
1341 fail:
1342 	return 1;
1343 #undef	LCP_OPT_ACCEPTED
1344 }
1345