static struct mbuf * proto_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) { u_char cp[2]; size_t got; if ((got = mbuf_View(bp, cp, 2)) == 0) { m_freem(bp); return NULL; } *proto = cp[0]; if (!(*proto & 1)) { if (got == 1) { m_freem(bp); return NULL; } bp = mbuf_Read(bp, cp, 2); *proto = (*proto << 8) | cp[1]; } else bp = mbuf_Read(bp, cp, 1); log_Printf(LogDEBUG, "proto_LayerPull: unknown -> 0x%04x\n", *proto); m_settype(bp, MB_PROTOIN); link_ProtocolRecord(l, *proto, PROTO_IN); return bp; }
static struct mbuf * sync_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, u_short *proto) { log_DumpBp(LogSYNC, "Write", bp); m_settype(bp, MB_SYNCOUT); return bp; }
static struct mbuf * acf_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) { struct physical *p = link2physical(l); u_char cp[2]; if (!p) { log_Printf(LogERROR, "Can't Pull an acf packet from a logical link\n"); return bp; } if (mbuf_View(bp, cp, 2) == 2) { if (!p->link.lcp.want_acfcomp) { /* We expect the packet not to be compressed */ bp = mbuf_Read(bp, cp, 2); if (cp[0] != HDLC_ADDR) { p->hdlc.lqm.ifInErrors++; p->hdlc.stats.badaddr++; log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]); m_freem(bp); return NULL; } if (cp[1] != HDLC_UI) { p->hdlc.lqm.ifInErrors++; p->hdlc.stats.badcommand++; log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]); m_freem(bp); return NULL; } m_settype(bp, MB_ACFIN); } else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) { /* * We can receive compressed packets, but the peer still sends * uncompressed packets (or maybe this is a PROTO_LCP packet) ! */ bp = mbuf_Read(bp, cp, 2); m_settype(bp, MB_ACFIN); } } return bp; }
static struct mbuf * vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri, u_short *proto) { int type; struct ip *pip; u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16; bp = m_pullup(bp); pip = (struct ip *)MBUF_CTOP(bp); if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP && cproto == PROTO_VJCOMP) { type = sl_compress_tcp(bp, pip, &bundle->ncp.ipcp.vj.cslc, &bundle->ncp.ipcp.vj.slstat, bundle->ncp.ipcp.peer_compproto & 0xff); log_Printf(LogDEBUG, "vj_LayerWrite: type = %x\n", type); switch (type) { case TYPE_IP: break; case TYPE_UNCOMPRESSED_TCP: *proto = PROTO_VJUNCOMP; log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n"); m_settype(bp, MB_VJOUT); break; case TYPE_COMPRESSED_TCP: *proto = PROTO_VJCOMP; log_Printf(LogDEBUG, "vj_LayerPush: PROTO_IP -> PROTO_VJUNCOMP\n"); m_settype(bp, MB_VJOUT); break; default: log_Printf(LogERROR, "vj_LayerPush: Unknown frame type %x\n", type); m_freem(bp); return NULL; } } return bp; }
static struct mbuf * proto_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, int pri, u_short *proto) { log_Printf(LogDEBUG, "proto_LayerPush: Using 0x%04x\n", *proto); bp = proto_Prepend(bp, *proto, l->lcp.his_protocomp, acf_WrapperOctets(&l->lcp, *proto)); m_settype(bp, MB_PROTOOUT); link_ProtocolRecord(l, *proto, PROTO_OUT); return bp; }
static struct mbuf * acf_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp, int pri, u_short *proto) { const u_char cp[2] = { HDLC_ADDR, HDLC_UI }; if (*proto == PROTO_LCP || l->lcp.his_acfcomp == 0) { bp = m_prepend(bp, cp, 2, 0); m_settype(bp, MB_ACFOUT); } return bp; }
static struct mbuf * lqr_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) { /* * This is the ``Rx'' process from rfc1989, although a part of it is * actually performed by sync_LayerPull() & hdlc_LayerPull() so that * our octet counts are correct. */ if (*proto == PROTO_LQR) m_settype(bp, MB_LQRIN); return bp; }
struct mbuf * ipv6cp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { /* Got PROTO_IPV6CP from link */ m_settype(bp, MB_IPV6CPIN); if (bundle_Phase(bundle) == PHASE_NETWORK) fsm_Input(&bundle->ncp.ipv6cp.fsm, bp); else { if (bundle_Phase(bundle) < PHASE_NETWORK) log_Printf(LogIPV6CP, "%s: Error: Unexpected IPV6CP in phase %s" " (ignored)\n", l->name, bundle_PhaseName(bundle)); m_freem(bp); } return NULL; }
extern struct mbuf * ccp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { /* Got PROTO_CCP from link */ m_settype(bp, MB_CCPIN); if (bundle_Phase(bundle) == PHASE_NETWORK) fsm_Input(&l->ccp.fsm, bp); else { if (bundle_Phase(bundle) < PHASE_NETWORK) log_Printf(LogCCP, "%s: Error: Unexpected CCP in phase %s (ignored)\n", l->ccp.fsm.link->name, bundle_PhaseName(bundle)); m_freem(bp); } return NULL; }
static struct mbuf * sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto) { struct physical *p = link2physical(l); if (!p) log_Printf(LogERROR, "Can't Pull a sync packet from a logical link\n"); else { log_DumpBp(LogSYNC, "Read", bp); /* Either done here or by the HDLC layer */ p->hdlc.lqm.SaveInOctets += m_length(bp) + 1; p->hdlc.lqm.SaveInPackets++; m_settype(bp, MB_SYNCIN); } return bp; }
static struct mbuf * VjUncompressTcp(struct ipcp *ipcp, struct mbuf *bp, u_char type) { u_char *bufp; int len, olen, rlen; u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */ bp = m_pullup(bp); olen = len = m_length(bp); if (type == TYPE_UNCOMPRESSED_TCP) { /* * Uncompressed packet does NOT change its size, so that we can use mbuf * space for uncompression job. */ bufp = MBUF_CTOP(bp); len = sl_uncompress_tcp(&bufp, len, type, &ipcp->vj.cslc, &ipcp->vj.slstat, (ipcp->my_compproto >> 8) & 255); if (len <= 0) { m_freem(bp); bp = NULL; } else m_settype(bp, MB_VJIN); return bp; }
struct mbuf * chap_Input_old(struct bundle *bundle, struct link *l, struct mbuf *bp) { struct physical *p = link2physical(l); struct chap *chap = &p->dl->chap; char *name, *key, *ans; int len, nlen; u_char alen; #ifdef HAVE_DES int lanman; #endif if (p == NULL) { log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n"); m_freem(bp); return NULL; } if (bundle_Phase(bundle) != PHASE_NETWORK && bundle_Phase(bundle) != PHASE_AUTHENTICATE) { log_Printf(LogPHASE, "Unexpected chap input - dropped !\n"); m_freem(bp); return NULL; } m_settype(bp, MB_CHAPIN); if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL && ntohs(chap->auth.in.hdr.length) == 0) log_Printf(LogWARN, "Chap Input: Truncated header !\n"); else if (chap->auth.in.hdr.code == 0 || chap->auth.in.hdr.code > MAXCHAPCODE) log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n", chap->auth.in.hdr.code); else { len = m_length(bp); ans = NULL; if (chap->auth.in.hdr.code != CHAP_CHALLENGE && chap->auth.id != chap->auth.in.hdr.id && Enabled(bundle, OPT_IDCHECK)) { /* Wrong conversation dude ! */ log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n", chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id, chap->auth.id); m_freem(bp); return NULL; } chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */ #ifdef HAVE_DES lanman = 0; #endif switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: bp = mbuf_Read(bp, &alen, 1); len -= alen + 1; /* len -= (alen + 1); */ if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated challenge !\n"); m_freem(bp); return NULL; } *chap->challenge.peer = alen; bp = mbuf_Read(bp, chap->challenge.peer + 1, alen); bp = auth_ReadName(&chap->auth, bp, len); #ifdef HAVE_DES lanman = p->link.lcp.his_authtype == 0x80 && ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) || !IsAccepted(p->link.lcp.cfg.chap80nt)); #endif break; case CHAP_RESPONSE: auth_StopTimer(&chap->auth); bp = mbuf_Read(bp, &alen, 1); /* read HASH-Size */ len -= alen + 1; /* len -= (alen + 1);, len is length of Name Field */ if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated response !\n"); m_freem(bp); return NULL; } if ((ans = malloc(alen + 2)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); m_freem(bp); return NULL; } *ans = chap->auth.id; bp = mbuf_Read(bp, ans + 1, alen); /* cut HASH value */ ans[alen+1] = '\0'; /* ans is (id, HASH, \0)*/ bp = auth_ReadName(&chap->auth, bp, len); #ifdef HAVE_DES lanman = alen == 49 && ans[alen] == 0; #endif break; case CHAP_SUCCESS: case CHAP_FAILURE: /* chap->auth.in.name is already set up at CHALLENGE time */ if ((ans = malloc(len + 1)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); m_freem(bp); return NULL; } bp = mbuf_Read(bp, ans, len); ans[len] = '\0'; break; } switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: case CHAP_RESPONSE: if (*chap->auth.in.name) log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n", chapcodes[chap->auth.in.hdr.code], alen, chap->auth.in.name, #ifdef HAVE_DES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif ""); else log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n", chapcodes[chap->auth.in.hdr.code], alen, #ifdef HAVE_DES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif ""); break; case CHAP_SUCCESS: case CHAP_FAILURE: if (*ans) log_Printf(LogPHASE, "Chap Input: %s (%s)\n", chapcodes[chap->auth.in.hdr.code], ans); else log_Printf(LogPHASE, "Chap Input: %s\n", chapcodes[chap->auth.in.hdr.code]); break; } switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: if (*bundle->cfg.auth.key == '!' && bundle->cfg.auth.key[1] != '!') chap_StartChild(chap, bundle->cfg.auth.key + 1, bundle->cfg.auth.name); else chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key + (*bundle->cfg.auth.key == '!' ? 1 : 0), p->link.lcp.his_authtype #ifdef HAVE_DES , lanman #endif ); break; case CHAP_RESPONSE: name = chap->auth.in.name; nlen = strlen(name); #ifndef NORADIUS if (*bundle->radius.cfg.file) { u_char end; end = chap->challenge.local[*chap->challenge.local+1]; chap->challenge.local[*chap->challenge.local+1] = '\0'; radius_Authenticate(&bundle->radius, &chap->auth, chap->auth.in.name, ans, chap->challenge.local + 1); chap->challenge.local[*chap->challenge.local+1] = end; } else #endif { key = auth_GetSecret(bundle, name, nlen, p); if (key) { char *myans; #ifdef HAVE_DES if (lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) { log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n"); if (chap_HaveAnotherGo(chap)) break; key = NULL; } else if (!lanman && !IsEnabled(p->link.lcp.cfg.chap80nt) && p->link.lcp.want_authtype == 0x80) { log_Printf(LogPHASE, "Auth failure: mschap not enabled\n"); if (chap_HaveAnotherGo(chap)) break; key = NULL; } else #endif { myans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.local, p->link.lcp.want_authtype #ifdef HAVE_DES , lanman #endif ); if (myans == NULL) key = NULL; else { if (!chap_Cmp(p->link.lcp.want_authtype, myans + 1, *myans, ans + 1, alen #ifdef HAVE_DES , lanman #endif )) key = NULL; free(myans); } } } if (key) chap_Success(&chap->auth); else chap_Failure(&chap->auth); } break; case CHAP_SUCCESS: if (p->link.lcp.auth_iwait == PROTO_CHAP) { p->link.lcp.auth_iwait = 0; if (p->link.lcp.auth_ineed == 0) /* * We've succeeded in our ``login'' * If we're not expecting the peer to authenticate (or he already * has), proceed to network phase. */ datalink_AuthOk(p->dl); } break; case CHAP_FAILURE: datalink_AuthNotOk(p->dl); break; } free(ans); } m_freem(bp); return NULL; }
struct mbuf * pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { struct physical *p = link2physical(l); struct authinfo *authp = &p->dl->pap; u_char nlen, klen, *key; const char *txt; int txtlen; if (p == NULL) { log_Printf(LogERROR, "pap_Input: Not a physical link - dropped\n"); m_freem(bp); return NULL; } if (bundle_Phase(bundle) != PHASE_NETWORK && bundle_Phase(bundle) != PHASE_AUTHENTICATE) { log_Printf(LogPHASE, "Unexpected pap input - dropped !\n"); m_freem(bp); return NULL; } if ((bp = auth_ReadHeader(authp, bp)) == NULL && ntohs(authp->in.hdr.length) == 0) { log_Printf(LogWARN, "Pap Input: Truncated header !\n"); return NULL; } if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) { log_Printf(LogPHASE, "Pap Input: %d: Bad PAP code !\n", authp->in.hdr.code); m_freem(bp); return NULL; } if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id && Enabled(bundle, OPT_IDCHECK)) { /* Wrong conversation dude ! */ log_Printf(LogPHASE, "Pap Input: %s dropped (got id %d, not %d)\n", papcodes[authp->in.hdr.code], authp->in.hdr.id, authp->id); m_freem(bp); return NULL; } m_settype(bp, MB_PAPIN); authp->id = authp->in.hdr.id; /* We respond with this id */ if (bp) { bp = mbuf_Read(bp, &nlen, 1); if (authp->in.hdr.code == PAP_ACK) { /* * Don't restrict the length of our acknowledgement freetext to * nlen (a one-byte length). Show the rest of the ack packet * instead. This isn't really part of the protocol..... */ bp = m_pullup(bp); txt = MBUF_CTOP(bp); txtlen = m_length(bp); } else { bp = auth_ReadName(authp, bp, nlen); txt = authp->in.name; txtlen = strlen(authp->in.name); } } else { txt = ""; txtlen = 0; } log_Printf(LogPHASE, "Pap Input: %s (%.*s)\n", papcodes[authp->in.hdr.code], txtlen, txt); switch (authp->in.hdr.code) { case PAP_REQUEST: if (bp == NULL) { log_Printf(LogPHASE, "Pap Input: No key given !\n"); break; } bp = mbuf_Read(bp, &klen, 1); if (m_length(bp) < klen) { log_Printf(LogERROR, "Pap Input: Truncated key !\n"); break; } if ((key = malloc(klen+1)) == NULL) { log_Printf(LogERROR, "Pap Input: Out of memory !\n"); break; } bp = mbuf_Read(bp, key, klen); key[klen] = '\0'; #ifndef NORADIUS if (*bundle->radius.cfg.file) { if (!radius_Authenticate(&bundle->radius, authp, authp->in.name, key, strlen(key), NULL, 0)) pap_Failure(authp); } else #endif if (auth_Validate(bundle, authp->in.name, key)) pap_Success(authp); else pap_Failure(authp); free(key); break; case PAP_ACK: auth_StopTimer(authp); if (p->link.lcp.auth_iwait == PROTO_PAP) { p->link.lcp.auth_iwait = 0; if (p->link.lcp.auth_ineed == 0) /* * We've succeeded in our ``login'' * If we're not expecting the peer to authenticate (or he already * has), proceed to network phase. */ datalink_AuthOk(p->dl); } break; case PAP_NAK: auth_StopTimer(authp); datalink_AuthNotOk(p->dl); break; } m_freem(bp); return NULL; }
struct mbuf * chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) { struct physical *p = link2physical(l); struct chap *chap = &p->dl->chap; char *name, *key, *ans; int len, nlen; u_char alen; #ifndef NODES int lanman; #endif if (p == NULL) { log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n"); m_freem(bp); return NULL; } if (bundle_Phase(bundle) != PHASE_NETWORK && bundle_Phase(bundle) != PHASE_AUTHENTICATE) { log_Printf(LogPHASE, "Unexpected chap input - dropped !\n"); m_freem(bp); return NULL; } m_settype(bp, MB_CHAPIN); if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL && ntohs(chap->auth.in.hdr.length) == 0) log_Printf(LogWARN, "Chap Input: Truncated header !\n"); else if (chap->auth.in.hdr.code == 0 || chap->auth.in.hdr.code > MAXCHAPCODE) log_Printf(LogPHASE, "Chap Input: %d: Bad CHAP code !\n", chap->auth.in.hdr.code); else { len = m_length(bp); ans = NULL; if (chap->auth.in.hdr.code != CHAP_CHALLENGE && chap->auth.id != chap->auth.in.hdr.id && Enabled(bundle, OPT_IDCHECK)) { /* Wrong conversation dude ! */ log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n", chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id, chap->auth.id); m_freem(bp); return NULL; } chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */ #ifndef NODES lanman = 0; #endif switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: bp = mbuf_Read(bp, &alen, 1); len -= alen + 1; if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated challenge !\n"); m_freem(bp); return NULL; } *chap->challenge.peer = alen; bp = mbuf_Read(bp, chap->challenge.peer + 1, alen); bp = auth_ReadName(&chap->auth, bp, len); #ifndef NODES lanman = p->link.lcp.his_authtype == 0x80 && ((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) || !IsAccepted(p->link.lcp.cfg.chap80nt)); /* Generate local challenge value */ chap_ChallengeInit(&chap->auth); #endif break; case CHAP_RESPONSE: auth_StopTimer(&chap->auth); bp = mbuf_Read(bp, &alen, 1); len -= alen + 1; if (len < 0) { log_Printf(LogERROR, "Chap Input: Truncated response !\n"); m_freem(bp); return NULL; } if ((ans = malloc(alen + 1)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); m_freem(bp); return NULL; } *ans = chap->auth.id; bp = mbuf_Read(bp, ans + 1, alen); bp = auth_ReadName(&chap->auth, bp, len); #ifndef NODES lanman = p->link.lcp.want_authtype == 0x80 && alen == 49 && ans[alen] == 0; #endif break; case CHAP_SUCCESS: case CHAP_FAILURE: /* chap->auth.in.name is already set up at CHALLENGE time */ if ((ans = malloc(len + 1)) == NULL) { log_Printf(LogERROR, "Chap Input: Out of memory !\n"); m_freem(bp); return NULL; } bp = mbuf_Read(bp, ans, len); ans[len] = '\0'; break; } switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: case CHAP_RESPONSE: if (*chap->auth.in.name) log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n", chapcodes[chap->auth.in.hdr.code], alen, chap->auth.in.name, #ifndef NODES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif ""); else log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n", chapcodes[chap->auth.in.hdr.code], alen, #ifndef NODES lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ? " - lanman" : #endif ""); break; case CHAP_SUCCESS: case CHAP_FAILURE: if (*ans) log_Printf(LogPHASE, "Chap Input: %s (%s)\n", chapcodes[chap->auth.in.hdr.code], ans); else log_Printf(LogPHASE, "Chap Input: %s\n", chapcodes[chap->auth.in.hdr.code]); break; } switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: if (*bundle->cfg.auth.key == '!' && bundle->cfg.auth.key[1] != '!') chap_StartChild(chap, bundle->cfg.auth.key + 1, bundle->cfg.auth.name); else chap_Respond(chap, bundle->cfg.auth.name, bundle->cfg.auth.key + (*bundle->cfg.auth.key == '!' ? 1 : 0), p->link.lcp.his_authtype #ifndef NODES , lanman #endif ); break; case CHAP_RESPONSE: name = chap->auth.in.name; nlen = strlen(name); #ifndef NODES if (p->link.lcp.want_authtype == 0x81) { struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1); chap->challenge.peer[0] = sizeof resp->PeerChallenge; memcpy(chap->challenge.peer + 1, resp->PeerChallenge, sizeof resp->PeerChallenge); } #endif #ifndef NORADIUS if (*bundle->radius.cfg.file) { if (!radius_Authenticate(&bundle->radius, &chap->auth, chap->auth.in.name, ans, alen + 1, chap->challenge.local + 1, *chap->challenge.local)) chap_Failure(&chap->auth); } else #endif { if (p->link.lcp.want_authtype == 0x81 && ans[alen] != '\0' && alen == sizeof(struct MSCHAPv2_resp)) { struct MSCHAPv2_resp *resp = (struct MSCHAPv2_resp *)(ans + 1); log_Printf(LogWARN, "%s: Compensating for corrupt (Win98/WinME?) " "CHAP81 RESPONSE\n", l->name); resp->Flags = '\0'; /* rfc2759 says it *MUST* be zero */ } key = auth_GetSecret(bundle, name, nlen, p); if (key) { #ifndef NODES if (p->link.lcp.want_authtype == 0x80 && lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) { log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n"); if (chap_HaveAnotherGo(chap)) break; key = NULL; } else if (p->link.lcp.want_authtype == 0x80 && !lanman && !IsEnabled(p->link.lcp.cfg.chap80nt)) { log_Printf(LogPHASE, "Auth failure: mschap not enabled\n"); if (chap_HaveAnotherGo(chap)) break; key = NULL; } else if (p->link.lcp.want_authtype == 0x81 && !IsEnabled(p->link.lcp.cfg.chap81)) { log_Printf(LogPHASE, "Auth failure: CHAP81 not enabled\n"); key = NULL; } else #endif { char *myans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.local, p->link.lcp.want_authtype #ifndef NODES , chap->challenge.peer, chap->authresponse, lanman); MPPE_IsServer = 1; /* XXX Global ! */ #else ); #endif if (myans == NULL) key = NULL; else { if (!chap_Cmp(p->link.lcp.want_authtype, myans + 1, *myans, ans + 1, alen #ifndef NODES , lanman #endif )) key = NULL; free(myans); } } } if (key) chap_Success(&chap->auth); else chap_Failure(&chap->auth); } break; case CHAP_SUCCESS: if (p->link.lcp.auth_iwait == PROTO_CHAP) { p->link.lcp.auth_iwait = 0; if (p->link.lcp.auth_ineed == 0) { #ifndef NODES if (p->link.lcp.his_authtype == 0x81) { if (strncasecmp(ans, chap->authresponse, 42)) { datalink_AuthNotOk(p->dl); log_Printf(LogWARN, "CHAP81: AuthenticatorResponse: (%.42s)" " != ans: (%.42s)\n", chap->authresponse, ans); } else { /* Successful login */ MPPE_MasterKeyValid = 1; /* XXX Global ! */ datalink_AuthOk(p->dl); } } else #endif /* * We've succeeded in our ``login'' * If we're not expecting the peer to authenticate (or he already * has), proceed to network phase. */ datalink_AuthOk(p->dl); } } break; case CHAP_FAILURE: datalink_AuthNotOk(p->dl); break; } free(ans); }