X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Flcp.c;h=1923c6d4cc0cc9b467b76b7642c4804e424c90b7;hb=dcc1a96716db2df51eb4f593c9e862433298de5c;hp=d708c2709eacab958780c41e703942ed73957261;hpb=37a8acc7ee2527693d0c8ba82b2eaea249abde34;p=ppp.git diff --git a/pppd/lcp.c b/pppd/lcp.c index d708c27..1923c6d 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: lcp.c,v 1.57 2001/03/08 05:11:14 paulus Exp $" +#define RCSID "$Id: lcp.c,v 1.62 2002/09/24 11:35:22 fcusack Exp $" /* * TODO: @@ -327,7 +327,6 @@ lcp_init(unit) wo->neg_mru = 1; wo->mru = DEFMRU; wo->neg_asyncmap = 1; - wo->chap_mdtype = CHAP_DIGEST_MD5; wo->neg_magicnumber = 1; wo->neg_pcompression = 1; wo->neg_accompression = 1; @@ -337,7 +336,7 @@ lcp_init(unit) ao->mru = MAXMRU; ao->neg_asyncmap = 1; ao->neg_chap = 1; - ao->chap_mdtype = CHAP_DIGEST_MD5; + ao->chap_mdtype = MDTYPE_ALL; ao->neg_upap = 1; ao->neg_magicnumber = 1; ao->neg_pcompression = 1; @@ -677,12 +676,12 @@ lcp_addci(f, ucp, lenp) PUTCHAR(CILEN_SHORT, ucp); \ PUTSHORT(val, ucp); \ } -#define ADDCICHAP(opt, neg, val, digest) \ +#define ADDCICHAP(opt, neg, val) \ if (neg) { \ - PUTCHAR(opt, ucp); \ + PUTCHAR((opt), ucp); \ PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, ucp); \ + PUTSHORT(PPP_CHAP, ucp); \ + PUTCHAR((CHAP_DIGEST(val)), ucp); \ } #define ADDCILONG(opt, neg, val) \ if (neg) { \ @@ -716,7 +715,7 @@ lcp_addci(f, ucp, lenp) ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); @@ -795,20 +794,20 @@ lcp_ackci(f, p, len) if (cichar != val) \ goto bad; \ } -#define ACKCICHAP(opt, neg, val, digest) \ +#define ACKCICHAP(opt, neg, val) \ if (neg) { \ if ((len -= CILEN_CHAP) < 0) \ goto bad; \ GETCHAR(citype, p); \ GETCHAR(cilen, p); \ if (cilen != CILEN_CHAP || \ - citype != opt) \ + citype != (opt)) \ goto bad; \ GETSHORT(cishort, p); \ - if (cishort != val) \ + if (cishort != PPP_CHAP) \ goto bad; \ GETCHAR(cichar, p); \ - if (cichar != digest) \ + if (cichar != (CHAP_DIGEST(val))) \ goto bad; \ } #define ACKCILONG(opt, neg, val) \ @@ -863,7 +862,7 @@ lcp_ackci(f, p, len) ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, go->asyncmap); - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); @@ -1035,7 +1034,7 @@ lcp_nakci(f, p, len) no.neg_chap = go->neg_chap; no.neg_upap = go->neg_upap; INCPTR(2, p); - GETSHORT(cishort, p); + GETSHORT(cishort, p); if (cishort == PPP_PAP && cilen == CILEN_SHORT) { /* * If we were asking for CHAP, they obviously don't want to do it. @@ -1050,18 +1049,25 @@ lcp_nakci(f, p, len) GETCHAR(cichar, p); if (go->neg_chap) { /* - * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we can ask for M$-CHAP - * if we support it, otherwise we'll have to stop - * asking for CHAP. + * We were asking for our preferred algorithm, they must + * want something different. */ - if (cichar != go->chap_mdtype) { -#ifdef CHAPMS - if (cichar == CHAP_MICROSOFT) - go->chap_mdtype = CHAP_MICROSOFT; - else -#endif /* CHAPMS */ - try.neg_chap = 0; + if (cichar != CHAP_DIGEST(go->chap_mdtype)) { + if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { + /* Use their suggestion if we support it ... */ + go->chap_mdtype = CHAP_MDTYPE_D(cichar); + } else { + /* ... otherwise, try our next-preferred algorithm. */ + try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype)); + if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */ + try.neg_chap = 0; + } + } else { + /* + * Whoops, they Nak'd our algorithm of choice + * but then suggested it back to us. + */ + goto bad; } } else { /* @@ -1294,7 +1300,7 @@ lcp_rejci(f, p, len) goto bad; \ try.neg = 0; \ } -#define REJCICHAP(opt, neg, val, digest) \ +#define REJCICHAP(opt, neg, val) \ if (go->neg && \ len >= CILEN_CHAP && \ p[1] == CILEN_CHAP && \ @@ -1304,7 +1310,7 @@ lcp_rejci(f, p, len) GETSHORT(cishort, p); \ GETCHAR(cichar, p); \ /* Check rejected value. */ \ - if (cishort != val || cichar != digest) \ + if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ goto bad; \ try.neg = 0; \ try.neg_upap = 0; \ @@ -1370,7 +1376,7 @@ lcp_rejci(f, p, len) REJCISHORT(CI_MRU, neg_mru, go->mru); REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); - REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); + REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); if (!go->neg_chap) { REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); } @@ -1527,7 +1533,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) * for UPAP, then we will reject the second request. * Whether we end up doing CHAP or UPAP depends then on * the ordering of the CIs in the peer's Configure-Request. - */ + */ if (cishort == PPP_PAP) { if (ho->neg_chap || /* we've already accepted CHAP */ @@ -1541,9 +1547,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTCHAR(CI_AUTHTYPE, nakp); PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - /* XXX if we can do CHAP_MICROSOFT as well, we should - probably put in another option saying so */ + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); break; } ho->neg_upap = 1; @@ -1563,20 +1567,20 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) PUTSHORT(PPP_PAP, nakp); break; } - GETCHAR(cichar, p); /* get digest type*/ - if (cichar != CHAP_DIGEST_MD5 -#ifdef CHAPMS - && cichar != CHAP_MICROSOFT -#endif - ) { + GETCHAR(cichar, p); /* get digest type */ + if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { + /* + * We can't/won't do the requested type, + * suggest something else. + */ orc = CONFNAK; PUTCHAR(CI_AUTHTYPE, nakp); PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); break; } - ho->chap_mdtype = cichar; /* save md type */ + ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ ho->neg_chap = 1; break; } @@ -1591,7 +1595,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) if (ao->neg_chap) { PUTCHAR(CILEN_CHAP, nakp); PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp); } else { PUTCHAR(CILEN_SHORT, nakp); PUTSHORT(PPP_PAP, nakp); @@ -1771,7 +1775,7 @@ lcp_up(f) lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; - int mtu; + int mtu, mru; if (!go->neg_magicnumber) go->magicnumber = 0; @@ -1784,18 +1788,19 @@ lcp_up(f) * set our MRU to the larger of value we wanted and * the value we got in the negotiation. * Note on the MTU: the link MTU can be the MRU the peer wanted, - * the interface MTU is set to the lower of that and the - * MTU we want to use. + * the interface MTU is set to the lowest of that, the + * MTU we want to use, and our link MRU. */ mtu = ho->neg_mru? ho->mru: PPP_MRU; + mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; #ifdef HAVE_MULTILINK if (!(multilink && go->neg_mrru && ho->neg_mrru)) #endif /* HAVE_MULTILINK */ - netif_set_mtu(f->unit, MIN(mtu, ao->mru)); + netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru)); ppp_send_config(f->unit, mtu, (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), + ppp_recv_config(f->unit, mru, (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), go->neg_pcompression, go->neg_accompression); @@ -1939,7 +1944,12 @@ lcp_printpkt(p, plen, printer, arg) break; #ifdef CHAPMS case CHAP_MICROSOFT: - printer(arg, " m$oft"); + printer(arg, " MS"); + ++p; + break; + + case CHAP_MICROSOFT_V2: + printer(arg, " MS-v2"); ++p; break; #endif