Allow Microsoft CHAP authentication.

This is a combination of MD4 & DES.
Submitted by:	Gabor Kincses <gabor@acm.org>
This commit is contained in:
Brian Somers 1997-09-25 00:52:37 +00:00
parent 2938fb783c
commit 7351f9d8e8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=29840
9 changed files with 145 additions and 61 deletions

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.23 1997/08/31 20:18:03 brian Exp $
# $Id: Makefile,v 1.24 1997/09/04 00:38:17 brian Exp $
PROG= ppp
SRCS= alias_cmd.c arp.c async.c auth.c ccp.c chap.c chat.c command.c \
@ -13,4 +13,11 @@ BINMODE=4550
BINOWN= root
BINGRP= network
.if exists(${DESTDIR}/usr/include/des.h) && !defined(NOSECURE)
CFLAGS+=-DHAVE_DES
SRCS+= chap_ms.c
LDADD+= -ldes
DPADD+= ${LIBDES}
.endif
.include <bsd.prog.mk>

View File

@ -17,15 +17,18 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chap.c,v 1.21 1997/09/17 23:17:48 brian Exp $
* $Id: chap.c,v 1.22 1997/09/22 23:59:13 brian Exp $
*
* TODO:
*/
#include <sys/types.h>
#include <time.h>
#include <utmp.h>
#include <ctype.h>
#include "fsm.h"
#include "chap.h"
#include "chap_ms.h"
#include "lcpproto.h"
#include "lcp.h"
#include "hdlc.h"
@ -101,10 +104,13 @@ RecvChapTalk(struct fsmheader * chp, struct mbuf * bp)
int arglen, keylen, namelen;
char *cp, *argp, *ap, *name, *digest;
char *keyp;
MD4_CTX MD4context; /* context for MD4 */
MD5_CTX MD5context; /* context for MD5 */
char answer[100];
char cdigest[16];
#ifdef HAVE_DES
int ix;
MD4_CTX MD4context; /* context for MD4 */
#endif
len = ntohs(chp->length);
LogPrintf(LogDEBUG, "RecvChapTalk: length: %d\n", len);
@ -131,34 +137,64 @@ RecvChapTalk(struct fsmheader * chp, struct mbuf * bp)
}
name = VarAuthName;
namelen = strlen(VarAuthName);
argp = malloc(1 + valsize + namelen + 16);
#ifdef HAVE_DES
if (VarMSChap)
argp = malloc(1 + namelen + MS_CHAP_RESPONSE_LEN);
else
#endif
argp = malloc(1 + valsize + namelen + 16);
if (argp == NULL) {
ChapOutput(CHAP_FAILURE, chp->id, "Out of memory!", 14);
return;
}
digest = argp;
*digest++ = 16; /* value size */
ap = answer;
*ap++ = chp->id;
bcopy(keyp, ap, keylen);
ap += keylen;
bcopy(cp, ap, valsize);
LogDumpBuff(LogDEBUG, "recv", ap, valsize);
ap += valsize;
if (VarEncMD4) {
#ifdef HAVE_DES
if (VarMSChap) {
digest = argp; /* this is the response */
*digest++ = MS_CHAP_RESPONSE_LEN; /* 49 */
bzero(digest, 24); digest += 24;
ap = answer; /* this is the challenge */
bcopy(keyp, ap, keylen);
ap += 2 * keylen;
bcopy(cp, ap, valsize);
LogDumpBuff(LogDEBUG, "recv", ap, valsize);
ap += valsize;
for (ix = keylen; ix > 0 ; ix--) {
answer[2*ix-2] = answer[ix-1];
answer[2*ix-1] = 0;
}
MD4Init(&MD4context);
MD4Update(&MD4context, answer, ap - answer);
MD4Update(&MD4context, answer, 2 * keylen);
MD4Final(digest, &MD4context);
bcopy(name, digest + 25, namelen);
ap += 2 * keylen;
ChapMS(digest, answer + 2 * keylen, valsize);
LogDumpBuff(LogDEBUG, "answer", digest, 24);
ChapOutput(CHAP_RESPONSE, chp->id, argp, namelen + MS_CHAP_RESPONSE_LEN + 1);
} else {
#endif
digest = argp;
*digest++ = 16; /* value size */
ap = answer;
*ap++ = chp->id;
bcopy(keyp, ap, keylen);
ap += keylen;
bcopy(cp, ap, valsize);
LogDumpBuff(LogDEBUG, "recv", ap, valsize);
ap += valsize;
MD5Init(&MD5context);
MD5Update(&MD5context, answer, ap - answer);
MD5Final(digest, &MD5context);
LogDumpBuff(LogDEBUG, "answer", digest, 16);
bcopy(name, digest + 16, namelen);
ap += namelen;
/* Send answer to the peer */
ChapOutput(CHAP_RESPONSE, chp->id, argp, namelen + 17);
#ifdef HAVE_DES
}
LogDumpBuff(LogDEBUG, "answer", digest, 16);
bcopy(name, digest + 16, namelen);
ap += namelen;
/* Send answer to the peer */
ChapOutput(CHAP_RESPONSE, chp->id, argp, namelen + 17);
#endif
free(argp);
break;
case CHAP_RESPONSE:
@ -172,17 +208,10 @@ RecvChapTalk(struct fsmheader * chp, struct mbuf * bp)
*ap++ = chp->id;
bcopy(keyp, ap, keylen);
ap += keylen;
if (VarEncMD4) {
MD4Init(&MD4context);
MD4Update(&MD4context, answer, ap - answer);
MD4Update(&MD4context, challenge_data + 1, challenge_len);
MD4Final(cdigest, &MD4context);
} else {
MD5Init(&MD5context);
MD5Update(&MD5context, answer, ap - answer);
MD5Update(&MD5context, challenge_data + 1, challenge_len);
MD5Final(cdigest, &MD5context);
}
MD5Init(&MD5context);
MD5Update(&MD5context, answer, ap - answer);
MD5Update(&MD5context, challenge_data + 1, challenge_len);
MD5Final(cdigest, &MD5context);
LogDumpBuff(LogDEBUG, "got", cp, 16);
LogDumpBuff(LogDEBUG, "expect", cdigest, 16);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.83 1997/09/21 13:07:57 brian Exp $
* $Id: command.c,v 1.84 1997/09/22 00:46:51 brian Exp $
*
*/
#include <sys/types.h>
@ -467,7 +467,9 @@ ShowAuthKey()
return 0;
fprintf(VarTerm, "AuthName = %s\n", VarAuthName);
fprintf(VarTerm, "AuthKey = %s\n", VarAuthKey);
fprintf(VarTerm, "Encrypt = %s\n", VarEncMD4 ? "MD4" : "MD5" );
#ifdef HAVE_DES
fprintf(VarTerm, "Encrypt = %s\n", VarMSChap ? "MSChap" : "MD5" );
#endif
return 1;
}
@ -1245,9 +1247,11 @@ SetVariable(struct cmdtab const * list, int argc, char **argv, int param)
strncpy(VarHangupScript, arg, sizeof(VarHangupScript) - 1);
VarHangupScript[sizeof(VarHangupScript) - 1] = '\0';
break;
#ifdef HAVE_DES
case VAR_ENC:
VarEncMD4 = !strcasecmp(arg, "md4");
VarMSChap = !strcasecmp(arg, "mschap");
break;
#endif
}
return 0;
}
@ -1302,8 +1306,10 @@ struct cmdtab const SetCommands[] = {
"Set demand filter", "set dfilter ..."},
{"dial", NULL, SetVariable, LOCAL_AUTH,
"Set dialing script", "set dial chat-script", (void *) VAR_DIAL},
#ifdef HAVE_DES
{"encrypt", NULL, SetVariable, LOCAL_AUTH,
"Set CHAP encryption algorithm", "set encrypt MD4|MD5", (void *) VAR_ENC},
"Set CHAP encryption algorithm", "set encrypt MSChap|MD5", (void *) VAR_ENC},
#endif
{"escape", NULL, SetEscape, LOCAL_AUTH,
"Set escape characters", "set escape hex-digit ..."},
{"hangup", NULL, SetVariable, LOCAL_AUTH,

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.h,v 1.5 1997/08/25 00:29:09 brian Exp $
* $Id: command.h,v 1.6 1997/09/22 00:46:53 brian Exp $
*
* TODO:
*/
@ -38,6 +38,7 @@ struct cmdtab {
#define VAR_ACCMAP 5
#define VAR_PHONE 6
#define VAR_HANGUP 7
#ifdef HAVE_DES
#define VAR_ENC 8
#endif
extern int SetVariable(struct cmdtab const *, int, char **, int var_param);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lcp.c,v 1.33 1997/09/22 23:59:14 brian Exp $
* $Id: lcp.c,v 1.34 1997/09/23 19:52:14 brian Exp $
*
* TODO:
* o Validate magic number received from peer.
@ -291,7 +291,11 @@ LcpSendConfigReq(struct fsm * fp)
break;
case PROTO_CHAP:
PutConfValue(&cp, cftypes, TY_AUTHPROTO, 5, lcp->want_auth);
*cp++ = 5; /* Use MD4/MD5 */
#ifdef HAVE_DES
*cp++ = VarMSChap ? 0x80 : 0x05; /* Use MSChap vs. RFC 1994 (MD5) */
#else
*cp++ = 0x05; /* Use MD5 */
#endif
break;
}
FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
@ -510,10 +514,18 @@ LcpDecodeConfig(u_char * cp, int plen, int mode)
LogPrintf(LogLCP, " %s bad length (%d)\n", request, length);
goto reqreject;
}
if (Acceptable(ConfChap) && cp[4] == 5) {
#ifdef HAVE_DES
if (Acceptable(ConfChap) && (cp[4] == 5 || cp[4] == 0x80))
#else
if (Acceptable(ConfChap) && cp[4] == 5)
#endif
{
LcpInfo.his_auth = proto;
bcopy(cp, ackp, length);
ackp += length;
#ifdef HAVE_DES
VarMSChap = cp[4] = 0x80;
#endif
} else if (Acceptable(ConfPap)) {
*nakp++ = *cp;
*nakp++ = 4;

View File

@ -17,12 +17,13 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.h,v 1.4 1997/06/09 03:27:28 brian Exp $
* $Id: main.h,v 1.5 1997/08/25 00:29:19 brian Exp $
*
*/
#ifndef _MAIN_H_
#define _MAIN_H_
void Cleanup(int);
#endif

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.66 1997/09/21 13:06:43 brian Exp $
.\" $Id: ppp.8,v 1.67 1997/09/22 23:59:15 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -1438,7 +1438,7 @@ in
.Pa ppp.conf .
CHAP is accepted by default.
Some ppp implementations use MD4 rather than MD5 when encrypting the
Some ppp implementations use "MS-CHAP" rather than MD5 when encrypting the
challenge. Refer to the description of the
.Dq set encrypt
command for further details.
@ -1689,12 +1689,24 @@ This specifies the chat script that will be used to reset the modem
before it is closed. It should not normally be necessary, but can
be used for devices that fail to reset themselves properly on close.
.It set encrypt MD4|MD5
This specifies the encryption algorithm to use when encrypting the
CHAP challenge string and defaults to MD5.
Normally, CHAP authentication is done using MD5, but some ppp
implementations (notably the RAS on Windows NT 3 & 4) use MD4
instead.
.It set encrypt MSChap|MD5
This specifies the encryption algorithm to request and use when issuing
the CHAP challenge, and defaults to MD5. If this is set to MSChap,
.Nm
will behave like a Microsoft RAS when sending the CHAP challenge (assuming
CHAP is enabled). When responding to a challenge,
.Nm
determines how to encrypt the response based on the challenge, so this
setting is ignored.
.Bl -tag -width NOTE:
.It NOTE:
Because the Microsoft encryption algorithm uses a combination of MD4 and DES,
if you have not installed DES encryption software on your machine
before building
.Nm ppp ,
this option will not be available - only MD5 will be used.
.El
.It set escape value...
This option is similar to the

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.66 1997/09/21 13:06:43 brian Exp $
.\" $Id: ppp.8,v 1.67 1997/09/22 23:59:15 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -1438,7 +1438,7 @@ in
.Pa ppp.conf .
CHAP is accepted by default.
Some ppp implementations use MD4 rather than MD5 when encrypting the
Some ppp implementations use "MS-CHAP" rather than MD5 when encrypting the
challenge. Refer to the description of the
.Dq set encrypt
command for further details.
@ -1689,12 +1689,24 @@ This specifies the chat script that will be used to reset the modem
before it is closed. It should not normally be necessary, but can
be used for devices that fail to reset themselves properly on close.
.It set encrypt MD4|MD5
This specifies the encryption algorithm to use when encrypting the
CHAP challenge string and defaults to MD5.
Normally, CHAP authentication is done using MD5, but some ppp
implementations (notably the RAS on Windows NT 3 & 4) use MD4
instead.
.It set encrypt MSChap|MD5
This specifies the encryption algorithm to request and use when issuing
the CHAP challenge, and defaults to MD5. If this is set to MSChap,
.Nm
will behave like a Microsoft RAS when sending the CHAP challenge (assuming
CHAP is enabled). When responding to a challenge,
.Nm
determines how to encrypt the response based on the challenge, so this
setting is ignored.
.Bl -tag -width NOTE:
.It NOTE:
Because the Microsoft encryption algorithm uses a combination of MD4 and DES,
if you have not installed DES encryption software on your machine
before building
.Nm ppp ,
this option will not be available - only MD5 will be used.
.El
.It set escape value...
This option is similar to the

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: vars.h,v 1.27 1997/09/17 23:17:57 brian Exp $
* $Id: vars.h,v 1.28 1997/09/22 23:59:16 brian Exp $
*
* TODO:
*/
@ -85,7 +85,9 @@ struct pppvars {
char login_script[200]; /* Login script */
char auth_key[50]; /* PAP/CHAP key */
char auth_name[50]; /* PAP/CHAP system name */
int enc_MD4; /* Use MD4 for CHAP encryption */
#ifdef HAVE_DES
int use_MSChap; /* Use MSCHAP encryption */
#endif
char phone_numbers[200]; /* Telephone Numbers */
char phone_copy[200]; /* copy for strsep() */
char *next_phone; /* Next phone from the list */
@ -113,11 +115,13 @@ struct pppvars {
#define VarRetryTimeout pppVars.retry_timeout
#define VarAuthKey pppVars.auth_key
#define VarAuthName pppVars.auth_name
#define VarEncMD4 pppVars.enc_MD4
#ifdef HAVE_DES
#define VarMSChap pppVars.use_MSChap
#endif
#define VarPhoneList pppVars.phone_numbers
#define VarPhoneCopy pppVars.phone_copy
#define VarNextPhone pppVars.next_phone
#define VarAltPhone pppVars.alt_phone
#define VarAltPhone pppVars.alt_phone
#define VarShortHost pppVars.shostname
#define VarReconnectTimer pppVars.reconnect_timer
#define VarReconnectTries pppVars.reconnect_tries