diff -ruNp ppp-2.4.4.orig/pppd/auth.c ppp-2.4.4/pppd/auth.c --- ppp-2.4.4.orig/pppd/auth.c 2006-06-18 14:26:00.000000000 +0300 +++ ppp-2.4.4/pppd/auth.c 2008-02-13 18:24:08.000000000 +0200 @@ -875,7 +875,7 @@ start_networks(unit) */ ecp_required = ecp_gotoptions[unit].required; mppe_required = ccp_gotoptions[unit].mppe; - if (!ecp_required && !mppe_required) + if (!ecp_required && (!mppe_required || allow_mppe_fallback)) continue_networks(unit); } diff -ruNp ppp-2.4.4.orig/pppd/ccp.c ppp-2.4.4/pppd/ccp.c --- ppp-2.4.4.orig/pppd/ccp.c 2005-07-09 03:23:05.000000000 +0300 +++ ppp-2.4.4/pppd/ccp.c 2008-02-13 18:31:16.000000000 +0200 @@ -156,6 +156,11 @@ static option_t ccp_option_list[] = { "allow MPPE stateful mode", OPT_PRIO }, { "nomppe-stateful", o_bool, &refuse_mppe_stateful, "disallow MPPE stateful mode", OPT_PRIO | 1 }, + + /* allow falling back to unencrypted connection mode */ + { "mppe-optional", o_bool, &allow_mppe_fallback, + "allow falling back to unencryped connection mode", OPT_PRIO | 1 }, + #endif /* MPPE */ { NULL } @@ -516,9 +521,14 @@ ccp_protrej(unit) #ifdef MPPE if (ccp_gotoptions[unit].mppe) { - error("MPPE required but peer negotiation failed"); - lcp_close(unit, "MPPE required but peer negotiation failed"); - } + if(!allow_mppe_fallback) { + error("MPPE required but peer negotiation failed"); + lcp_close(unit, "MPPE required but peer negotiation failed"); + } else { + error("MPPE required but peer negotiation failed."); + error("Falling back and disabling MPPE"); + } + } #endif } @@ -1004,11 +1014,17 @@ ccp_rejci(f, p, len) #ifdef MPPE if (go->mppe && len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - error("MPPE required but peer refused"); - lcp_close(f->unit, "MPPE required but peer refused"); - p += CILEN_MPPE; - len -= CILEN_MPPE; + if(!allow_mppe_fallback) { + error("MPPE required but peer refused. Closing LCP"); + lcp_close(f->unit, "MPPE required but peer refused"); + } else { + try.mppe = 0; + error("MPPE required but peer refused."); + error("Falling back and disabling MPPE"); + } } + p += CILEN_MPPE; + len -= CILEN_MPPE; #endif if (go->deflate_correct && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { diff -ruNp ppp-2.4.4.orig/pppd/ccp.h ppp-2.4.4/pppd/ccp.h --- ppp-2.4.4.orig/pppd/ccp.h 2004-11-04 12:02:26.000000000 +0200 +++ ppp-2.4.4/pppd/ccp.h 2008-02-13 19:03:43.000000000 +0200 @@ -43,6 +43,8 @@ typedef struct ccp_options { short method; /* code for chosen compression method */ } ccp_options; +bool allow_mppe_fallback; + extern fsm ccp_fsm[]; extern ccp_options ccp_wantoptions[]; extern ccp_options ccp_gotoptions[]; @@ -50,3 +52,5 @@ extern ccp_options ccp_allowoptions[]; extern ccp_options ccp_hisoptions[]; extern struct protent ccp_protent; + + diff -ruNp ppp-2.4.4.orig/pppd/pppd.8 ppp-2.4.4/pppd/pppd.8 --- ppp-2.4.4.orig/pppd/pppd.8 2006-06-16 03:01:23.000000000 +0300 +++ ppp-2.4.4/pppd/pppd.8 2008-02-13 18:41:31.000000000 +0200 @@ -770,6 +770,9 @@ available under Linux. .B nomppe Disables MPPE (Microsoft Point to Point Encryption). This is the default. .TP +.B mppe-optional +Makes MPPE optional, allowing both MPPE and non-MPPE clients +.TP .B nomppe\-40 Disable 40-bit encryption with MPPE. .TP