Fully support both NT and LANMan CHAP type 0x80 as both
authenticator and authenticatee.
This commit is contained in:
parent
75ffaf5939
commit
5e31549897
@ -17,7 +17,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: auth.c,v 1.37 1999/02/02 09:35:17 brian Exp $
|
* $Id: auth.c,v 1.38 1999/02/06 02:54:43 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* o Implement check against with registered IP addresses.
|
* o Implement check against with registered IP addresses.
|
||||||
@ -66,13 +66,16 @@
|
|||||||
#include "bundle.h"
|
#include "bundle.h"
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
Auth2Nam(u_short auth)
|
Auth2Nam(u_short auth, u_char type)
|
||||||
{
|
{
|
||||||
|
static char chap[10];
|
||||||
|
|
||||||
switch (auth) {
|
switch (auth) {
|
||||||
case PROTO_PAP:
|
case PROTO_PAP:
|
||||||
return "PAP";
|
return "PAP";
|
||||||
case PROTO_CHAP:
|
case PROTO_CHAP:
|
||||||
return "CHAP";
|
snprintf(chap, sizeof chap, "CHAP 0x%02x", type);
|
||||||
|
return chap;
|
||||||
case 0:
|
case 0:
|
||||||
return "none";
|
return "none";
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: auth.h,v 1.14 1999/02/02 09:35:17 brian Exp $
|
* $Id: auth.h,v 1.15 1999/02/06 02:54:43 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
*/
|
*/
|
||||||
@ -47,7 +47,7 @@ struct authinfo {
|
|||||||
#define auth_Failure(a) (*a->fn.failure)(a);
|
#define auth_Failure(a) (*a->fn.failure)(a);
|
||||||
#define auth_Success(a) (*a->fn.success)(a);
|
#define auth_Success(a) (*a->fn.success)(a);
|
||||||
|
|
||||||
extern const char *Auth2Nam(u_short);
|
extern const char *Auth2Nam(u_short, u_char);
|
||||||
extern void auth_Init(struct authinfo *, struct physical *,
|
extern void auth_Init(struct authinfo *, struct physical *,
|
||||||
auth_func, auth_func, auth_func);
|
auth_func, auth_func, auth_func);
|
||||||
extern void auth_StopTimer(struct authinfo *);
|
extern void auth_StopTimer(struct authinfo *);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: chap.c,v 1.42 1999/02/07 13:56:29 brian Exp $
|
* $Id: chap.c,v 1.43 1999/02/11 10:14:07 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
*/
|
*/
|
||||||
@ -31,12 +31,12 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#ifdef HAVE_DES
|
#ifdef HAVE_DES
|
||||||
#include <md4.h>
|
#include <md4.h>
|
||||||
#include <string.h>
|
|
||||||
#endif
|
#endif
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -105,7 +105,8 @@ ChapOutput(struct physical *physical, u_int code, u_int id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, int MSChap)
|
chap_BuildAnswer(char *name, char *key, u_char id, char *challenge,
|
||||||
|
u_char type, int lanman)
|
||||||
{
|
{
|
||||||
char *result, *digest;
|
char *result, *digest;
|
||||||
size_t nlen, klen;
|
size_t nlen, klen;
|
||||||
@ -114,7 +115,7 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, int MSChap)
|
|||||||
klen = strlen(key);
|
klen = strlen(key);
|
||||||
|
|
||||||
#ifdef HAVE_DES
|
#ifdef HAVE_DES
|
||||||
if (MSChap) {
|
if (type == 0x80) {
|
||||||
char expkey[AUTHLEN << 2];
|
char expkey[AUTHLEN << 2];
|
||||||
MD4_CTX MD4context;
|
MD4_CTX MD4context;
|
||||||
int f;
|
int f;
|
||||||
@ -122,38 +123,42 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, int MSChap)
|
|||||||
if ((result = malloc(1 + nlen + MS_CHAP_RESPONSE_LEN)) == NULL)
|
if ((result = malloc(1 + nlen + MS_CHAP_RESPONSE_LEN)) == NULL)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
digest = result; /* this is the response */
|
digest = result; /* the response */
|
||||||
*digest++ = MS_CHAP_RESPONSE_LEN; /* 49 */
|
*digest++ = MS_CHAP_RESPONSE_LEN; /* 49 */
|
||||||
memset(digest, '\0', 24);
|
memcpy(digest + MS_CHAP_RESPONSE_LEN, name, nlen);
|
||||||
digest += 24;
|
if (lanman) {
|
||||||
|
memset(digest + 24, '\0', 25);
|
||||||
|
mschap_LANMan(digest, challenge + 1, key); /* LANMan response */
|
||||||
|
} else {
|
||||||
|
memset(digest, '\0', 25);
|
||||||
|
digest += 24;
|
||||||
|
|
||||||
for (f = klen; f; f--) {
|
for (f = 0; f < klen; f++) {
|
||||||
expkey[2*f-2] = key[f-1];
|
expkey[2*f] = key[f];
|
||||||
expkey[2*f-1] = 0;
|
expkey[2*f+1] = '\0';
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* -----------
|
||||||
|
* expkey = | k\0e\0y\0 |
|
||||||
|
* -----------
|
||||||
|
*/
|
||||||
|
MD4Init(&MD4context);
|
||||||
|
MD4Update(&MD4context, expkey, klen << 1);
|
||||||
|
MD4Final(digest, &MD4context);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ---- -------- ---------------- ------- ------
|
||||||
|
* result = | 49 | LANMan | 16 byte digest | 9 * ? | name |
|
||||||
|
* ---- -------- ---------------- ------- ------
|
||||||
|
*/
|
||||||
|
mschap_NT(digest, challenge + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -----------
|
* ---- -------- ------------- ----- ------
|
||||||
* answer = | k\0e\0y\0 |
|
* | | struct MS_ChapResponse24 | |
|
||||||
* -----------
|
* result = | 49 | LANMan | NT digest | 0/1 | name |
|
||||||
*/
|
* ---- -------- ------------- ----- ------
|
||||||
MD4Init(&MD4context);
|
* where only one of LANMan & NT digest are set.
|
||||||
MD4Update(&MD4context, expkey, klen << 1);
|
|
||||||
MD4Final(digest, &MD4context);
|
|
||||||
memcpy(digest + 25, name, nlen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ``result'' is:
|
|
||||||
* ---- --------- -------------------- ------
|
|
||||||
* result = | 49 | 24 * \0 | digest (pad to 25) | name |
|
|
||||||
* ---- --------- -------------------- ------
|
|
||||||
*/
|
|
||||||
chap_MS(digest, challenge + 1, *challenge);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ---- --------- ---------------- --- ----------
|
|
||||||
* result = | 49 | 24 * \0 | 24 byte digest | 1 | authname |
|
|
||||||
* ---- --------- ---------------- --- ----------
|
|
||||||
*/
|
*/
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
@ -281,18 +286,20 @@ chap_Cleanup(struct chap *chap, int sig)
|
|||||||
log_Printf(LogERROR, "Chap: Child exited %d\n", WEXITSTATUS(status));
|
log_Printf(LogERROR, "Chap: Child exited %d\n", WEXITSTATUS(status));
|
||||||
}
|
}
|
||||||
*chap->challenge = 0;
|
*chap->challenge = 0;
|
||||||
|
chap->peertries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chap_SendResponse(struct chap *chap, char *name, char *key)
|
chap_Respond(struct chap *chap, char *name, char *key, u_char type, int lm)
|
||||||
{
|
{
|
||||||
char *ans;
|
u_char *ans;
|
||||||
|
|
||||||
ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge, 0);
|
ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge, type, lm);
|
||||||
|
|
||||||
if (ans) {
|
if (ans) {
|
||||||
ChapOutput(chap->auth.physical, CHAP_RESPONSE, chap->auth.id,
|
ChapOutput(chap->auth.physical, CHAP_RESPONSE, chap->auth.id,
|
||||||
ans, *ans + 1 + strlen(name), name);
|
ans, *ans + 1 + strlen(name), name);
|
||||||
|
chap->NTRespSent = !lm;
|
||||||
free(ans);
|
free(ans);
|
||||||
} else
|
} else
|
||||||
ChapOutput(chap->auth.physical, CHAP_FAILURE, chap->auth.id,
|
ChapOutput(chap->auth.physical, CHAP_FAILURE, chap->auth.id,
|
||||||
@ -355,6 +362,11 @@ chap_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
|||||||
chap_Cleanup(chap, SIGTERM);
|
chap_Cleanup(chap, SIGTERM);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
int lanman = chap->auth.physical->link.lcp.his_authtype == 0x80 &&
|
||||||
|
((chap->NTRespSent &&
|
||||||
|
IsAccepted(chap->auth.physical->link.lcp.cfg.chap80lm)) ||
|
||||||
|
!IsAccepted(chap->auth.physical->link.lcp.cfg.chap80nt));
|
||||||
|
|
||||||
while (end >= name && strchr(" \t\r\n", *end))
|
while (end >= name && strchr(" \t\r\n", *end))
|
||||||
*end-- = '\0';
|
*end-- = '\0';
|
||||||
end = key - 1;
|
end = key - 1;
|
||||||
@ -362,7 +374,8 @@ chap_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
|||||||
*end-- = '\0';
|
*end-- = '\0';
|
||||||
key += strspn(key, " \t");
|
key += strspn(key, " \t");
|
||||||
|
|
||||||
chap_SendResponse(chap, name, key);
|
chap_Respond(chap, name, key,
|
||||||
|
chap->auth.physical->link.lcp.his_authtype, lanman);
|
||||||
chap_Cleanup(chap, 0);
|
chap_Cleanup(chap, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +411,12 @@ chap_Challenge(struct authinfo *authp)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
*cp++ = random() % (CHAPCHALLENGELEN-16) + 16;
|
#ifdef HAVE_DES
|
||||||
|
if (authp->physical->link.lcp.want_authtype == 0x80)
|
||||||
|
*cp++ = 8; /* MS does 8 byte callenges :-/ */
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
*cp++ = random() % (CHAPCHALLENGELEN-16) + 16;
|
||||||
for (i = 0; i < *chap->challenge; i++)
|
for (i = 0; i < *chap->challenge; i++)
|
||||||
*cp++ = random() & 0xff;
|
*cp++ = random() & 0xff;
|
||||||
}
|
}
|
||||||
@ -432,6 +450,35 @@ chap_Failure(struct authinfo *authp)
|
|||||||
datalink_AuthNotOk(authp->physical->dl);
|
datalink_AuthNotOk(authp->physical->dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chap_Cmp(u_char type, int lm, char *myans, int mylen, char *hisans, int hislen)
|
||||||
|
{
|
||||||
|
if (mylen != hislen)
|
||||||
|
return 0;
|
||||||
|
else if (type == 0x80) {
|
||||||
|
int off = lm ? 0 : 24;
|
||||||
|
|
||||||
|
if (memcmp(myans + off, hisans + off, 24))
|
||||||
|
return 0;
|
||||||
|
} else if (memcmp(myans, hisans, mylen))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chap_HaveAnotherGo(struct chap *chap)
|
||||||
|
{
|
||||||
|
if (++chap->peertries < 3) {
|
||||||
|
/* Give the peer another shot */
|
||||||
|
*chap->challenge = '\0';
|
||||||
|
chap_Challenge(&chap->auth);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
chap_Init(struct chap *chap, struct physical *p)
|
chap_Init(struct chap *chap, struct physical *p)
|
||||||
{
|
{
|
||||||
@ -444,7 +491,8 @@ chap_Init(struct chap *chap, struct physical *p)
|
|||||||
chap->child.fd = -1;
|
chap->child.fd = -1;
|
||||||
auth_Init(&chap->auth, p, chap_Challenge, chap_Success, chap_Failure);
|
auth_Init(&chap->auth, p, chap_Challenge, chap_Success, chap_Failure);
|
||||||
*chap->challenge = 0;
|
*chap->challenge = 0;
|
||||||
chap->using_MSChap = 0;
|
chap->NTRespSent = 0;
|
||||||
|
chap->peertries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -457,8 +505,8 @@ void
|
|||||||
chap_Input(struct physical *p, struct mbuf *bp)
|
chap_Input(struct physical *p, struct mbuf *bp)
|
||||||
{
|
{
|
||||||
struct chap *chap = &p->dl->chap;
|
struct chap *chap = &p->dl->chap;
|
||||||
char *name, *key, *ans, *myans;
|
char *name, *key, *ans;
|
||||||
int len, nlen;
|
int len, nlen, lanman;
|
||||||
u_char alen;
|
u_char alen;
|
||||||
|
|
||||||
if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL)
|
if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL)
|
||||||
@ -482,17 +530,22 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||||||
}
|
}
|
||||||
chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */
|
chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */
|
||||||
|
|
||||||
|
lanman = 0;
|
||||||
switch (chap->auth.in.hdr.code) {
|
switch (chap->auth.in.hdr.code) {
|
||||||
case CHAP_CHALLENGE:
|
case CHAP_CHALLENGE:
|
||||||
bp = mbuf_Read(bp, chap->challenge, 1);
|
bp = mbuf_Read(bp, &alen, 1);
|
||||||
len -= *chap->challenge + 1;
|
len -= alen + 1;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
|
log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
|
||||||
mbuf_Free(bp);
|
mbuf_Free(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bp = mbuf_Read(bp, chap->challenge + 1, *chap->challenge);
|
*chap->challenge = alen;
|
||||||
|
bp = mbuf_Read(bp, chap->challenge + 1, alen);
|
||||||
bp = auth_ReadName(&chap->auth, bp, len);
|
bp = auth_ReadName(&chap->auth, bp, len);
|
||||||
|
lanman = p->link.lcp.his_authtype == 0x80 &&
|
||||||
|
((chap->NTRespSent && IsAccepted(p->link.lcp.cfg.chap80lm)) ||
|
||||||
|
!IsAccepted(p->link.lcp.cfg.chap80nt));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAP_RESPONSE:
|
case CHAP_RESPONSE:
|
||||||
@ -513,6 +566,7 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||||||
bp = mbuf_Read(bp, ans + 1, alen);
|
bp = mbuf_Read(bp, ans + 1, alen);
|
||||||
ans[alen+1] = '\0';
|
ans[alen+1] = '\0';
|
||||||
bp = auth_ReadName(&chap->auth, bp, len);
|
bp = auth_ReadName(&chap->auth, bp, len);
|
||||||
|
lanman = alen == 49 && ans[alen] == 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAP_SUCCESS:
|
case CHAP_SUCCESS:
|
||||||
@ -532,11 +586,16 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||||||
case CHAP_CHALLENGE:
|
case CHAP_CHALLENGE:
|
||||||
case CHAP_RESPONSE:
|
case CHAP_RESPONSE:
|
||||||
if (*chap->auth.in.name)
|
if (*chap->auth.in.name)
|
||||||
log_Printf(LogPHASE, "Chap Input: %s (from %s)\n",
|
log_Printf(LogPHASE, "Chap Input: %s (%d bytes from %s%s)\n",
|
||||||
chapcodes[chap->auth.in.hdr.code], chap->auth.in.name);
|
chapcodes[chap->auth.in.hdr.code], alen,
|
||||||
|
chap->auth.in.name,
|
||||||
|
lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
|
||||||
|
" - lanman" : "");
|
||||||
else
|
else
|
||||||
log_Printf(LogPHASE, "Chap Input: %s\n",
|
log_Printf(LogPHASE, "Chap Input: %s (%d bytes%s)\n",
|
||||||
chapcodes[chap->auth.in.hdr.code]);
|
chapcodes[chap->auth.in.hdr.code], alen,
|
||||||
|
lanman && chap->auth.in.hdr.code == CHAP_RESPONSE ?
|
||||||
|
" - lanman" : "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAP_SUCCESS:
|
case CHAP_SUCCESS:
|
||||||
@ -556,8 +615,9 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||||||
chap_StartChild(chap, p->dl->bundle->cfg.auth.key + 1,
|
chap_StartChild(chap, p->dl->bundle->cfg.auth.key + 1,
|
||||||
p->dl->bundle->cfg.auth.name);
|
p->dl->bundle->cfg.auth.name);
|
||||||
else
|
else
|
||||||
chap_SendResponse(chap, p->dl->bundle->cfg.auth.name,
|
chap_Respond(chap, p->dl->bundle->cfg.auth.name,
|
||||||
p->dl->bundle->cfg.auth.key);
|
p->dl->bundle->cfg.auth.key,
|
||||||
|
p->link.lcp.his_authtype, lanman);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAP_RESPONSE:
|
case CHAP_RESPONSE:
|
||||||
@ -573,14 +633,29 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||||||
{
|
{
|
||||||
key = auth_GetSecret(p->dl->bundle, name, nlen, p);
|
key = auth_GetSecret(p->dl->bundle, name, nlen, p);
|
||||||
if (key) {
|
if (key) {
|
||||||
myans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge,
|
char *myans;
|
||||||
chap->using_MSChap);
|
if (lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) {
|
||||||
if (myans == NULL)
|
log_Printf(LogPHASE, "Auth failure: LANMan not enabled\n");
|
||||||
|
if (chap_HaveAnotherGo(chap))
|
||||||
|
break;
|
||||||
key = NULL;
|
key = NULL;
|
||||||
else {
|
} else if (!lanman && !IsEnabled(p->link.lcp.cfg.chap80nt)) {
|
||||||
if (*myans != alen || memcmp(myans + 1, ans + 1, *myans))
|
log_Printf(LogPHASE, "Auth failure: mschap not enabled\n");
|
||||||
|
if (chap_HaveAnotherGo(chap))
|
||||||
|
break;
|
||||||
|
key = NULL;
|
||||||
|
} else {
|
||||||
|
myans = chap_BuildAnswer(name, key, chap->auth.id,
|
||||||
|
chap->challenge,
|
||||||
|
p->link.lcp.want_authtype, lanman);
|
||||||
|
if (myans == NULL)
|
||||||
key = NULL;
|
key = NULL;
|
||||||
free(myans);
|
else {
|
||||||
|
if (!chap_Cmp(p->link.lcp.want_authtype, lanman,
|
||||||
|
myans + 1, *myans, ans + 1, alen))
|
||||||
|
key = NULL;
|
||||||
|
free(myans);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: chap.h,v 1.11 1999/02/06 02:54:44 brian Exp $
|
* $Id: chap.h,v 1.12 1999/02/11 10:14:07 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
*/
|
*/
|
||||||
@ -39,8 +39,9 @@ struct chap {
|
|||||||
} buf;
|
} buf;
|
||||||
} child;
|
} child;
|
||||||
struct authinfo auth;
|
struct authinfo auth;
|
||||||
char challenge[CHAPCHALLENGELEN + AUTHLEN];
|
u_char challenge[CHAPCHALLENGELEN + AUTHLEN];
|
||||||
unsigned using_MSChap : 1; /* A combination of MD4 & DES */
|
unsigned NTRespSent : 1; /* Our last response */
|
||||||
|
int peertries;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define descriptor2chap(d) \
|
#define descriptor2chap(d) \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
* chap_ms.c - Microsoft MS-CHAP (NT only) compatible implementation.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||||
* http://www.strataware.com/
|
* http://www.strataware.com/
|
||||||
@ -19,12 +19,13 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: chap_ms.c,v 1.5.4.3 1998/05/01 19:24:07 brian Exp $
|
* $Id: chap_ms.c,v 1.6 1998/05/21 21:44:30 brian Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <des.h>
|
#include <des.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -38,33 +39,6 @@ struct MS_ChapResponse {
|
|||||||
u_char UseNT; /* If 1, ignore the LANMan response field */
|
u_char UseNT; /* If 1, ignore the LANMan response field */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void DesEncrypt(u_char *, u_char *, u_char *);
|
|
||||||
static void MakeKey(u_char *, u_char *);
|
|
||||||
|
|
||||||
static void /* IN 8 octets IN 16 octets OUT 24 octets */
|
|
||||||
ChallengeResponse(u_char *challenge, u_char *pwHash, u_char *response)
|
|
||||||
{
|
|
||||||
char ZPasswordHash[21];
|
|
||||||
|
|
||||||
memset(ZPasswordHash, '\0', sizeof ZPasswordHash);
|
|
||||||
memcpy(ZPasswordHash, pwHash, 16);
|
|
||||||
|
|
||||||
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
|
|
||||||
DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
|
|
||||||
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void /* IN 8 octets IN 7 octest OUT 8 octets */
|
|
||||||
DesEncrypt(u_char *clear, u_char *key, u_char *cipher)
|
|
||||||
{
|
|
||||||
des_cblock des_key;
|
|
||||||
des_key_schedule key_schedule;
|
|
||||||
|
|
||||||
MakeKey(key, des_key);
|
|
||||||
des_set_key(&des_key, key_schedule);
|
|
||||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u_char Get7Bits(u_char *input, int startBit)
|
static u_char Get7Bits(u_char *input, int startBit)
|
||||||
{
|
{
|
||||||
register unsigned int word;
|
register unsigned int word;
|
||||||
@ -93,16 +67,58 @@ static void MakeKey(u_char *key, u_char *des_key)
|
|||||||
des_set_odd_parity((des_cblock *)des_key);
|
des_set_odd_parity((des_cblock *)des_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void /* IN 8 octets IN 7 octest OUT 8 octets */
|
||||||
|
DesEncrypt(u_char *clear, u_char *key, u_char *cipher)
|
||||||
|
{
|
||||||
|
des_cblock des_key;
|
||||||
|
des_key_schedule key_schedule;
|
||||||
|
|
||||||
|
MakeKey(key, des_key);
|
||||||
|
des_set_key(&des_key, key_schedule);
|
||||||
|
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void /* IN 8 octets IN 16 octets OUT 24 octets */
|
||||||
|
ChallengeResponse(u_char *challenge, u_char *pwHash, u_char *response)
|
||||||
|
{
|
||||||
|
char ZPasswordHash[21];
|
||||||
|
|
||||||
|
memset(ZPasswordHash, '\0', sizeof ZPasswordHash);
|
||||||
|
memcpy(ZPasswordHash, pwHash, 16);
|
||||||
|
|
||||||
|
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
|
||||||
|
DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
|
||||||
|
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
|
||||||
|
}
|
||||||
|
|
||||||
/* passwordHash 16-bytes MD4 hashed password
|
/* passwordHash 16-bytes MD4 hashed password
|
||||||
challenge 8-bytes peer CHAP challenge
|
challenge 8-bytes peer CHAP challenge
|
||||||
since passwordHash is in a 24-byte buffer, response is written in there */
|
since passwordHash is in a 24-byte buffer, response is written in there */
|
||||||
void
|
void
|
||||||
chap_MS(char *passwordHash, char *challenge, int challenge_len)
|
mschap_NT(char *passwordHash, char *challenge)
|
||||||
{
|
{
|
||||||
u_char response[24];
|
u_char response[24];
|
||||||
|
|
||||||
ChallengeResponse(challenge, passwordHash, response);
|
ChallengeResponse(challenge, passwordHash, response);
|
||||||
memcpy(passwordHash, response, 24);
|
memcpy(passwordHash, response, 24);
|
||||||
passwordHash += 24;
|
passwordHash[24] = 1; /* NT-style response */
|
||||||
*passwordHash = 1;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mschap_LANMan(char *digest, char *challenge, char *secret)
|
||||||
|
{
|
||||||
|
static u_char salt[] = "KGS!@#$%"; /* RASAPI32.dll */
|
||||||
|
char SECRET[14], *ptr, *end;
|
||||||
|
u_char hash[16];
|
||||||
|
|
||||||
|
end = SECRET + sizeof SECRET;
|
||||||
|
for (ptr = SECRET; *secret && ptr < end; ptr++, secret++)
|
||||||
|
*ptr = toupper(*secret);
|
||||||
|
if (ptr < end)
|
||||||
|
memset(ptr, '\0', end - ptr);
|
||||||
|
|
||||||
|
DesEncrypt(salt, SECRET, hash);
|
||||||
|
DesEncrypt(salt, SECRET + 7, hash + 8);
|
||||||
|
|
||||||
|
ChallengeResponse(challenge, hash, digest);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: chap_ms.h,v 1.2.4.1 1998/05/01 19:24:08 brian Exp $
|
* $Id: chap_ms.h,v 1.3 1998/05/21 21:44:32 brian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Max # of (Unicode) chars in an NT password */
|
/* Max # of (Unicode) chars in an NT password */
|
||||||
@ -28,4 +28,5 @@
|
|||||||
/* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
|
/* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
|
||||||
#define MS_CHAP_RESPONSE_LEN 49
|
#define MS_CHAP_RESPONSE_LEN 49
|
||||||
|
|
||||||
extern void chap_MS(char *, char *, int);
|
extern void mschap_NT(char *, char *);
|
||||||
|
extern void mschap_LANMan(char *, char *, char *);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: command.c,v 1.180 1999/02/11 10:14:07 brian Exp $
|
* $Id: command.c,v 1.181 1999/02/16 00:16:55 brian Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -127,19 +127,21 @@
|
|||||||
|
|
||||||
/* ``accept|deny|disable|enable'' values */
|
/* ``accept|deny|disable|enable'' values */
|
||||||
#define NEG_ACFCOMP 40
|
#define NEG_ACFCOMP 40
|
||||||
#define NEG_CHAP 41
|
#define NEG_CHAP05 41
|
||||||
#define NEG_DEFLATE 42
|
#define NEG_CHAP80 42
|
||||||
#define NEG_LQR 43
|
#define NEG_CHAP80LM 43
|
||||||
#define NEG_PAP 44
|
#define NEG_DEFLATE 44
|
||||||
#define NEG_PPPDDEFLATE 45
|
#define NEG_LQR 45
|
||||||
#define NEG_PRED1 46
|
#define NEG_PAP 46
|
||||||
#define NEG_PROTOCOMP 47
|
#define NEG_PPPDDEFLATE 47
|
||||||
#define NEG_SHORTSEQ 48
|
#define NEG_PRED1 48
|
||||||
#define NEG_VJCOMP 49
|
#define NEG_PROTOCOMP 49
|
||||||
#define NEG_DNS 50
|
#define NEG_SHORTSEQ 50
|
||||||
|
#define NEG_VJCOMP 51
|
||||||
|
#define NEG_DNS 52
|
||||||
|
|
||||||
const char Version[] = "2.11";
|
const char Version[] = "2.11";
|
||||||
const char VersionDate[] = "$Date: 1999/02/11 10:14:07 $";
|
const char VersionDate[] = "$Date: 1999/02/16 00:16:55 $";
|
||||||
|
|
||||||
static int ShowCommand(struct cmdargs const *);
|
static int ShowCommand(struct cmdargs const *);
|
||||||
static int TerminalCommand(struct cmdargs const *);
|
static int TerminalCommand(struct cmdargs const *);
|
||||||
@ -2170,10 +2172,20 @@ NegotiateSet(struct cmdargs const *arg)
|
|||||||
cx->physical->link.lcp.cfg.acfcomp &= keep;
|
cx->physical->link.lcp.cfg.acfcomp &= keep;
|
||||||
cx->physical->link.lcp.cfg.acfcomp |= add;
|
cx->physical->link.lcp.cfg.acfcomp |= add;
|
||||||
break;
|
break;
|
||||||
case NEG_CHAP:
|
case NEG_CHAP05:
|
||||||
cx->physical->link.lcp.cfg.chap &= keep;
|
cx->physical->link.lcp.cfg.chap05 &= keep;
|
||||||
cx->physical->link.lcp.cfg.chap |= add;
|
cx->physical->link.lcp.cfg.chap05 |= add;
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
case NEG_CHAP80:
|
||||||
|
cx->physical->link.lcp.cfg.chap80nt &= keep;
|
||||||
|
cx->physical->link.lcp.cfg.chap80nt |= add;
|
||||||
|
break;
|
||||||
|
case NEG_CHAP80LM:
|
||||||
|
cx->physical->link.lcp.cfg.chap80lm &= keep;
|
||||||
|
cx->physical->link.lcp.cfg.chap80lm |= add;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case NEG_DEFLATE:
|
case NEG_DEFLATE:
|
||||||
l->ccp.cfg.neg[CCP_NEG_DEFLATE] &= keep;
|
l->ccp.cfg.neg[CCP_NEG_DEFLATE] &= keep;
|
||||||
l->ccp.cfg.neg[CCP_NEG_DEFLATE] |= add;
|
l->ccp.cfg.neg[CCP_NEG_DEFLATE] |= add;
|
||||||
@ -2257,9 +2269,17 @@ static struct cmdtab const NegotiateCommands[] = {
|
|||||||
{"acfcomp", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
{"acfcomp", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
||||||
"Address & Control field compression", "accept|deny|disable|enable",
|
"Address & Control field compression", "accept|deny|disable|enable",
|
||||||
(const void *)NEG_ACFCOMP},
|
(const void *)NEG_ACFCOMP},
|
||||||
{"chap", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
{"chap", "chap05", NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
||||||
"Challenge Handshake Authentication Protocol", "accept|deny|disable|enable",
|
"Challenge Handshake Authentication Protocol", "accept|deny|disable|enable",
|
||||||
(const void *)NEG_CHAP},
|
(const void *)NEG_CHAP05},
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
{"mschap", "chap80nt", NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
||||||
|
"Microsoft (NT) CHAP", "accept|deny|disable|enable",
|
||||||
|
(const void *)NEG_CHAP80},
|
||||||
|
{"LANMan", "chap80lm", NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
||||||
|
"Microsoft (NT) CHAP", "accept|deny|disable|enable",
|
||||||
|
(const void *)NEG_CHAP80LM},
|
||||||
|
#endif
|
||||||
{"deflate", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX_OPT,
|
{"deflate", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||||
"Deflate compression", "accept|deny|disable|enable",
|
"Deflate compression", "accept|deny|disable|enable",
|
||||||
(const void *)NEG_DEFLATE},
|
(const void *)NEG_DEFLATE},
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: datalink.c,v 1.30 1999/02/11 10:14:08 brian Exp $
|
* $Id: datalink.c,v 1.31 1999/02/17 02:11:28 brian Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -475,20 +475,21 @@ datalink_LayerUp(void *v, struct fsm *fp)
|
|||||||
{
|
{
|
||||||
/* The given fsm is now up */
|
/* The given fsm is now up */
|
||||||
struct datalink *dl = (struct datalink *)v;
|
struct datalink *dl = (struct datalink *)v;
|
||||||
|
struct lcp *lcp = &dl->physical->link.lcp;
|
||||||
|
|
||||||
if (fp->proto == PROTO_LCP) {
|
if (fp->proto == PROTO_LCP) {
|
||||||
datalink_GotAuthname(dl, "");
|
datalink_GotAuthname(dl, "");
|
||||||
dl->physical->link.lcp.auth_ineed = dl->physical->link.lcp.want_auth;
|
lcp->auth_ineed = lcp->want_auth;
|
||||||
dl->physical->link.lcp.auth_iwait = dl->physical->link.lcp.his_auth;
|
lcp->auth_iwait = lcp->his_auth;
|
||||||
if (dl->physical->link.lcp.his_auth || dl->physical->link.lcp.want_auth) {
|
if (lcp->his_auth || lcp->want_auth) {
|
||||||
if (bundle_Phase(dl->bundle) == PHASE_ESTABLISH)
|
if (bundle_Phase(dl->bundle) == PHASE_ESTABLISH)
|
||||||
bundle_NewPhase(dl->bundle, PHASE_AUTHENTICATE);
|
bundle_NewPhase(dl->bundle, PHASE_AUTHENTICATE);
|
||||||
log_Printf(LogPHASE, "%s: his = %s, mine = %s\n", dl->name,
|
log_Printf(LogPHASE, "%s: his = %s, mine = %s\n", dl->name,
|
||||||
Auth2Nam(dl->physical->link.lcp.his_auth),
|
Auth2Nam(lcp->his_auth, lcp->his_authtype),
|
||||||
Auth2Nam(dl->physical->link.lcp.want_auth));
|
Auth2Nam(lcp->want_auth, lcp->want_authtype));
|
||||||
if (dl->physical->link.lcp.his_auth == PROTO_PAP)
|
if (lcp->his_auth == PROTO_PAP)
|
||||||
auth_StartReq(&dl->pap);
|
auth_StartReq(&dl->pap);
|
||||||
if (dl->physical->link.lcp.want_auth == PROTO_CHAP)
|
if (lcp->want_auth == PROTO_CHAP)
|
||||||
auth_StartReq(&dl->chap.auth);
|
auth_StartReq(&dl->chap.auth);
|
||||||
} else
|
} else
|
||||||
datalink_AuthOk(dl);
|
datalink_AuthOk(dl);
|
||||||
@ -955,8 +956,6 @@ datalink_Show(struct cmdargs const *arg)
|
|||||||
prompt_Printf(arg->prompt, "Name: %s\n", arg->cx->name);
|
prompt_Printf(arg->prompt, "Name: %s\n", arg->cx->name);
|
||||||
prompt_Printf(arg->prompt, " State: %s\n",
|
prompt_Printf(arg->prompt, " State: %s\n",
|
||||||
datalink_State(arg->cx));
|
datalink_State(arg->cx));
|
||||||
prompt_Printf(arg->prompt, " CHAP Encryption: %s\n",
|
|
||||||
arg->cx->chap.using_MSChap ? "MSChap" : "MD5" );
|
|
||||||
prompt_Printf(arg->prompt, " Peer name: ");
|
prompt_Printf(arg->prompt, " Peer name: ");
|
||||||
if (*arg->cx->peer.authname)
|
if (*arg->cx->peer.authname)
|
||||||
prompt_Printf(arg->prompt, "%s\n", arg->cx->peer.authname);
|
prompt_Printf(arg->prompt, "%s\n", arg->cx->peer.authname);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: lcp.c,v 1.66 1999/01/12 21:50:20 brian Exp $
|
* $Id: lcp.c,v 1.67 1999/01/28 01:56:32 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* o Limit data field length by MRU
|
* o Limit data field length by MRU
|
||||||
@ -177,7 +177,13 @@ lcp_ReportStatus(struct cmdargs const *arg)
|
|||||||
prompt_Printf(arg->prompt, " ACFCOMP = %s\n",
|
prompt_Printf(arg->prompt, " ACFCOMP = %s\n",
|
||||||
command_ShowNegval(lcp->cfg.acfcomp));
|
command_ShowNegval(lcp->cfg.acfcomp));
|
||||||
prompt_Printf(arg->prompt, " CHAP = %s\n",
|
prompt_Printf(arg->prompt, " CHAP = %s\n",
|
||||||
command_ShowNegval(lcp->cfg.chap));
|
command_ShowNegval(lcp->cfg.chap05));
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
prompt_Printf(arg->prompt, " MSCHAP = %s\n",
|
||||||
|
command_ShowNegval(lcp->cfg.chap80nt));
|
||||||
|
prompt_Printf(arg->prompt, " LANMan = %s\n",
|
||||||
|
command_ShowNegval(lcp->cfg.chap80lm));
|
||||||
|
#endif
|
||||||
prompt_Printf(arg->prompt, " LQR = %s\n",
|
prompt_Printf(arg->prompt, " LQR = %s\n",
|
||||||
command_ShowNegval(lcp->cfg.lqr));
|
command_ShowNegval(lcp->cfg.lqr));
|
||||||
prompt_Printf(arg->prompt, " PAP = %s\n",
|
prompt_Printf(arg->prompt, " PAP = %s\n",
|
||||||
@ -222,7 +228,11 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
|
|||||||
lcp->cfg.fsmretry = DEF_FSMRETRY;
|
lcp->cfg.fsmretry = DEF_FSMRETRY;
|
||||||
|
|
||||||
lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
|
lcp->cfg.acfcomp = NEG_ENABLED|NEG_ACCEPTED;
|
||||||
lcp->cfg.chap = NEG_ACCEPTED;
|
lcp->cfg.chap05 = NEG_ACCEPTED;
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
lcp->cfg.chap80nt = NEG_ACCEPTED;
|
||||||
|
lcp->cfg.chap80lm = NEG_ACCEPTED;
|
||||||
|
#endif
|
||||||
lcp->cfg.lqr = NEG_ACCEPTED;
|
lcp->cfg.lqr = NEG_ACCEPTED;
|
||||||
lcp->cfg.pap = NEG_ACCEPTED;
|
lcp->cfg.pap = NEG_ACCEPTED;
|
||||||
lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
|
lcp->cfg.protocomp = NEG_ENABLED|NEG_ACCEPTED;
|
||||||
@ -244,6 +254,7 @@ lcp_Setup(struct lcp *lcp, int openmode)
|
|||||||
lcp->his_lqrperiod = 0;
|
lcp->his_lqrperiod = 0;
|
||||||
lcp->his_acfcomp = 0;
|
lcp->his_acfcomp = 0;
|
||||||
lcp->his_auth = 0;
|
lcp->his_auth = 0;
|
||||||
|
lcp->his_authtype = 0;
|
||||||
lcp->his_callback.opmask = 0;
|
lcp->his_callback.opmask = 0;
|
||||||
lcp->his_shortseq = 0;
|
lcp->his_shortseq = 0;
|
||||||
|
|
||||||
@ -260,8 +271,24 @@ lcp_Setup(struct lcp *lcp, int openmode)
|
|||||||
lcp->his_protocomp = 0;
|
lcp->his_protocomp = 0;
|
||||||
lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
|
lcp->want_protocomp = IsEnabled(lcp->cfg.protocomp) ? 1 : 0;
|
||||||
lcp->want_magic = GenerateMagic();
|
lcp->want_magic = GenerateMagic();
|
||||||
lcp->want_auth = IsEnabled(lcp->cfg.chap) ? PROTO_CHAP :
|
|
||||||
IsEnabled(lcp->cfg.pap) ? PROTO_PAP : 0;
|
if (IsEnabled(lcp->cfg.chap05)) {
|
||||||
|
lcp->want_auth = PROTO_CHAP;
|
||||||
|
lcp->want_authtype = 0x05;
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
} else if (IsEnabled(lcp->cfg.chap80nt) ||
|
||||||
|
IsEnabled(lcp->cfg.chap80lm)) {
|
||||||
|
lcp->want_auth = PROTO_CHAP;
|
||||||
|
lcp->want_authtype = 0x80;
|
||||||
|
#endif
|
||||||
|
} else if (IsEnabled(lcp->cfg.pap)) {
|
||||||
|
lcp->want_auth = PROTO_PAP;
|
||||||
|
lcp->want_authtype = 0;
|
||||||
|
} else {
|
||||||
|
lcp->want_auth = 0;
|
||||||
|
lcp->want_authtype = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->type != PHYS_DIRECT)
|
if (p->type != PHYS_DIRECT)
|
||||||
memcpy(&lcp->want_callback, &p->dl->cfg.callback, sizeof(struct callback));
|
memcpy(&lcp->want_callback, &p->dl->cfg.callback, sizeof(struct callback));
|
||||||
else
|
else
|
||||||
@ -273,6 +300,7 @@ lcp_Setup(struct lcp *lcp, int openmode)
|
|||||||
lcp->his_protocomp = lcp->want_protocomp = 1;
|
lcp->his_protocomp = lcp->want_protocomp = 1;
|
||||||
lcp->want_magic = 0;
|
lcp->want_magic = 0;
|
||||||
lcp->want_auth = 0;
|
lcp->want_auth = 0;
|
||||||
|
lcp->want_authtype = 0;
|
||||||
lcp->want_callback.opmask = 0;
|
lcp->want_callback.opmask = 0;
|
||||||
lcp->want_lqrperiod = 0;
|
lcp->want_lqrperiod = 0;
|
||||||
}
|
}
|
||||||
@ -350,7 +378,7 @@ LcpSendConfigReq(struct fsm *fp)
|
|||||||
case PROTO_CHAP:
|
case PROTO_CHAP:
|
||||||
proto = PROTO_CHAP;
|
proto = PROTO_CHAP;
|
||||||
ua_htons(&proto, o->data);
|
ua_htons(&proto, o->data);
|
||||||
o->data[2] = 0x05;
|
o->data[2] = lcp->want_authtype;
|
||||||
INC_LCP_OPT(TY_AUTHPROTO, 5, o);
|
INC_LCP_OPT(TY_AUTHPROTO, 5, o);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -615,17 +643,8 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||||||
|
|
||||||
case TY_AUTHPROTO:
|
case TY_AUTHPROTO:
|
||||||
ua_ntohs(cp + 2, &proto);
|
ua_ntohs(cp + 2, &proto);
|
||||||
switch (proto) {
|
log_Printf(LogLCP, "%s 0x%04x (%s)\n", request, proto,
|
||||||
case PROTO_PAP:
|
Auth2Nam(proto, length > 4 ? cp[4] : 0));
|
||||||
log_Printf(LogLCP, "%s 0x%04x (PAP)\n", request, proto);
|
|
||||||
break;
|
|
||||||
case PROTO_CHAP:
|
|
||||||
log_Printf(LogLCP, "%s 0x%04x (CHAP 0x%02x)\n", request, proto, cp[4]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log_Printf(LogLCP, "%s 0x%04x\n", request, proto);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mode_type) {
|
switch (mode_type) {
|
||||||
case MODE_REQ:
|
case MODE_REQ:
|
||||||
@ -637,46 +656,69 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||||||
}
|
}
|
||||||
if (IsAccepted(lcp->cfg.pap)) {
|
if (IsAccepted(lcp->cfg.pap)) {
|
||||||
lcp->his_auth = proto;
|
lcp->his_auth = proto;
|
||||||
|
lcp->his_authtype = 0;
|
||||||
memcpy(dec->ackend, cp, length);
|
memcpy(dec->ackend, cp, length);
|
||||||
dec->ackend += length;
|
dec->ackend += length;
|
||||||
} else if (IsAccepted(lcp->cfg.chap)) {
|
} else if (IsAccepted(lcp->cfg.chap05)) {
|
||||||
*dec->nakend++ = *cp;
|
*dec->nakend++ = *cp;
|
||||||
*dec->nakend++ = 5;
|
*dec->nakend++ = 5;
|
||||||
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
|
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
|
||||||
*dec->nakend++ = (unsigned char) PROTO_CHAP;
|
*dec->nakend++ = (unsigned char) PROTO_CHAP;
|
||||||
*dec->nakend++ = 0x05;
|
*dec->nakend++ = 0x05;
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
} else if (IsAccepted(lcp->cfg.chap80nt) ||
|
||||||
|
IsAccepted(lcp->cfg.chap80lm)) {
|
||||||
|
*dec->nakend++ = *cp;
|
||||||
|
*dec->nakend++ = 5;
|
||||||
|
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
|
||||||
|
*dec->nakend++ = (unsigned char) PROTO_CHAP;
|
||||||
|
*dec->nakend++ = 0x80;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
goto reqreject;
|
goto reqreject;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROTO_CHAP:
|
case PROTO_CHAP:
|
||||||
if (length < 5) {
|
if (length != 5) {
|
||||||
log_Printf(LogLCP, " Bad length!\n");
|
log_Printf(LogLCP, " Bad length!\n");
|
||||||
goto reqreject;
|
goto reqreject;
|
||||||
}
|
}
|
||||||
|
if ((cp[4] == 0x05 && IsAccepted(lcp->cfg.chap05))
|
||||||
#ifdef HAVE_DES
|
#ifdef HAVE_DES
|
||||||
if (IsAccepted(lcp->cfg.chap) && (cp[4] == 0x05 || cp[4] == 0x80))
|
|| (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
|
||||||
#else
|
(IsAccepted(lcp->cfg.chap80lm))))
|
||||||
if (IsAccepted(lcp->cfg.chap) && cp[4] == 0x05)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
) {
|
||||||
lcp->his_auth = proto;
|
lcp->his_auth = proto;
|
||||||
|
lcp->his_authtype = cp[4];
|
||||||
memcpy(dec->ackend, cp, length);
|
memcpy(dec->ackend, cp, length);
|
||||||
dec->ackend += length;
|
dec->ackend += length;
|
||||||
#ifdef HAVE_DES
|
|
||||||
link2physical(fp->link)->dl->chap.using_MSChap = cp[4] == 0x80;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
if (IsAccepted(lcp->cfg.chap)) {
|
|
||||||
#ifndef HAVE_DES
|
#ifndef HAVE_DES
|
||||||
if (cp[4] == 0x80)
|
if (cp[4] == 0x80)
|
||||||
log_Printf(LogWARN, "Chap 0x80 not available without DES\n");
|
log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
log_Printf(LogWARN, "Chap 0x%02x not supported\n",
|
if (cp[4] != 0x05)
|
||||||
(unsigned)cp[4]);
|
log_Printf(LogWARN, "%s not supported\n",
|
||||||
}
|
Auth2Nam(PROTO_CHAP, cp[4]));
|
||||||
if (IsAccepted(lcp->cfg.pap)) {
|
|
||||||
|
if (IsAccepted(lcp->cfg.chap05)) {
|
||||||
|
*dec->nakend++ = *cp;
|
||||||
|
*dec->nakend++ = 5;
|
||||||
|
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
|
||||||
|
*dec->nakend++ = (unsigned char) PROTO_CHAP;
|
||||||
|
*dec->nakend++ = 0x05;
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
} else if (IsAccepted(lcp->cfg.chap80nt) ||
|
||||||
|
IsAccepted(lcp->cfg.chap80lm)) {
|
||||||
|
*dec->nakend++ = *cp;
|
||||||
|
*dec->nakend++ = 5;
|
||||||
|
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
|
||||||
|
*dec->nakend++ = (unsigned char) PROTO_CHAP;
|
||||||
|
*dec->nakend++ = 0x80;
|
||||||
|
#endif
|
||||||
|
} else if (IsAccepted(lcp->cfg.pap)) {
|
||||||
*dec->nakend++ = *cp;
|
*dec->nakend++ = *cp;
|
||||||
*dec->nakend++ = 4;
|
*dec->nakend++ = 4;
|
||||||
*dec->nakend++ = (unsigned char) (PROTO_PAP >> 8);
|
*dec->nakend++ = (unsigned char) (PROTO_PAP >> 8);
|
||||||
@ -697,18 +739,33 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||||||
case MODE_NAK:
|
case MODE_NAK:
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case PROTO_PAP:
|
case PROTO_PAP:
|
||||||
if (IsEnabled(lcp->cfg.pap))
|
if (IsEnabled(lcp->cfg.pap)) {
|
||||||
lcp->want_auth = PROTO_PAP;
|
lcp->want_auth = PROTO_PAP;
|
||||||
else {
|
lcp->want_authtype = 0;
|
||||||
|
} else {
|
||||||
log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
|
log_Printf(LogLCP, "Peer will only send PAP (not enabled)\n");
|
||||||
lcp->his_reject |= (1 << type);
|
lcp->his_reject |= (1 << type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROTO_CHAP:
|
case PROTO_CHAP:
|
||||||
if (IsEnabled(lcp->cfg.chap))
|
if (cp[4] == 0x05 && IsEnabled(lcp->cfg.chap05)) {
|
||||||
lcp->want_auth = PROTO_CHAP;
|
lcp->want_auth = PROTO_CHAP;
|
||||||
else {
|
lcp->want_authtype = 0x05;
|
||||||
log_Printf(LogLCP, "Peer will only send CHAP (not enabled)\n");
|
#ifdef HAVE_DES
|
||||||
|
} else if (cp[4] == 0x80 && (IsEnabled(lcp->cfg.chap80nt) ||
|
||||||
|
IsEnabled(lcp->cfg.chap80lm))) {
|
||||||
|
lcp->want_auth = PROTO_CHAP;
|
||||||
|
lcp->want_authtype = 0x80;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifndef HAVE_DES
|
||||||
|
if (cp[4] == 0x80)
|
||||||
|
log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
|
||||||
|
" without DES)\n");
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
log_Printf(LogLCP, "Peer will only send %s (not supported)\n",
|
||||||
|
Auth2Nam(PROTO_CHAP, cp[4]));
|
||||||
lcp->his_reject |= (1 << type);
|
lcp->his_reject |= (1 << type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: lcp.h,v 1.18 1998/06/27 23:48:48 brian Exp $
|
* $Id: lcp.h,v 1.19 1998/08/07 18:42:49 brian Exp $
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
*/
|
*/
|
||||||
@ -46,6 +46,7 @@ struct lcp {
|
|||||||
u_int32_t his_magic; /* Peers magic number */
|
u_int32_t his_magic; /* Peers magic number */
|
||||||
u_int32_t his_lqrperiod; /* Peers LQR frequency (100ths of seconds) */
|
u_int32_t his_lqrperiod; /* Peers LQR frequency (100ths of seconds) */
|
||||||
u_short his_auth; /* Peer wants this type of authentication */
|
u_short his_auth; /* Peer wants this type of authentication */
|
||||||
|
u_char his_authtype; /* Fifth octet of REQ/NAK/REJ */
|
||||||
struct callback his_callback; /* Peer wants callback ? */
|
struct callback his_callback; /* Peer wants callback ? */
|
||||||
unsigned his_shortseq : 1; /* Peer would like only 12bit seqs (MP) */
|
unsigned his_shortseq : 1; /* Peer would like only 12bit seqs (MP) */
|
||||||
unsigned his_protocomp : 1; /* Does peer do Protocol field compression */
|
unsigned his_protocomp : 1; /* Does peer do Protocol field compression */
|
||||||
@ -57,6 +58,7 @@ struct lcp {
|
|||||||
u_int32_t want_magic; /* Our magic number */
|
u_int32_t want_magic; /* Our magic number */
|
||||||
u_int32_t want_lqrperiod; /* Our LQR frequency (100ths of seconds) */
|
u_int32_t want_lqrperiod; /* Our LQR frequency (100ths of seconds) */
|
||||||
u_short want_auth; /* We want this type of authentication */
|
u_short want_auth; /* We want this type of authentication */
|
||||||
|
u_char want_authtype; /* Fifth octet of REQ/NAK/REJ */
|
||||||
struct callback want_callback;/* We want callback ? */
|
struct callback want_callback;/* We want callback ? */
|
||||||
unsigned want_shortseq : 1; /* I'd like only 12bit seqs (MP) */
|
unsigned want_shortseq : 1; /* I'd like only 12bit seqs (MP) */
|
||||||
unsigned want_protocomp : 1; /* Do we do protocol field compression */
|
unsigned want_protocomp : 1; /* Do we do protocol field compression */
|
||||||
@ -78,7 +80,11 @@ struct lcp {
|
|||||||
u_int fsmretry; /* FSM retry frequency */
|
u_int fsmretry; /* FSM retry frequency */
|
||||||
|
|
||||||
unsigned acfcomp : 2; /* Address & Control Field Compression neg */
|
unsigned acfcomp : 2; /* Address & Control Field Compression neg */
|
||||||
unsigned chap : 2; /* Challenge Handshake Authentication proto */
|
unsigned chap05 : 2; /* Challenge Handshake Authentication proto */
|
||||||
|
#ifdef HAVE_DES
|
||||||
|
unsigned chap80nt : 2; /* Microsoft (NT) CHAP */
|
||||||
|
unsigned chap80lm : 2; /* Microsoft (LANMan) CHAP */
|
||||||
|
#endif
|
||||||
unsigned lqr : 2; /* Link Quality Report */
|
unsigned lqr : 2; /* Link Quality Report */
|
||||||
unsigned pap : 2; /* Password Authentication protocol */
|
unsigned pap : 2; /* Password Authentication protocol */
|
||||||
unsigned protocomp : 2; /* Protocol field compression */
|
unsigned protocomp : 2; /* Protocol field compression */
|
||||||
@ -120,7 +126,6 @@ struct lcp_opt {
|
|||||||
|
|
||||||
struct mbuf;
|
struct mbuf;
|
||||||
struct link;
|
struct link;
|
||||||
struct physical;
|
|
||||||
struct bundle;
|
struct bundle;
|
||||||
struct cmdargs;
|
struct cmdargs;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: ppp.8,v 1.148 1999/02/14 12:16:41 brian Exp $
|
.\" $Id: ppp.8,v 1.149 1999/02/16 00:16:56 brian Exp $
|
||||||
.Dd 20 September 1995
|
.Dd 20 September 1995
|
||||||
.nr XX \w'\fC00'
|
.nr XX \w'\fC00'
|
||||||
.Os FreeBSD
|
.Os FreeBSD
|
||||||
@ -2111,7 +2111,7 @@ may be one of the following:
|
|||||||
Default: Enabled and Accepted. ACFComp stands for Address and Control
|
Default: Enabled and Accepted. ACFComp stands for Address and Control
|
||||||
Field Compression. Non LCP packets usually have very similar address
|
Field Compression. Non LCP packets usually have very similar address
|
||||||
and control fields - making them easily compressible.
|
and control fields - making them easily compressible.
|
||||||
.It chap
|
.It chap[05]
|
||||||
Default: Disabled and Accepted. CHAP stands for Challenge Handshake
|
Default: Disabled and Accepted. CHAP stands for Challenge Handshake
|
||||||
Authentication Protocol. Only one of CHAP and PAP (below) may be
|
Authentication Protocol. Only one of CHAP and PAP (below) may be
|
||||||
negotiated. With CHAP, the authenticator sends a "challenge" message
|
negotiated. With CHAP, the authenticator sends a "challenge" message
|
||||||
@ -2210,6 +2210,18 @@ them. The answer is taken from
|
|||||||
unless the
|
unless the
|
||||||
.Dq set dns
|
.Dq set dns
|
||||||
command is used as an override.
|
command is used as an override.
|
||||||
|
.It LANMan|chap80lm
|
||||||
|
Default: Disabled and Accepted. The use of this authentication protocol
|
||||||
|
is discouraged as it partially violates the authentication protocol by
|
||||||
|
implementing two different mechanisms (LANMan & NT) under the guise of
|
||||||
|
a single CHAP type (0x80).
|
||||||
|
.Dq LANMan
|
||||||
|
uses a simple DES encryption mechanism and is the least secure of the
|
||||||
|
CHAP alternatives (although is still more secure than PAP).
|
||||||
|
.Pp
|
||||||
|
Refer to the
|
||||||
|
.Dq MSChap
|
||||||
|
description below for more details.
|
||||||
.It lqr
|
.It lqr
|
||||||
Default: Disabled and Accepted. This option decides if Link Quality
|
Default: Disabled and Accepted. This option decides if Link Quality
|
||||||
Requests will be sent or accepted. LQR is a protocol that allows
|
Requests will be sent or accepted. LQR is a protocol that allows
|
||||||
@ -2238,6 +2250,39 @@ level, and any appropriate
|
|||||||
.Dq reconnect
|
.Dq reconnect
|
||||||
values are honoured as if the peer were responsible for dropping the
|
values are honoured as if the peer were responsible for dropping the
|
||||||
connection.
|
connection.
|
||||||
|
.It MSChap|chap80nt
|
||||||
|
Default: Disabled and Accepted. The use of this authentication protocol
|
||||||
|
is discouraged as it partially violates the authentication protocol by
|
||||||
|
implementing two different mechanisms (LANMan & NT) under the guise of
|
||||||
|
a single CHAP type (0x80). It is very similar to standard CHAP (type 0x05)
|
||||||
|
except that it issues challenges of a fixed 8 bytes in length and uses a
|
||||||
|
combination of MD4 and DES to encrypt the challenge rather than using the
|
||||||
|
standard MD5 mechanism. CHAP type 0x80 for LANMan is also supported - see
|
||||||
|
.Dq enable LANMan
|
||||||
|
for details.
|
||||||
|
.Pp
|
||||||
|
Because both
|
||||||
|
.Dq LANMan
|
||||||
|
and
|
||||||
|
.Dq NT
|
||||||
|
use CHAP type 0x80, when acting as authenticator with both
|
||||||
|
.Dq enable Ns No d ,
|
||||||
|
.Nm
|
||||||
|
will rechallenge the peer up to three times if it responds using the wrong
|
||||||
|
one of the two protocols. This gives the peer a chance to attempt using
|
||||||
|
both protocols.
|
||||||
|
.Pp
|
||||||
|
Conversely, when
|
||||||
|
.Nm
|
||||||
|
acts as the authenticatee with both protocols
|
||||||
|
.Dq accept Ns No ed ,
|
||||||
|
the protocols are used alternately in response to challenges.
|
||||||
|
.Pp
|
||||||
|
Note: If only LANMan is enabled,
|
||||||
|
.Xr pppd 8
|
||||||
|
(version 2.3.5) misbehaves when acting as authenticatee. It provides both
|
||||||
|
the NT and the LANMan answers, but also suggests that only the NT answer
|
||||||
|
should be used.
|
||||||
.It pap
|
.It pap
|
||||||
Default: Disabled and Accepted. PAP stands for Password Authentication
|
Default: Disabled and Accepted. PAP stands for Password Authentication
|
||||||
Protocol. Only one of PAP and CHAP (above) may be negotiated. With
|
Protocol. Only one of PAP and CHAP (above) may be negotiated. With
|
||||||
@ -2253,7 +2298,9 @@ and have an entry in
|
|||||||
.Pa /etc/ppp/ppp.secret
|
.Pa /etc/ppp/ppp.secret
|
||||||
for the peer (although see the
|
for the peer (although see the
|
||||||
.Dq passwdauth
|
.Dq passwdauth
|
||||||
option below).
|
and
|
||||||
|
.Dq set radius
|
||||||
|
options below).
|
||||||
.Pp
|
.Pp
|
||||||
When using PAP as the client, you need only specify
|
When using PAP as the client, you need only specify
|
||||||
.Dq AuthName
|
.Dq AuthName
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: ppp.8,v 1.148 1999/02/14 12:16:41 brian Exp $
|
.\" $Id: ppp.8,v 1.149 1999/02/16 00:16:56 brian Exp $
|
||||||
.Dd 20 September 1995
|
.Dd 20 September 1995
|
||||||
.nr XX \w'\fC00'
|
.nr XX \w'\fC00'
|
||||||
.Os FreeBSD
|
.Os FreeBSD
|
||||||
@ -2111,7 +2111,7 @@ may be one of the following:
|
|||||||
Default: Enabled and Accepted. ACFComp stands for Address and Control
|
Default: Enabled and Accepted. ACFComp stands for Address and Control
|
||||||
Field Compression. Non LCP packets usually have very similar address
|
Field Compression. Non LCP packets usually have very similar address
|
||||||
and control fields - making them easily compressible.
|
and control fields - making them easily compressible.
|
||||||
.It chap
|
.It chap[05]
|
||||||
Default: Disabled and Accepted. CHAP stands for Challenge Handshake
|
Default: Disabled and Accepted. CHAP stands for Challenge Handshake
|
||||||
Authentication Protocol. Only one of CHAP and PAP (below) may be
|
Authentication Protocol. Only one of CHAP and PAP (below) may be
|
||||||
negotiated. With CHAP, the authenticator sends a "challenge" message
|
negotiated. With CHAP, the authenticator sends a "challenge" message
|
||||||
@ -2210,6 +2210,18 @@ them. The answer is taken from
|
|||||||
unless the
|
unless the
|
||||||
.Dq set dns
|
.Dq set dns
|
||||||
command is used as an override.
|
command is used as an override.
|
||||||
|
.It LANMan|chap80lm
|
||||||
|
Default: Disabled and Accepted. The use of this authentication protocol
|
||||||
|
is discouraged as it partially violates the authentication protocol by
|
||||||
|
implementing two different mechanisms (LANMan & NT) under the guise of
|
||||||
|
a single CHAP type (0x80).
|
||||||
|
.Dq LANMan
|
||||||
|
uses a simple DES encryption mechanism and is the least secure of the
|
||||||
|
CHAP alternatives (although is still more secure than PAP).
|
||||||
|
.Pp
|
||||||
|
Refer to the
|
||||||
|
.Dq MSChap
|
||||||
|
description below for more details.
|
||||||
.It lqr
|
.It lqr
|
||||||
Default: Disabled and Accepted. This option decides if Link Quality
|
Default: Disabled and Accepted. This option decides if Link Quality
|
||||||
Requests will be sent or accepted. LQR is a protocol that allows
|
Requests will be sent or accepted. LQR is a protocol that allows
|
||||||
@ -2238,6 +2250,39 @@ level, and any appropriate
|
|||||||
.Dq reconnect
|
.Dq reconnect
|
||||||
values are honoured as if the peer were responsible for dropping the
|
values are honoured as if the peer were responsible for dropping the
|
||||||
connection.
|
connection.
|
||||||
|
.It MSChap|chap80nt
|
||||||
|
Default: Disabled and Accepted. The use of this authentication protocol
|
||||||
|
is discouraged as it partially violates the authentication protocol by
|
||||||
|
implementing two different mechanisms (LANMan & NT) under the guise of
|
||||||
|
a single CHAP type (0x80). It is very similar to standard CHAP (type 0x05)
|
||||||
|
except that it issues challenges of a fixed 8 bytes in length and uses a
|
||||||
|
combination of MD4 and DES to encrypt the challenge rather than using the
|
||||||
|
standard MD5 mechanism. CHAP type 0x80 for LANMan is also supported - see
|
||||||
|
.Dq enable LANMan
|
||||||
|
for details.
|
||||||
|
.Pp
|
||||||
|
Because both
|
||||||
|
.Dq LANMan
|
||||||
|
and
|
||||||
|
.Dq NT
|
||||||
|
use CHAP type 0x80, when acting as authenticator with both
|
||||||
|
.Dq enable Ns No d ,
|
||||||
|
.Nm
|
||||||
|
will rechallenge the peer up to three times if it responds using the wrong
|
||||||
|
one of the two protocols. This gives the peer a chance to attempt using
|
||||||
|
both protocols.
|
||||||
|
.Pp
|
||||||
|
Conversely, when
|
||||||
|
.Nm
|
||||||
|
acts as the authenticatee with both protocols
|
||||||
|
.Dq accept Ns No ed ,
|
||||||
|
the protocols are used alternately in response to challenges.
|
||||||
|
.Pp
|
||||||
|
Note: If only LANMan is enabled,
|
||||||
|
.Xr pppd 8
|
||||||
|
(version 2.3.5) misbehaves when acting as authenticatee. It provides both
|
||||||
|
the NT and the LANMan answers, but also suggests that only the NT answer
|
||||||
|
should be used.
|
||||||
.It pap
|
.It pap
|
||||||
Default: Disabled and Accepted. PAP stands for Password Authentication
|
Default: Disabled and Accepted. PAP stands for Password Authentication
|
||||||
Protocol. Only one of PAP and CHAP (above) may be negotiated. With
|
Protocol. Only one of PAP and CHAP (above) may be negotiated. With
|
||||||
@ -2253,7 +2298,9 @@ and have an entry in
|
|||||||
.Pa /etc/ppp/ppp.secret
|
.Pa /etc/ppp/ppp.secret
|
||||||
for the peer (although see the
|
for the peer (although see the
|
||||||
.Dq passwdauth
|
.Dq passwdauth
|
||||||
option below).
|
and
|
||||||
|
.Dq set radius
|
||||||
|
options below).
|
||||||
.Pp
|
.Pp
|
||||||
When using PAP as the client, you need only specify
|
When using PAP as the client, you need only specify
|
||||||
.Dq AuthName
|
.Dq AuthName
|
||||||
|
Loading…
Reference in New Issue
Block a user