When doing MPPE, if the peer doesn't agree to it, we need to terminate
LCP. Older win* clients request Stac/LZS along with MPPE (because
MPPE overloads MPPC ... sigh). So if sending CONFREJ, we would keep
LCP up if we saw a CI_MPPE *at all*, because the CONFREJ may may have
been due to the Stac/LZS option. Now, we only keep LCP up if the MPPE
offer is acceptable.
Thanks to James Cameron for showing this problem in action.
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: ccp.c,v 1.42 2002/12/23 23:24:37 fcusack Exp $"
+#define RCSID "$Id: ccp.c,v 1.43 2002/12/24 00:34:13 fcusack Exp $"
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
ccp_options *ho = &ccp_hisoptions[f->unit];
ccp_options *ao = &ccp_allowoptions[f->unit];
#ifdef MPPE
ccp_options *ho = &ccp_hisoptions[f->unit];
ccp_options *ao = &ccp_allowoptions[f->unit];
#ifdef MPPE
+ bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */
+ /* CI_MPPE, or due to other options? */
newret = CONFREJ;
break;
}
newret = CONFREJ;
break;
}
MPPE_CI_TO_OPTS(&p[2], ho->mppe);
/* Nak if anything unsupported or unknown are set. */
MPPE_CI_TO_OPTS(&p[2], ho->mppe);
/* Nak if anything unsupported or unknown are set. */
+ /*
+ * We have accepted MPPE or are willing to negotiate
+ * MPPE parameters. A CONFREJ is due to subsequent
+ * (non-MPPE) processing.
+ */
+ rej_for_ci_mppe = 0;
break;
#endif /* MPPE */
case CI_DEFLATE:
break;
#endif /* MPPE */
case CI_DEFLATE:
*lenp = retp - p0;
}
#ifdef MPPE
*lenp = retp - p0;
}
#ifdef MPPE
- if (ret == CONFREJ && ao->mppe && !seen_ci_mppe) {
+ if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
error("MPPE required but peer negotiation failed");
lcp_close(f->unit, "MPPE required but peer negotiation failed");
}
error("MPPE required but peer negotiation failed");
lcp_close(f->unit, "MPPE required but peer negotiation failed");
}