static void datalink_AuthReInit(struct datalink *dl) { auth_StopTimer(&dl->pap); auth_StopTimer(&dl->chap.auth); chap_ReInit(&dl->chap); }
/***************************************************************************** 函 数 名 : chap_Input 功能描述 : 收到CHAP帧的处理入口函数 输入参数 : l - PPP链接 pstMem - 收到的CHAP帧 输出参数 : 无 返 回 值 : NULL 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2008年10月24日 作 者 : liukai 修改内容 : porting from BSD *****************************************************************************/ PPP_ZC_STRU *chap_Input(struct link *l, PPP_ZC_STRU *pstMem) { struct chap *chap; VOS_INT32 len; VOS_UCHAR alen; /* answer length: challenge or response body length */ struct ppp_mbuf *bp; VOS_UCHAR aucHashValue[MD5DIGESTSIZE]; bp = ppp_m_get_from_ttfmem(pstMem); PPP_MemFree(pstMem); if (VOS_NULL_PTR == bp) { return VOS_NULL_PTR; } if (VOS_NULL_PTR == l) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Chap Input: Not a physical link - dropped\r\n"); ppp_m_freem(bp); return VOS_NULL_PTR; } if ((PHASE_NETWORK != l->phase) && (PHASE_AUTHENTICATE != l->phase)) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Unexpected Chap input - dropped\r\n"); ppp_m_freem(bp); return VOS_NULL_PTR; } chap = &(l->chap); if ((VOS_NULL_PTR == (bp = auth_ReadHeader(&chap->auth, bp))) && (0 == VOS_NTOHS(chap->auth.in.hdr.length))) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Chap Input: Truncated header\r\n"); } else if ((0 == chap->auth.in.hdr.code) || ((VOS_UINT8)(chap->auth.in.hdr.code) > MAXCHAPCODE)) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: Bad CHAP code %d !\r\n", chap->auth.in.hdr.code); } else { len = ppp_m_length(bp); /* Identifier of rx-ed Response, Success, Fail should match Challenge tx-ed */ if ((CHAP_CHALLENGE != chap->auth.in.hdr.code) && (chap->auth.id != chap->auth.in.hdr.id)) { /* Wrong conversation dude ! */ PPP_MNTN_LOG3(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: code <1> dropped (got id <2> not equal to previous id <3>)\r\n", chap->auth.in.hdr.code, chap->auth.in.hdr.id, chap->auth.id); ppp_m_freem(bp); return VOS_NULL_PTR; } chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */ if (CHAP_CHALLENGE == chap->auth.in.hdr.code) /* rx-ed challenge */ { bp = ppp_mbuf_Read(bp, &alen, 1); /* fetch length of peer's challenge */ len -= (alen + 1); /* after this step, len is length of peer's name */ if (len < 0) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: Truncated challenge (len %d, alen %d)!\r\n", len, alen); ppp_m_freem(bp); return VOS_NULL_PTR; } if (AUTHLEN < len) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: name of challenge too long (len %d, alen %d)!\r\n", len, alen); ppp_m_freem(bp); return VOS_NULL_PTR; } if (CHAPCHALLENGELEN < alen) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: challenge too long (len %d)!\r\n", alen); ppp_m_freem(bp); return VOS_NULL_PTR; } *chap->challenge.peer = alen; bp = ppp_mbuf_Read(bp, chap->challenge.peer + 1, alen); /* record peer's challenge */ bp = auth_ReadName(&chap->auth, bp, len); /* record peer's name */ if (*chap->auth.in.name) /* challenge with name */ { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: challenge (len %d, alen %d) with name\r\n", len, alen); } else /* without name */ { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: challenge (len %d, alen %d) without name\r\n", len, alen); } chap_Respond(l, "HUAWEI_CHAP_CLNT"); /* we always use "HUAWEI_CHAP_CLNT" as Name of Response */ } /* end of rx-ed challenge */ else if (CHAP_RESPONSE == chap->auth.in.hdr.code) /* rx-ed response */ { bp = ppp_mbuf_Read(bp, &alen, 1); /* read HASH-Size */ if (MD5DIGESTSIZE != alen) /* as just support MD5, must be 16 octets */ { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: Hash-Size %f is not correct !\r\n", alen); ppp_m_freem(bp); return VOS_NULL_PTR; } len -= (alen + 1); /* after this step, len is length of Name Field */ if (len < 0) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: Truncated response (len %d, alen %d)!\r\n", len, alen); ppp_m_freem(bp); return VOS_NULL_PTR; } if (AUTHLEN < len) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Chap Input: name of response too long (len %d, alen %d)!\r\n", len, alen); ppp_m_freem(bp); return VOS_NULL_PTR; } bp = ppp_mbuf_Read(bp, aucHashValue, MD5DIGESTSIZE); /* cut HASH value */ bp = auth_ReadName(&chap->auth, bp, len); if (*chap->auth.in.name) { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL,"Chap Input: response (len <1>, alen <2>) with name\r\n", len, alen); } else { PPP_MNTN_LOG2(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL,"Chap Input: response (len <1>, alen <2>) without name\r\n", len, alen); } if (PHASE_AUTHENTICATE == l->phase) /* 需要注意只备份在认证阶段中与challenge id匹配的response */ { ChapBufferResponsePacket(chap, MD5DIGESTSIZE, aucHashValue, len); } chap_Success(l); /* Moves code to here as the last step of dealing with response by liukai, it should stop authentication timer after authentication pass or fail. Stops timer at first, a response frame format is not correct and discards it(way of BSD), UE has no chance to send challenge again */ auth_StopTimer(&(chap->auth)); } /* end of rx-ed response */ else if (CHAP_SUCCESS == chap->auth.in.hdr.code) /* rx-ed success */ { /* chap->auth.in.name is already set up at CHALLENGE time, need NOT to print again */ if (0 < len) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: success with message\r\n"); } else { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: success without message\r\n"); } if (PROTO_CHAP == l->lcp.auth_iwait) { l->lcp.auth_iwait = 0; if (0 == l->lcp.auth_ineed) /* auth_ineed: 0, authentication by peer is not complete or no need to authentication, !0, authentication by peer is complete */ { /* * We've succeeded in our ``login'' * If we're not expecting the peer to authenticate (or he already * has), proceed to network phase. */ chap_ReInit(&(l->chap)); if (PHASE_AUTHENTICATE == l->phase) { l->phase = PHASE_NETWORK; l->ipcp.fsm.state = ST_CLOSED; fsm_Open(&(l->ipcp.fsm)); PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "goto ipcp stage!\r\n"); } } } } /* end of rx-ed success */ else /* rx-ed fail */ { /* chap->auth.in.name is already set up at CHALLENGE time, need NOT to print again */ if (0 < len) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: fail with message\r\n"); } else { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Chap Input: fail without message\r\n"); } chap_Cleanup(&(l->chap)); l->phase = PHASE_TERMINATE; fsm_Close(&(l->lcp.fsm)); PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "goto lcp stage!\r\n"); } /* end of rx-ed fail */ } ppp_m_freem(bp); return VOS_NULL_PTR; } /* chap_Input */
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; }
PPP_ZC_STRU * pap_Input(/*struct bundle *bundle,*/ struct link *l, PPP_ZC_STRU *pstMem) { /* struct physical *p = link2physical(l);*/ #if 0 /* delete for transplant */ VOS_CHAR nlen, *key; #endif struct authinfo *authp =/* &p->dl*/&(l->pap.auth); VOS_CHAR nlen; VOS_UINT8 klen; const VOS_CHAR *txt; VOS_INT32 txtlen; struct ppp_mbuf *bp; bp = ppp_m_get_from_ttfmem(pstMem); PPP_MemFree(pstMem); if (VOS_NULL_PTR == bp) { return VOS_NULL_PTR; } if (l == VOS_NULL_PTR) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "pap input, Not a physical link - dropped\r\n"); ppp_m_freem(bp); return VOS_NULL_PTR; } if (/*bundle_Phase(bundle)*/ l->phase!= PHASE_NETWORK && /*bundle_Phase(bundle)*/ l->phase!= PHASE_AUTHENTICATE) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Unexpected pap input - dropped\r\n"); ppp_m_freem(bp); return VOS_NULL_PTR; } if ((bp = auth_ReadHeader(authp, bp)) == VOS_NULL_PTR && VOS_NTOHS(authp->in.hdr.length) == 0) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Pap Input: Truncated header\r\n"); return VOS_NULL_PTR; } if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "Bad PAP code: %d", authp->in.hdr.code); ppp_m_freem(bp); return VOS_NULL_PTR; } if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id) { /* Wrong conversation dude ! */ PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "pap input, dropped (got id not equal to previous id)\r\n"); ppp_m_freem(bp); return VOS_NULL_PTR; } authp->id = authp->in.hdr.id; /* We respond with this id */ /*fanzhibin f49086 add it begin*/ if (authp->in.hdr.code == PAP_REQUEST) { /*将config req报文头部拷贝到缓存中*/ PS_MEM_CPY(l->pap.RecordData.BufRequest,&(authp->in.hdr),sizeof(authp->in.hdr)); ppp_mbuf_View(bp,(l->pap.RecordData.BufRequest + sizeof(authp->in.hdr)), VOS_NTOHS(authp->in.hdr.length) - sizeof(authp->in.hdr)); l->pap.RecordData.LenOfRequest = VOS_NTOHS(authp->in.hdr.length); } /*fanzhibin f49086 add it end*/ if (bp) { bp = ppp_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 = ppp_m_pullup(bp); txt = PPP_MBUF_CTOP(bp); txtlen = ppp_m_length(bp); } else { bp = auth_ReadName(authp, bp, nlen); txt = authp->in.name; txtlen = VOS_StrNLen(authp->in.name,AUTHLEN); PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "username:"******""; txtlen = 0; } PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "\r\nPap Input\r\n"); switch (authp->in.hdr.code) { case PAP_REQUEST: if (bp == VOS_NULL_PTR) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "Pap Input: No key given !\r\n"); break; } bp = ppp_mbuf_Read(bp, &klen, 1); if (ppp_m_length(bp) < klen) { PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_WARNING, "Pap Input: Truncated key !\r\n"); break; } #if 0/*fanzhibin f49086 delete it*/ if ((key = VOS_MemAlloc(PS_PID_APP_PPP, DYNAMIC_DOPRA_MEM_PT,klen+1)) == VOS_NULL_PTR) { PS_LOG(PS_PID_APP_PPP, 0, PS_PRINT_ERROR, "Pap Input: Out of memory !\n"); break; } bp = ppp_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), VOS_NULL_PTR, 0)) pap_Failure(authp); } else #endif /*下面这句在改造的时候要添进去*/ if (auth_Validate(bundle, authp->in.name, key, p)) pap_Success(authp); else pap_Failure(authp); VOS_MemFree(PS_PID_APP_PPP,key); #endif /*fanzhibin f49086 add it begin*/ if (klen > sizeof l->pap.RecordData.password- 1) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "auth_ReadPassword: PassWord too long,len= %d", klen); } else { if (klen > ppp_m_length(bp)) { PPP_MNTN_LOG1(PS_PID_APP_PPP, 0, LOG_LEVEL_WARNING, "auth_ReadPassword: Short packet, pass_len = %d", klen); } else { bp = ppp_mbuf_Read(bp, l->pap.RecordData.password, klen); l->pap.RecordData.password[klen] = '\0'; PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, "password:"); PPP_MNTN_LOG(PS_PID_APP_PPP, 0, PS_PRINT_NORMAL, l->pap.RecordData.password); } } pap_Success(l); /*fanzhibin f49086 add it end*/ break; case PAP_ACK: #if 0/*fanzhibin f49086 delete it*/ 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); } #endif break; case PAP_NAK: #if 0/*fanzhibin f49086 delete it*/ auth_StopTimer(authp); datalink_AuthNotOk(p->dl); #endif break; } ppp_m_freem(bp); return VOS_NULL_PTR; }
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); }