summaryrefslogtreecommitdiff
path: root/usr.sbin/ppp
diff options
context:
space:
mode:
authorbrian <brian@cvs.openbsd.org>2000-11-02 00:54:36 +0000
committerbrian <brian@cvs.openbsd.org>2000-11-02 00:54:36 +0000
commit7955efec1aed61bf8bdd9448f4a23cd289fb3e3c (patch)
treea81e4872a735b8d22d21fc21d9851ef1754bb84e /usr.sbin/ppp
parent5692c094e2a56114a53555eece196578113c1fe5 (diff)
Some whitespace changes
Some slightly better diagnostics Add MPPE and chapv2 support; Ustimenko Semen <semen@iclub.nsu.ru> Bump the version number Add ``all'' logging; perhaps@yes.no Handle quoted hash characters properly Honour ``nat deny_incoming'' properly Fix radius accounting initialisation Moan about tcsetattr() failures
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r--usr.sbin/ppp/ppp/Makefile11
-rw-r--r--usr.sbin/ppp/ppp/arp.c5
-rw-r--r--usr.sbin/ppp/ppp/ccp.c24
-rw-r--r--usr.sbin/ppp/ppp/ccp.h13
-rw-r--r--usr.sbin/ppp/ppp/chap.c165
-rw-r--r--usr.sbin/ppp/ppp/chap.h6
-rw-r--r--usr.sbin/ppp/ppp/chap_ms.c286
-rw-r--r--usr.sbin/ppp/ppp/chap_ms.h18
-rw-r--r--usr.sbin/ppp/ppp/command.c46
-rw-r--r--usr.sbin/ppp/ppp/datalink.c5
-rw-r--r--usr.sbin/ppp/ppp/defs.c4
-rw-r--r--usr.sbin/ppp/ppp/defs.h3
-rw-r--r--usr.sbin/ppp/ppp/ether.c5
-rw-r--r--usr.sbin/ppp/ppp/filter.c8
-rw-r--r--usr.sbin/ppp/ppp/lcp.c42
-rw-r--r--usr.sbin/ppp/ppp/lcp.h3
-rw-r--r--usr.sbin/ppp/ppp/log.c23
-rw-r--r--usr.sbin/ppp/ppp/main.c6
-rw-r--r--usr.sbin/ppp/ppp/mbuf.c36
-rw-r--r--usr.sbin/ppp/ppp/mp.c5
-rw-r--r--usr.sbin/ppp/ppp/mppe.c430
-rw-r--r--usr.sbin/ppp/ppp/mppe.h32
-rw-r--r--usr.sbin/ppp/ppp/nat_cmd.c8
-rw-r--r--usr.sbin/ppp/ppp/ppp.836
-rw-r--r--usr.sbin/ppp/ppp/radius.c4
-rw-r--r--usr.sbin/ppp/ppp/server.c5
-rw-r--r--usr.sbin/ppp/ppp/tty.c25
27 files changed, 1161 insertions, 93 deletions
diff --git a/usr.sbin/ppp/ppp/Makefile b/usr.sbin/ppp/ppp/Makefile
index 55dbcc3fdbb..cc5d4115c74 100644
--- a/usr.sbin/ppp/ppp/Makefile
+++ b/usr.sbin/ppp/ppp/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.18 2000/09/14 22:02:49 brian Exp $
+# $OpenBSD: Makefile,v 1.19 2000/11/02 00:54:32 brian Exp $
PROG= ppp
SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
@@ -6,12 +6,13 @@ SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chap_ms.c \
chat.c command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c \
hdlc.c iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c \
- main.c mbuf.c mp.c nat_cmd.c pap.c physical.c pred.c probe.c prompt.c \
- proto.c radius.c radlib.c route.c server.c sig.c slcompress.c \
- systems.c sync.c tcp.c throughput.c timer.c tty.c tun.c udp.c vjcomp.c
+ main.c mbuf.c mp.c mppe.c nat_cmd.c pap.c physical.c pred.c probe.c \
+ prompt.c proto.c radius.c radlib.c route.c server.c sig.c \
+ slcompress.c systems.c sync.c tcp.c throughput.c timer.c tty.c tun.c \
+ udp.c vjcomp.c
CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH -DNOI4B -DNONETGRAPH
CFLAGS+=-DLOCALNAT -DLOCALRAD
-LDADD+= -ldes -lutil -lz
+LDADD+= -lcrypto -ldes -lutil -lz
DPADD+= ${LIBDES} ${LIBUTIL} ${LIBZ}
.if defined(NOSUID) || defined(PPP_NOSUID)
BINMODE=554
diff --git a/usr.sbin/ppp/ppp/arp.c b/usr.sbin/ppp/ppp/arp.c
index f33eb15d043..602165d8f15 100644
--- a/usr.sbin/ppp/ppp/arp.c
+++ b/usr.sbin/ppp/ppp/arp.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: arp.c,v 1.7 2000/02/27 01:38:24 brian Exp $
+ * $OpenBSD: arp.c,v 1.8 2000/11/02 00:54:33 brian Exp $
*
*/
@@ -179,7 +179,8 @@ arp_SetProxy(struct bundle *bundle, struct in_addr addr, int s)
* address.
*/
if (!get_ether_addr(s, addr, &dls.sdl)) {
- log_Printf(LOG_PHASE_BIT, "Cannot determine ethernet address for proxy ARP\n");
+ log_Printf(LOG_PHASE_BIT, "Cannot determine ethernet address for "
+ "proxy ARP\n");
return 0;
}
arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
diff --git a/usr.sbin/ppp/ppp/ccp.c b/usr.sbin/ppp/ppp/ccp.c
index 31baf74edc9..7a98e451b08 100644
--- a/usr.sbin/ppp/ppp/ccp.c
+++ b/usr.sbin/ppp/ppp/ccp.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: ccp.c,v 1.14 2000/07/19 11:06:31 brian Exp $
+ * $OpenBSD: ccp.c,v 1.15 2000/11/02 00:54:33 brian Exp $
*
* TODO:
* o Support other compression protocols
@@ -61,6 +61,9 @@
#ifndef NORADIUS
#include "radius.h"
#endif
+#ifdef HAVE_DES
+#include "mppe.h"
+#endif
#include "bundle.h"
static void CcpSendConfigReq(struct fsm *);
@@ -106,7 +109,8 @@ protoname(int proto)
NULL, NULL, NULL, NULL, NULL, NULL,
"HWPPC", /* 16: Hewlett-Packard PPC */
"STAC", /* 17: Stac Electronics LZS (rfc1974) */
- "MPPC", /* 18: Microsoft PPC (rfc2118) */
+ "MPPE", /* 18: Microsoft PPC (rfc2118) and */
+ /* Microsoft PPE (draft-ietf-pppext-mppe) */
"GAND", /* 19: Gandalf FZA (rfc1993) */
"V42BIS", /* 20: ARG->DATA.42bis compression */
"BSD", /* 21: BSD LZW Compress */
@@ -130,6 +134,9 @@ static const struct ccp_algorithm * const algorithm[] = {
&DeflateAlgorithm,
&Pred1Algorithm,
&PppdDeflateAlgorithm
+#ifdef HAVE_DES
+ , &MPPEAlgorithm
+#endif
};
#define NALGORITHMS (sizeof algorithm/sizeof algorithm[0])
@@ -167,6 +174,11 @@ ccp_ReportStatus(struct cmdargs const *arg)
command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1]));
prompt_Printf(arg->prompt, " DEFLATE24: %s\n",
command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24]));
+#ifdef HAVE_DES
+ prompt_Printf(arg->prompt, " MPPE: %s",
+ command_ShowNegval(ccp->cfg.neg[CCP_NEG_MPPE]));
+ prompt_Printf(arg->prompt, " (Key Size = %d-bits)\n", ccp->cfg.mppe.keybits);
+#endif
return 0;
}
@@ -196,6 +208,10 @@ ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l,
ccp->cfg.neg[CCP_NEG_DEFLATE] = NEG_ENABLED|NEG_ACCEPTED;
ccp->cfg.neg[CCP_NEG_PRED1] = NEG_ENABLED|NEG_ACCEPTED;
ccp->cfg.neg[CCP_NEG_DEFLATE24] = 0;
+#ifdef HAVE_DES
+ ccp->cfg.mppe.keybits = 128;
+ ccp->cfg.neg[CCP_NEG_MPPE] = 0;
+#endif
ccp_Setup(ccp);
}
@@ -484,8 +500,8 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
if (o->val.id == cp[0])
break;
if (o == NULL)
- log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent option\n",
- fp->link->name);
+ log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent"
+ " option\n", fp->link->name);
else {
memcpy(&o->val, cp, length);
if ((*algorithm[f]->o.Set)(&o->val) == MODE_ACK)
diff --git a/usr.sbin/ppp/ppp/ccp.h b/usr.sbin/ppp/ppp/ccp.h
index a48e84bfa56..95f3ff15c06 100644
--- a/usr.sbin/ppp/ppp/ccp.h
+++ b/usr.sbin/ppp/ppp/ccp.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: ccp.h,v 1.5 2000/02/27 01:38:25 brian Exp $
+ * $OpenBSD: ccp.h,v 1.6 2000/11/02 00:54:33 brian Exp $
*
* TODO:
*/
@@ -29,6 +29,7 @@
#define TY_HWPPC 16 /* Hewlett-Packard PPC */
#define TY_STAC 17 /* Stac Electronics LZS */
#define TY_MSPPC 18 /* Microsoft PPC */
+#define TY_MPPE 18 /* Microsoft PPE */
#define TY_GAND 19 /* Gandalf FZA */
#define TY_V42BIS 20 /* V.42bis compression */
#define TY_BSD 21 /* BSD LZW Compress */
@@ -38,7 +39,12 @@
#define CCP_NEG_DEFLATE 0
#define CCP_NEG_PRED1 1
#define CCP_NEG_DEFLATE24 2
+#ifdef HAVE_DES
+#define CCP_NEG_MPPE 3
+#define CCP_NEG_TOTAL 4
+#else
#define CCP_NEG_TOTAL 3
+#endif
struct mbuf;
struct link;
@@ -49,6 +55,11 @@ struct ccp_config {
int winsize;
} in, out;
} deflate;
+#ifdef HAVE_DES
+ struct {
+ int keybits;
+ } mppe;
+#endif
struct fsm_retry fsm; /* How often/frequently to resend requests */
unsigned neg[CCP_NEG_TOTAL];
};
diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c
index f5b6122acb4..c7cad849796 100644
--- a/usr.sbin/ppp/ppp/chap.c
+++ b/usr.sbin/ppp/ppp/chap.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: chap.c,v 1.23 2000/08/18 00:02:10 brian Exp $
+ * $OpenBSD: chap.c,v 1.24 2000/11/02 00:54:33 brian Exp $
*
* TODO:
*/
@@ -75,6 +75,7 @@
#include "datalink.h"
#ifdef HAVE_DES
#include "chap_ms.h"
+#include "mppe.h"
#endif
#include "id.h"
@@ -111,7 +112,7 @@ ChapOutput(struct physical *physical, u_int code, u_int id,
static char *
chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, u_char type
#ifdef HAVE_DES
- , int lanman
+ , char *peerchallenge, char *authresponse, int lanman
#endif
)
{
@@ -167,6 +168,51 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, u_char type
* ---- -------- ------------- ----- ------
* where only one of LANMan & NT digest are set.
*/
+ } else if (type == 0x81) {
+ char expkey[AUTHLEN << 2];
+ char pwdhash[CHAP81_HASH_LEN];
+ char pwdhashhash[CHAP81_HASH_LEN];
+ char *ntresponse;
+ int f;
+
+ if ((result = malloc(1 + nlen + CHAP81_RESPONSE_LEN)) == NULL)
+ return result;
+
+ memset(result, 0, 1 + nlen + CHAP81_RESPONSE_LEN);
+
+ digest = result;
+ *digest++ = CHAP81_RESPONSE_LEN; /* value size */
+
+ /* Copy our challenge */
+ memcpy(digest, peerchallenge + 1, CHAP81_CHALLENGE_LEN);
+
+ /* Expand password to Unicode XXX */
+ for (f = 0; f < klen; f++) {
+ expkey[2*f] = key[f];
+ expkey[2*f+1] = '\0';
+ }
+
+ ntresponse = digest + CHAP81_NTRESPONSE_OFF;
+
+ /* Get some needed hashes */
+ NtPasswordHash(expkey, klen * 2, pwdhash);
+ HashNtPasswordHash(pwdhash, pwdhashhash);
+
+ /* Generate NTRESPONSE to respond on challenge call */
+ GenerateNTResponse(challenge + 1, peerchallenge + 1, name, nlen,
+ expkey, klen * 2, ntresponse);
+
+ /* Generate MPPE MASTERKEY */
+ GetMasterKey(pwdhashhash, ntresponse, MPPE_MasterKey);
+
+ /* Generate AUTHRESPONSE to verify on auth success */
+ GenerateAuthenticatorResponse(expkey, klen * 2, ntresponse,
+ peerchallenge + 1, challenge + 1, name, nlen,
+ authresponse);
+
+ authresponse[CHAP81_AUTHRESPONSE_LEN] = 0;
+
+ memcpy(digest + CHAP81_RESPONSE_LEN, name, nlen);
} else
#endif
if ((result = malloc(nlen + 17)) != NULL) {
@@ -316,7 +362,7 @@ chap_Respond(struct chap *chap, char *name, char *key, u_char type
ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge.peer, type
#ifdef HAVE_DES
- , lm
+ , chap->challenge.local, chap->authresponse, lm
#endif
);
@@ -421,7 +467,7 @@ chap_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
}
static void
-chap_Challenge(struct authinfo *authp)
+chap_ChallengeInit(struct authinfo *authp)
{
struct chap *chap = auth2chap(authp);
int len, i;
@@ -445,6 +491,8 @@ chap_Challenge(struct authinfo *authp)
#ifdef HAVE_DES
if (authp->physical->link.lcp.want_authtype == 0x80)
*cp++ = 8; /* MS does 8 byte callenges :-/ */
+ else if (authp->physical->link.lcp.want_authtype == 0x81)
+ *cp++ = 16; /* MS-CHAP-V2 does 16 bytes challenges */
else
#endif
*cp++ = random() % (CHAPCHALLENGELEN-16) + 16;
@@ -453,15 +501,49 @@ chap_Challenge(struct authinfo *authp)
}
memcpy(cp, authp->physical->dl->bundle->cfg.auth.name, len);
}
- ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id, chap->challenge.local,
- 1 + *chap->challenge.local + len, NULL);
+}
+
+static void
+chap_Challenge(struct authinfo *authp)
+{
+ struct chap *chap = auth2chap(authp);
+ int len;
+
+ log_Printf(LogDEBUG, "CHAP%02X: Challenge\n",
+ authp->physical->link.lcp.want_authtype);
+
+ len = strlen(authp->physical->dl->bundle->cfg.auth.name);
+
+ /* Generate new local challenge value */
+ if (!*chap->challenge.local)
+ chap_ChallengeInit(authp);
+
+#ifdef HAVE_DES
+ if (authp->physical->link.lcp.want_authtype == 0x81)
+ ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id,
+ chap->challenge.local, 1 + *chap->challenge.local, NULL);
+ else
+#endif
+ ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id,
+ chap->challenge.local, 1 + *chap->challenge.local + len, NULL);
}
static void
chap_Success(struct authinfo *authp)
{
+ const char *msg;
datalink_GotAuthname(authp->physical->dl, authp->in.name);
- ChapOutput(authp->physical, CHAP_SUCCESS, authp->id, "Welcome!!", 10, NULL);
+#ifdef HAVE_DES
+ if (authp->physical->link.lcp.want_authtype == 0x81) {
+ msg = auth2chap(authp)->authresponse;
+ MPPE_MasterKeyValid = 1;
+ } else
+#endif
+ msg = "Welcome!!";
+
+ ChapOutput(authp->physical, CHAP_SUCCESS, authp->id, msg, strlen(msg) + 1,
+ NULL);
+
authp->physical->link.lcp.auth_ineed = 0;
if (Enabled(authp->physical->dl->bundle, OPT_UTMP))
physical_Login(authp->physical, authp->in.name);
@@ -477,7 +559,29 @@ chap_Success(struct authinfo *authp)
static void
chap_Failure(struct authinfo *authp)
{
- ChapOutput(authp->physical, CHAP_FAILURE, authp->id, "Invalid!!", 9, NULL);
+#ifdef HAVE_DES
+ char buf[1024];
+#endif
+ const char *msg;
+
+#ifdef HAVE_DES
+ if (authp->physical->link.lcp.want_authtype == 0x81) {
+ char *ptr;
+ int i;
+
+ ptr = buf;
+ ptr += sprintf(buf, "E=691 R=0 C=");
+ for (i=0; i<16; i++)
+ ptr += sprintf(ptr, "%02X", *(auth2chap(authp)->challenge.local+1+i));
+
+ sprintf(ptr, " V=3 M=Invalid!");
+ msg = buf;
+ } else
+#endif
+ msg = "Invalid!!";
+
+ ChapOutput(authp->physical, CHAP_FAILURE, authp->id, msg, strlen(msg) + 1,
+ NULL);
datalink_AuthNotOk(authp->physical->dl);
}
@@ -610,6 +714,9 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
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;
@@ -632,7 +739,8 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
ans[alen+1] = '\0';
bp = auth_ReadName(&chap->auth, bp, len);
#ifdef HAVE_DES
- lanman = alen == 49 && ans[alen] == 0;
+ lanman = p->link.lcp.want_authtype == 0x80 &&
+ alen == 49 && ans[alen] == 0;
#endif
break;
@@ -717,25 +825,39 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
if (key) {
char *myans;
#ifdef HAVE_DES
- if (lanman && !IsEnabled(p->link.lcp.cfg.chap80lm)) {
+ 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 (!lanman && !IsEnabled(p->link.lcp.cfg.chap80nt) &&
- p->link.lcp.want_authtype == 0x80) {
+ } 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
{
+#ifdef HAVE_DES
+ /* Get peer's challenge */
+ if (p->link.lcp.want_authtype == 0x81) {
+ chap->challenge.peer[0] = CHAP81_CHALLENGE_LEN;
+ memcpy(chap->challenge.peer + 1, ans + 1, CHAP81_CHALLENGE_LEN);
+ }
+#endif
+
myans = chap_BuildAnswer(name, key, chap->auth.id,
chap->challenge.local,
p->link.lcp.want_authtype
#ifdef HAVE_DES
- , lanman
+ , chap->challenge.peer,
+ chap->authresponse, lanman
#endif
);
if (myans == NULL)
@@ -764,13 +886,28 @@ chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
case CHAP_SUCCESS:
if (p->link.lcp.auth_iwait == PROTO_CHAP) {
p->link.lcp.auth_iwait = 0;
- if (p->link.lcp.auth_ineed == 0)
+ if (p->link.lcp.auth_ineed == 0) {
+#ifdef HAVE_DES
+ if (p->link.lcp.his_authtype == 0x81) {
+ if (strncmp(ans, chap->authresponse, 42)) {
+ datalink_AuthNotOk(p->dl);
+ log_Printf(LogDEBUG, "CHAP81: AuthenticatorResponse: (%s)"
+ " != ans: (%s)\n", chap->authresponse, ans);
+
+ } else {
+ /* Successful login */
+ MPPE_MasterKeyValid = 1;
+ 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;
diff --git a/usr.sbin/ppp/ppp/chap.h b/usr.sbin/ppp/ppp/chap.h
index bb2a32bd447..8bbc54b19c7 100644
--- a/usr.sbin/ppp/ppp/chap.h
+++ b/usr.sbin/ppp/ppp/chap.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: chap.h,v 1.9 2000/02/27 01:38:25 brian Exp $
+ * $OpenBSD: chap.h,v 1.10 2000/11/02 00:54:33 brian Exp $
*
* TODO:
*/
@@ -46,12 +46,14 @@ struct chap {
#ifdef HAVE_DES
unsigned NTRespSent : 1; /* Our last response */
int peertries;
+ u_char authresponse[CHAPAUTHRESPONSELEN]; /* CHAP 81 response */
#endif
};
#define descriptor2chap(d) \
((d)->type == CHAP_DESCRIPTOR ? (struct chap *)(d) : NULL)
-#define auth2chap(a) (struct chap *)((char *)a - (int)&((struct chap *)0)->auth)
+#define auth2chap(a) \
+ ((struct chap *)((char *)a - (int)&((struct chap *)0)->auth))
extern void chap_Init(struct chap *, struct physical *);
extern void chap_ReInit(struct chap *);
diff --git a/usr.sbin/ppp/ppp/chap_ms.c b/usr.sbin/ppp/ppp/chap_ms.c
index 4e6cf2c3cc0..1a05a6b245a 100644
--- a/usr.sbin/ppp/ppp/chap_ms.c
+++ b/usr.sbin/ppp/ppp/chap_ms.c
@@ -19,7 +19,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: chap_ms.c,v 1.5 2000/02/27 01:38:25 brian Exp $
+ * $OpenBSD: chap_ms.c,v 1.6 2000/11/02 00:54:33 brian Exp $
*
*/
@@ -28,13 +28,37 @@
#include <ctype.h>
#ifdef __FreeBSD__
#include <openssl/des.h>
+#include <sha.h>
#else
+#include <stdlib.h>
#include <des.h>
+#include <openssl/sha.h>
#endif
+#include <md4.h>
#include <string.h>
#include "chap_ms.h"
+/*
+ * Documentation & specifications:
+ *
+ * MS-CHAP (CHAP80) rfc2433
+ * MS-CHAP-V2 (CHAP81) rfc2759
+ * MPPE key management draft-ietf-pppext-mppe-keys-02.txt
+ */
+
+static char SHA1_Pad1[40] =
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static char SHA1_Pad2[40] =
+ {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
+
/* unused, for documentation only */
/* only NTResp is filled in for FreeBSD */
struct MS_ChapResponse {
@@ -43,7 +67,8 @@ struct MS_ChapResponse {
u_char UseNT; /* If 1, ignore the LANMan response field */
};
-static u_char Get7Bits(u_char *input, int startBit)
+static u_char
+Get7Bits(u_char *input, int startBit)
{
register unsigned int word;
@@ -57,7 +82,8 @@ static u_char Get7Bits(u_char *input, int startBit)
/* IN 56 bit DES key missing parity bits
OUT 64 bit DES key with parity bits added */
-static void MakeKey(u_char *key, u_char *des_key)
+static void
+MakeKey(u_char *key, u_char *des_key)
{
des_key[0] = Get7Bits(key, 0);
des_key[1] = Get7Bits(key, 7);
@@ -95,6 +121,260 @@ ChallengeResponse(u_char *challenge, u_char *pwHash, u_char *response)
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
}
+void
+NtPasswordHash(char *key, int keylen, char *hash)
+{
+ MD4_CTX MD4context;
+
+ MD4Init(&MD4context);
+ MD4Update(&MD4context, key, keylen);
+ MD4Final(hash, &MD4context);
+}
+
+void
+HashNtPasswordHash(char *hash, char *hashhash)
+{
+ MD4_CTX MD4context;
+
+ MD4Init(&MD4context);
+ MD4Update(&MD4context, hash, 16);
+ MD4Final(hashhash, &MD4context);
+}
+
+void
+ChallengeHash(char *PeerChallenge, char *AuthenticatorChallenge,
+ char *UserName, int UserNameLen, char *Challenge)
+{
+ SHA_CTX Context;
+ char Digest[SHA_DIGEST_LENGTH];
+ char *Name;
+
+ Name = strrchr(UserName, '\\');
+ if(NULL == Name)
+ Name = UserName;
+ else
+ Name++;
+
+ SHA1_Init(&Context);
+
+ SHA1_Update(&Context, PeerChallenge, 16);
+ SHA1_Update(&Context, AuthenticatorChallenge, 16);
+ SHA1_Update(&Context, UserName, UserNameLen);
+
+ SHA1_Final(Digest, &Context);
+ memcpy(Challenge, Digest, 8);
+}
+
+void
+GenerateNTResponse(char *AuthenticatorChallenge, char *PeerChallenge,
+ char *UserName, int UserNameLen, char *Password,
+ int PasswordLen, char *Response)
+{
+ char Challenge[8];
+ char PasswordHash[16];
+
+ ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName, UserNameLen,
+ Challenge);
+ NtPasswordHash(Password, PasswordLen, PasswordHash);
+ ChallengeResponse(Challenge, PasswordHash, Response);
+}
+
+#ifndef __FreeBSD__
+#define LENGTH 20
+char *
+SHA1_End(SHA_CTX *ctx, char *buf)
+{
+ int i;
+ unsigned char digest[LENGTH];
+ static const char hex[]="0123456789abcdef";
+
+ if (!buf)
+ buf = malloc(2*LENGTH + 1);
+ if (!buf)
+ return 0;
+ SHA1_Final(digest, ctx);
+ for (i = 0; i < LENGTH; i++) {
+ buf[i+i] = hex[digest[i] >> 4];
+ buf[i+i+1] = hex[digest[i] & 0x0f];
+ }
+ buf[i+i] = '\0';
+ return buf;
+}
+#endif
+
+void
+GenerateAuthenticatorResponse(char *Password, int PasswordLen,
+ char *NTResponse, char *PeerChallenge,
+ char *AuthenticatorChallenge, char *UserName,
+ int UserNameLen, char *AuthenticatorResponse)
+{
+ SHA_CTX Context;
+ char PasswordHash[16];
+ char PasswordHashHash[16];
+ char Challenge[8];
+ u_char Digest[SHA_DIGEST_LENGTH];
+ int i;
+
+ /*
+ * "Magic" constants used in response generation
+ */
+ char Magic1[39] =
+ {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
+ 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
+ 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74};
+
+
+ char Magic2[41] =
+ {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
+ 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
+ 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
+ 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E};
+ /*
+ * Hash the password with MD4
+ */
+ NtPasswordHash(Password, PasswordLen, PasswordHash);
+ /*
+ * Now hash the hash
+ */
+ HashNtPasswordHash(PasswordHash, PasswordHashHash);
+
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, PasswordHashHash, 16);
+ SHA1_Update(&Context, NTResponse, 24);
+ SHA1_Update(&Context, Magic1, 39);
+ SHA1_Final(Digest, &Context);
+ ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName, UserNameLen,
+ Challenge);
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, Digest, 20);
+ SHA1_Update(&Context, Challenge, 8);
+ SHA1_Update(&Context, Magic2, 41);
+
+ /*
+ * Encode the value of 'Digest' as "S=" followed by
+ * 40 ASCII hexadecimal digits and return it in
+ * AuthenticatorResponse.
+ * For example,
+ * "S=0123456789ABCDEF0123456789ABCDEF01234567"
+ */
+ AuthenticatorResponse[0] = 'S';
+ AuthenticatorResponse[1] = '=';
+ SHA1_End(&Context, AuthenticatorResponse + 2);
+ for (i=2; i<42; i++)
+ AuthenticatorResponse[i] = toupper(AuthenticatorResponse[i]);
+
+}
+
+void
+GetMasterKey(char *PasswordHashHash, char *NTResponse, char *MasterKey)
+{
+ char Digest[SHA_DIGEST_LENGTH];
+ SHA_CTX Context;
+ static char Magic1[27] =
+ {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
+ 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79};
+
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, PasswordHashHash, 16);
+ SHA1_Update(&Context, NTResponse, 24);
+ SHA1_Update(&Context, Magic1, 27);
+ SHA1_Final(Digest, &Context);
+ memcpy(MasterKey, Digest, 16);
+}
+
+void
+GetAsymetricStartKey(char *MasterKey, char *SessionKey, int SessionKeyLength,
+ int IsSend, int IsServer)
+{
+ char Digest[SHA_DIGEST_LENGTH];
+ SHA_CTX Context;
+ char *s;
+
+ static char Magic2[84] =
+ {0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+ 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+ 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
+ 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+ 0x6b, 0x65, 0x79, 0x2e};
+
+ static char Magic3[84] =
+ {0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+ 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+ 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
+ 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
+ 0x6b, 0x65, 0x79, 0x2e};
+
+ if (IsSend) {
+ if (IsServer) {
+ s = Magic3;
+ } else {
+ s = Magic2;
+ }
+ } else {
+ if (IsServer) {
+ s = Magic2;
+ } else {
+ s = Magic3;
+ }
+ }
+
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, MasterKey, 16);
+ SHA1_Update(&Context, SHA1_Pad1, 40);
+ SHA1_Update(&Context, s, 84);
+ SHA1_Update(&Context, SHA1_Pad2, 40);
+ SHA1_Final(Digest, &Context);
+
+ memcpy(SessionKey, Digest, SessionKeyLength);
+}
+
+void
+GetNewKeyFromSHA(char *StartKey, char *SessionKey, long SessionKeyLength,
+ char *InterimKey)
+{
+ SHA_CTX Context;
+ char Digest[SHA_DIGEST_LENGTH];
+
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, StartKey, SessionKeyLength);
+ SHA1_Update(&Context, SHA1_Pad1, 40);
+ SHA1_Update(&Context, SessionKey, SessionKeyLength);
+ SHA1_Update(&Context, SHA1_Pad2, 40);
+ SHA1_Final(Digest, &Context);
+
+ memcpy(InterimKey, Digest, SessionKeyLength);
+}
+
+#if 0
+static void
+Get_Key(char *InitialSessionKey, char *CurrentSessionKey,
+ int LengthOfDesiredKey)
+{
+ SHA_CTX Context;
+ char Digest[SHA_DIGEST_LENGTH];
+
+ SHA1_Init(&Context);
+ SHA1_Update(&Context, InitialSessionKey, LengthOfDesiredKey);
+ SHA1_Update(&Context, SHA1_Pad1, 40);
+ SHA1_Update(&Context, CurrentSessionKey, LengthOfDesiredKey);
+ SHA1_Update(&Context, SHA1_Pad2, 40);
+ SHA1_Final(Digest, &Context);
+
+ memcpy(CurrentSessionKey, Digest, LengthOfDesiredKey);
+}
+#endif
+
/* passwordHash 16-bytes MD4 hashed password
challenge 8-bytes peer CHAP challenge
since passwordHash is in a 24-byte buffer, response is written in there */
diff --git a/usr.sbin/ppp/ppp/chap_ms.h b/usr.sbin/ppp/ppp/chap_ms.h
index bb4f26bb7a0..ae5ba35c3d5 100644
--- a/usr.sbin/ppp/ppp/chap_ms.h
+++ b/usr.sbin/ppp/ppp/chap_ms.h
@@ -19,14 +19,28 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: chap_ms.h,v 1.4 2000/02/27 01:38:25 brian Exp $
+ * $OpenBSD: chap_ms.h,v 1.5 2000/11/02 00:54:33 brian Exp $
*/
/* Max # of (Unicode) chars in an NT password */
#define MAX_NT_PASSWORD 256
/* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
-#define MS_CHAP_RESPONSE_LEN 49
+#define MS_CHAP_RESPONSE_LEN 49
+#define CHAP81_RESPONSE_LEN 49
+#define CHAP81_NTRESPONSE_LEN 24
+#define CHAP81_NTRESPONSE_OFF 24
+#define CHAP81_HASH_LEN 16
+#define CHAP81_AUTHRESPONSE_LEN 42
+#define CHAP81_CHALLENGE_LEN 16
extern void mschap_NT(char *, char *);
extern void mschap_LANMan(char *, char *, char *);
+extern void GenerateNTResponse(char *, char *, char *, int, char *, int , char *);
+extern void HashNtPasswordHash(char *, char *);
+extern void NtPasswordHash(char *, int, char *);
+extern void ChallengeHash(char *, char *, char *UserName, int, char *);
+extern void GenerateAuthenticatorResponse(char *, int, char *, char *, char *, char *, int, char *);
+extern void GetAsymetricStartKey(char *, char *, int, int, int);
+extern void GetMasterKey(char *, char *, char *);
+extern void GetNewKeyFromSHA(char *, char *, long, char *);
diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c
index 42bf6cdf55b..eec0206792d 100644
--- a/usr.sbin/ppp/ppp/command.c
+++ b/usr.sbin/ppp/ppp/command.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: command.c,v 1.52 2000/09/06 21:03:38 brian Exp $
+ * $OpenBSD: command.c,v 1.53 2000/11/02 00:54:33 brian Exp $
*
*/
#include <sys/param.h>
@@ -127,6 +127,7 @@
#define VAR_URGENTPORTS 33
#define VAR_LOGOUT 34
#define VAR_IFQUEUE 35
+#define VAR_KEYBITS 36
/* ``accept|deny|disable|enable'' masks */
#define NEG_HISMASK (1)
@@ -147,8 +148,10 @@
#define NEG_PROTOCOMP 51
#define NEG_SHORTSEQ 52
#define NEG_VJCOMP 53
+#define NEG_MPPE 54
+#define NEG_CHAP81 55
-const char Version[] = "2.27";
+const char Version[] = "2.3";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@@ -1574,6 +1577,24 @@ SetVariable(struct cmdargs const *arg)
}
break;
+#ifdef HAVE_DES
+ case VAR_KEYBITS:
+ if (arg->argc > arg->argn) {
+ l->ccp.cfg.mppe.keybits = atoi(arg->argv[arg->argn]);
+ if (l->ccp.cfg.mppe.keybits != 40 &&
+ l->ccp.cfg.mppe.keybits != 56 &&
+ l->ccp.cfg.mppe.keybits != 128 ) {
+ log_Printf(LogWARN, "%d: Invalid bits number\n",
+ l->ccp.cfg.mppe.keybits);
+ l->ccp.cfg.mppe.keybits = 40;
+ }
+ } else {
+ err = "No bits number pecified\n";
+ log_Printf(LogWARN, err);
+ }
+ break;
+#endif
+
case VAR_DEVICE:
physical_SetDeviceList(cx->physical, arg->argc - arg->argn,
arg->argv + arg->argn);
@@ -1968,6 +1989,11 @@ static struct cmdtab const SetCommands[] = {
{"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
"deflate window sizes", "set deflate out-winsize in-winsize",
(const void *) VAR_WINSIZE},
+#ifdef HAVE_DES
+ {"mppe", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
+ "MPPE key size", "set mppe {40|56|128}",
+ (const void *) VAR_KEYBITS},
+#endif
{"device", "line", SetVariable, LOCAL_AUTH | LOCAL_CX,
"physical device name", "set device|line device-name[,device-name]",
(const void *) VAR_DEVICE},
@@ -1994,7 +2020,7 @@ static struct cmdtab const SetCommands[] = {
{"lcpretry", "lcpretries", SetVariable, LOCAL_AUTH | LOCAL_CX, "LCP retries",
"set lcpretry value [attempts]", (const void *)VAR_LCPRETRY},
{"log", NULL, log_SetLevel, LOCAL_AUTH, "log level",
- "set log [local] [+|-]async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|"
+ "set log [local] [+|-]all|async|cbcp|ccp|chat|command|connect|debug|dns|hdlc|"
"id0|ipcp|lcp|lqm|phase|physical|sync|tcp/ip|timer|tun..."},
{"login", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
"login script", "set login chat-script", (const void *) VAR_LOGIN},
@@ -2414,6 +2440,14 @@ NegotiateSet(struct cmdargs const *arg)
cx->physical->link.lcp.cfg.chap80lm &= keep;
cx->physical->link.lcp.cfg.chap80lm |= add;
break;
+ case NEG_CHAP81:
+ cx->physical->link.lcp.cfg.chap81 &= keep;
+ cx->physical->link.lcp.cfg.chap81 |= add;
+ break;
+ case NEG_MPPE:
+ l->ccp.cfg.neg[CCP_NEG_MPPE] &= keep;
+ l->ccp.cfg.neg[CCP_NEG_MPPE] |= add;
+ break;
#endif
case NEG_DEFLATE:
l->ccp.cfg.neg[CCP_NEG_DEFLATE] &= keep;
@@ -2517,6 +2551,12 @@ static struct cmdtab const NegotiateCommands[] = {
{"LANMan", "chap80lm", NegotiateSet, LOCAL_AUTH | LOCAL_CX,
"Microsoft (NT) CHAP", "accept|deny|disable|enable",
(const void *)NEG_CHAP80LM},
+ {"mschapv2", "chap81", NegotiateSet, LOCAL_AUTH | LOCAL_CX,
+ "Microsoft CHAP v2", "accept|deny|disable|enable",
+ (const void *)NEG_CHAP81},
+ {"mppe", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX_OPT,
+ "MPPE encryption", "accept|deny|disable|enable",
+ (const void *)NEG_MPPE},
#endif
{"deflate", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX_OPT,
"Deflate compression", "accept|deny|disable|enable",
diff --git a/usr.sbin/ppp/ppp/datalink.c b/usr.sbin/ppp/ppp/datalink.c
index f69314cab05..24f70ff0e85 100644
--- a/usr.sbin/ppp/ppp/datalink.c
+++ b/usr.sbin/ppp/ppp/datalink.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: datalink.c,v 1.32 2000/07/19 11:06:32 brian Exp $
+ * $OpenBSD: datalink.c,v 1.33 2000/11/02 00:54:33 brian Exp $
*/
#include <sys/param.h>
@@ -474,7 +474,8 @@ datalink_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
}
static int
-datalink_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
+datalink_Write(struct fdescriptor *d, struct bundle *bundle,
+ const fd_set *fdset)
{
struct datalink *dl = descriptor2datalink(d);
int result = 0;
diff --git a/usr.sbin/ppp/ppp/defs.c b/usr.sbin/ppp/ppp/defs.c
index 2b133bed934..693b405ec32 100644
--- a/usr.sbin/ppp/ppp/defs.c
+++ b/usr.sbin/ppp/ppp/defs.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: defs.c,v 1.18 2000/10/09 21:18:56 brian Exp $
+ * $OpenBSD: defs.c,v 1.19 2000/11/02 00:54:33 brian Exp $
*/
@@ -301,7 +301,7 @@ MakeArgs(char *script, char **pvect, int maxargs, int flags)
nargs = 0;
while (*script) {
script += strspn(script, " \t");
- if (*script == '#' && flags & PARSE_NOHASH) {
+ if (*script == '#' && !(flags & PARSE_NOHASH)) {
*script = '\0';
break;
}
diff --git a/usr.sbin/ppp/ppp/defs.h b/usr.sbin/ppp/ppp/defs.h
index e88a413b5e0..39bf72c24bc 100644
--- a/usr.sbin/ppp/ppp/defs.h
+++ b/usr.sbin/ppp/ppp/defs.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: defs.h,v 1.18 2000/10/09 21:18:56 brian Exp $
+ * $OpenBSD: defs.h,v 1.19 2000/11/02 00:54:33 brian Exp $
*
* TODO:
*/
@@ -49,6 +49,7 @@
#define AUTHLEN 100 /* Size of authname/authkey */
#define CHAPDIGESTLEN 100 /* Maximum chap digest */
#define CHAPCHALLENGELEN 48 /* Maximum chap challenge */
+#define CHAPAUTHRESPONSELEN 48 /* Maximum chap authresponse (chap81) */
#define MAXARGS 40 /* How many args per config line */
#define NCP_IDLE_TIMEOUT 180 /* Drop all links */
#define CHOKED_TIMEOUT 120 /* Delete queued packets w/ blocked tun */
diff --git a/usr.sbin/ppp/ppp/ether.c b/usr.sbin/ppp/ppp/ether.c
index 7b7ee433111..ee0e421ef38 100644
--- a/usr.sbin/ppp/ppp/ether.c
+++ b/usr.sbin/ppp/ppp/ether.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: ether.c,v 1.5 2000/10/09 21:18:56 brian Exp $
+ * $OpenBSD: ether.c,v 1.6 2000/11/02 00:54:33 brian Exp $
*/
#include <sys/param.h>
@@ -584,11 +584,10 @@ ether_Create(struct physical *p)
/* And finally, request a connection to the given provider */
- data = (struct ngpppoe_init_data *)alloca(sizeof *data + providerlen + 1);
+ data = (struct ngpppoe_init_data *)alloca(sizeof *data + providerlen);
snprintf(data->hook, sizeof data->hook, "%s", dev->hook);
strcpy(data->data, provider);
- data->data_len = providerlen;
snprintf(connectpath, sizeof connectpath, ".:%s", dev->hook);
log_Printf(LogDEBUG, "Sending PPPOE_CONNECT to %s\n", connectpath);
diff --git a/usr.sbin/ppp/ppp/filter.c b/usr.sbin/ppp/ppp/filter.c
index 5c2fe6dd241..dbb4d0b0f84 100644
--- a/usr.sbin/ppp/ppp/filter.c
+++ b/usr.sbin/ppp/ppp/filter.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: filter.c,v 1.16 2000/07/11 22:13:03 brian Exp $
+ * $OpenBSD: filter.c,v 1.17 2000/11/02 00:54:33 brian Exp $
*
* TODO: Should send ICMP error message when we discard packets.
*/
@@ -502,9 +502,11 @@ Parse(struct ipcp *ipcp, int argc, char const *const *argv,
}
log_Printf(LogDEBUG, "Parse: Src: %s\n", inet_ntoa(filterdata.f_src.ipaddr));
- log_Printf(LogDEBUG, "Parse: Src mask: %s\n", inet_ntoa(filterdata.f_src.mask));
+ log_Printf(LogDEBUG, "Parse: Src mask: %s\n",
+ inet_ntoa(filterdata.f_src.mask));
log_Printf(LogDEBUG, "Parse: Dst: %s\n", inet_ntoa(filterdata.f_dst.ipaddr));
- log_Printf(LogDEBUG, "Parse: Dst mask: %s\n", inet_ntoa(filterdata.f_dst.mask));
+ log_Printf(LogDEBUG, "Parse: Dst mask: %s\n",
+ inet_ntoa(filterdata.f_dst.mask));
log_Printf(LogDEBUG, "Parse: Proto = %d\n", proto);
log_Printf(LogDEBUG, "Parse: src: %s (%d)\n",
diff --git a/usr.sbin/ppp/ppp/lcp.c b/usr.sbin/ppp/ppp/lcp.c
index abee7f34121..76a75cdd02f 100644
--- a/usr.sbin/ppp/ppp/lcp.c
+++ b/usr.sbin/ppp/ppp/lcp.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: lcp.c,v 1.21 2000/07/19 11:06:34 brian Exp $
+ * $OpenBSD: lcp.c,v 1.22 2000/11/02 00:54:34 brian Exp $
*
*/
@@ -193,6 +193,8 @@ lcp_ReportStatus(struct cmdargs const *arg)
command_ShowNegval(lcp->cfg.chap80nt));
prompt_Printf(arg->prompt, " LANMan = %s\n",
command_ShowNegval(lcp->cfg.chap80lm));
+ prompt_Printf(arg->prompt, " CHAP81 = %s\n",
+ command_ShowNegval(lcp->cfg.chap81));
#endif
prompt_Printf(arg->prompt, " LQR = %s\n",
command_ShowNegval(lcp->cfg.lqr));
@@ -244,6 +246,7 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
#ifdef HAVE_DES
lcp->cfg.chap80nt = NEG_ACCEPTED;
lcp->cfg.chap80lm = NEG_ACCEPTED;
+ lcp->cfg.chap81 = 0;
#endif
lcp->cfg.lqr = NEG_ACCEPTED;
lcp->cfg.pap = NEG_ACCEPTED;
@@ -292,6 +295,9 @@ lcp_Setup(struct lcp *lcp, int openmode)
IsEnabled(lcp->cfg.chap80lm)) {
lcp->want_auth = PROTO_CHAP;
lcp->want_authtype = 0x80;
+ } else if (IsEnabled(lcp->cfg.chap81)) {
+ lcp->want_auth = PROTO_CHAP;
+ lcp->want_authtype = 0x81;
#endif
} else if (IsEnabled(lcp->cfg.pap)) {
lcp->want_auth = PROTO_PAP;
@@ -302,7 +308,8 @@ lcp_Setup(struct lcp *lcp, int openmode)
}
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
lcp->want_callback.opmask = 0;
lcp->want_lqrperiod = IsEnabled(lcp->cfg.lqr) ?
@@ -733,6 +740,12 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
*dec->nakend++ = (unsigned char) PROTO_CHAP;
*dec->nakend++ = 0x80;
+ } else if (IsAccepted(lcp->cfg.chap81)) {
+ *dec->nakend++ = *cp;
+ *dec->nakend++ = 5;
+ *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
+ *dec->nakend++ = (unsigned char) PROTO_CHAP;
+ *dec->nakend++ = 0x81;
#endif
} else
goto reqreject;
@@ -747,6 +760,7 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
#ifdef HAVE_DES
|| (cp[4] == 0x80 && (IsAccepted(lcp->cfg.chap80nt) ||
(IsAccepted(lcp->cfg.chap80lm))))
+ || (cp[4] == 0x81 && IsAccepted(lcp->cfg.chap81))
#endif
) {
lcp->his_auth = proto;
@@ -755,9 +769,11 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
dec->ackend += length;
} else {
#ifndef HAVE_DES
- if (cp[4] == 0x80)
+ if (cp[4] == 0x80) {
log_Printf(LogWARN, "CHAP 0x80 not available without DES\n");
- else
+ } else if (cp[4] == 0x81) {
+ log_Printf(LogWARN, "CHAP 0x81 not available without DES\n");
+ } else
#endif
if (cp[4] != 0x05)
log_Printf(LogWARN, "%s not supported\n",
@@ -777,6 +793,12 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
*dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
*dec->nakend++ = (unsigned char) PROTO_CHAP;
*dec->nakend++ = 0x80;
+ } else if (IsAccepted(lcp->cfg.chap81)) {
+ *dec->nakend++ = *cp;
+ *dec->nakend++ = 5;
+ *dec->nakend++ = (unsigned char) (PROTO_CHAP >> 8);
+ *dec->nakend++ = (unsigned char) PROTO_CHAP;
+ *dec->nakend++ = 0x81;
#endif
} else if (IsAccepted(lcp->cfg.pap)) {
*dec->nakend++ = *cp;
@@ -816,18 +838,24 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
IsEnabled(lcp->cfg.chap80lm))) {
lcp->want_auth = PROTO_CHAP;
lcp->want_authtype = 0x80;
+ } else if (cp[4] == 0x81 && IsEnabled(lcp->cfg.chap81)) {
+ lcp->want_auth = PROTO_CHAP;
+ lcp->want_authtype = 0x81;
#endif
} else {
#ifndef HAVE_DES
- if (cp[4] == 0x80)
+ if (cp[4] == 0x80) {
log_Printf(LogLCP, "Peer will only send MSCHAP (not available"
" without DES)\n");
- else
+ } else if (cp[4] == 0x81) {
+ log_Printf(LogLCP, "Peer will only send MSCHAPV2 (not available"
+ " without DES)\n");
+ } else
#endif
log_Printf(LogLCP, "Peer will only send %s (not %s)\n",
Auth2Nam(PROTO_CHAP, cp[4]),
#ifdef HAVE_DES
- cp[4] == 0x80 ? "configured" :
+ (cp[4] == 0x80 || cp[4] == 0x81) ? "configured" :
#endif
"supported");
lcp->his_reject |= (1 << type);
diff --git a/usr.sbin/ppp/ppp/lcp.h b/usr.sbin/ppp/ppp/lcp.h
index b3b2eac9a50..b73f3f18c1c 100644
--- a/usr.sbin/ppp/ppp/lcp.h
+++ b/usr.sbin/ppp/ppp/lcp.h
@@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: lcp.h,v 1.7 2000/07/19 11:06:35 brian Exp $
+ * $OpenBSD: lcp.h,v 1.8 2000/11/02 00:54:34 brian Exp $
*
* TODO:
*/
@@ -83,6 +83,7 @@ struct lcp {
#ifdef HAVE_DES
unsigned chap80nt : 2; /* Microsoft (NT) CHAP */
unsigned chap80lm : 2; /* Microsoft (LANMan) CHAP */
+ unsigned chap81 : 2; /* Microsoft CHAP v2 */
#endif
unsigned lqr : 2; /* Link Quality Report */
unsigned pap : 2; /* Password Authentication protocol */
diff --git a/usr.sbin/ppp/ppp/log.c b/usr.sbin/ppp/ppp/log.c
index 6b3c75e9669..ae8b100bac1 100644
--- a/usr.sbin/ppp/ppp/log.c
+++ b/usr.sbin/ppp/ppp/log.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: log.c,v 1.11 2000/08/28 23:25:28 brian Exp $
+ * $OpenBSD: log.c,v 1.12 2000/11/02 00:54:34 brian Exp $
*/
#include <sys/types.h>
@@ -435,7 +435,8 @@ log_SetLevel(struct cmdargs const *arg)
local = 0;
else {
if (arg->prompt == NULL) {
- log_Printf(LogWARN, "set log local: Only available on the command line\n");
+ log_Printf(LogWARN, "set log local: Only available on the"
+ " command line\n");
return 1;
}
argc--;
@@ -452,6 +453,24 @@ log_SetLevel(struct cmdargs const *arg)
while (argc--) {
argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
+ /* Special case 'all' */
+ if (strcasecmp(argp, "all") == 0) {
+ if (**argv == '-') {
+ if (local)
+ for (i = LogMIN; i <= LogMAX; i++)
+ log_DiscardLocal(i, &arg->prompt->logmask);
+ else
+ for (i = LogMIN; i <= LogMAX; i++)
+ log_Discard(i);
+ } else if (local)
+ for (i = LogMIN; i <= LogMAX; i++)
+ log_KeepLocal(i, &arg->prompt->logmask);
+ else
+ for (i = LogMIN; i <= LogMAX; i++)
+ log_Keep(i);
+ argv++;
+ continue;
+ }
for (i = LogMIN; i <= LogMAX; i++)
if (strcasecmp(argp, log_Name(i)) == 0) {
if (**argv == '-') {
diff --git a/usr.sbin/ppp/ppp/main.c b/usr.sbin/ppp/ppp/main.c
index b68a10dd364..e963d5b2821 100644
--- a/usr.sbin/ppp/ppp/main.c
+++ b/usr.sbin/ppp/ppp/main.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: main.c,v 1.22 2000/10/09 21:18:57 brian Exp $
+ * $OpenBSD: main.c,v 1.23 2000/11/02 00:54:34 brian Exp $
*
* TODO:
*/
@@ -168,8 +168,8 @@ BringDownServer(int signo)
static void
Usage(void)
{
- fprintf(stderr,
- "Usage: ppp [-auto | -foreground | -background | -direct | -dedicated | -ddial | -interactive]"
+ fprintf(stderr, "Usage: ppp [-auto | -foreground | -background | -direct |"
+ " -dedicated | -ddial | -interactive]"
#ifndef NOALIAS
" [-nat]"
#endif
diff --git a/usr.sbin/ppp/ppp/mbuf.c b/usr.sbin/ppp/ppp/mbuf.c
index 54c91c51425..20784a99447 100644
--- a/usr.sbin/ppp/ppp/mbuf.c
+++ b/usr.sbin/ppp/ppp/mbuf.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $OpenBSD: mbuf.c,v 1.12 2000/05/07 10:12:14 brian Exp $
+ * $OpenBSD: mbuf.c,v 1.13 2000/11/02 00:54:34 brian Exp $
*
*/
#include <sys/types.h>
@@ -75,6 +75,22 @@ m_length(struct mbuf *bp)
return len;
}
+static const char *
+mbuftype(int type)
+{
+ static const char * const mbufdesc[MB_MAX] = {
+ "ip in", "ip out", "nat in", "nat out", "mp in", "mp out",
+ "vj in", "vj out", "icompd in", "icompd out", "compd in", "compd out",
+ "lqr in", "lqr out", "echo in", "echo out", "proto in", "proto out",
+ "acf in", "acf out", "sync in", "sync out", "hdlc in", "hdlc out",
+ "async in", "async out", "cbcp in", "cbcp out", "chap in", "chap out",
+ "pap in", "pap out", "ccp in", "ccp out", "ipcp in", "ipcp out",
+ "lcp in", "lcp out"
+ };
+
+ return type < 0 || type >= MB_MAX ? "unknown" : mbufdesc[type];
+}
+
struct mbuf *
m_get(size_t m_len, int type)
{
@@ -88,7 +104,8 @@ m_get(size_t m_len, int type)
}
if (m_len > M_MAXLEN || m_len == 0) {
- log_Printf(LogERROR, "Request for mbuf size %lu denied\n", (u_long)m_len);
+ log_Printf(LogERROR, "Request for mbuf size %lu (\"%s\") denied !\n",
+ (u_long)m_len, mbuftype(type));
AbortProgram(EX_OSERR);
}
@@ -293,27 +310,18 @@ int
mbuf_Show(struct cmdargs const *arg)
{
int i;
- static const char * const mbuftype[] = {
- "ip in", "ip out", "nat in", "nat out", "mp in", "mp out",
- "vj in", "vj out", "icompd in", "icompd out", "compd in", "compd out",
- "lqr in", "lqr out", "echo in", "echo out", "proto in", "proto out",
- "acf in", "acf out", "sync in", "sync out", "hdlc in", "hdlc out",
- "async in", "async out", "cbcp in", "cbcp out", "chap in", "chap out",
- "pap in", "pap out", "ccp in", "ccp out", "ipcp in", "ipcp out",
- "lcp in", "lcp out", "unknown"
- };
prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
for (i = 0; i < MB_MAX; i += 2)
prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\t"
"%10.10s: %04lu (%06lu)\n",
- mbuftype[i], (u_long)MemMap[i].fragments,
- (u_long)MemMap[i].octets, mbuftype[i+1],
+ mbuftype(i), (u_long)MemMap[i].fragments,
+ (u_long)MemMap[i].octets, mbuftype(i+1),
(u_long)MemMap[i+1].fragments, (u_long)MemMap[i+1].octets);
if (i == MB_MAX)
prompt_Printf(arg->prompt, "%10.10s: %04lu (%06lu)\n",
- mbuftype[i], (u_long)MemMap[i].fragments,
+ mbuftype(i), (u_long)MemMap[i].fragments,
(u_long)MemMap[i].octets);
prompt_Printf(arg->prompt, "Mallocs: %llu, Frees: %llu\n",
diff --git a/usr.sbin/ppp/ppp/mp.c b/usr.sbin/ppp/ppp/mp.c
index 7275cefd464..bec0c0b399a 100644
--- a/usr.sbin/ppp/ppp/mp.c
+++ b/usr.sbin/ppp/ppp/mp.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: mp.c,v 1.20 2000/08/17 14:14:55 brian Exp $
+ * $OpenBSD: mp.c,v 1.21 2000/11/02 00:54:34 brian Exp $
*/
#include <sys/param.h>
@@ -1076,7 +1076,8 @@ mpserver_Read(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
}
static int
-mpserver_Write(struct fdescriptor *d, struct bundle *bundle, const fd_set *fdset)
+mpserver_Write(struct fdescriptor *d, struct bundle *bundle,
+ const fd_set *fdset)
{
/* We never want to write here ! */
log_Printf(LogALERT, "mpserver_Write: Internal error: Bad call !\n");
diff --git a/usr.sbin/ppp/ppp/mppe.c b/usr.sbin/ppp/ppp/mppe.c
new file mode 100644
index 00000000000..275c6057edf
--- /dev/null
+++ b/usr.sbin/ppp/ppp/mppe.c
@@ -0,0 +1,430 @@
+/*-
+ * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: mppe.c,v 1.1 2000/11/02 00:54:34 brian Exp $
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#ifdef __FreeBSD__
+#include <sha.h>
+#else
+#include <openssl/sha.h>
+#endif
+#include <openssl/rc4.h>
+
+#include "defs.h"
+#include "mbuf.h"
+#include "log.h"
+#include "timer.h"
+#include "fsm.h"
+#include "lqr.h"
+#include "hdlc.h"
+#include "lcp.h"
+#include "ccp.h"
+#include "chap_ms.h"
+#include "mppe.h"
+
+/*
+ * Documentation:
+ *
+ * draft-ietf-pppext-mppe-04.txt
+ * draft-ietf-pppext-mppe-keys-02.txt
+ */
+
+struct mppe_state {
+ int cohnum;
+ int keylen; /* 8 or 16 bytes */
+ int keybits; /* 40, 56 or 128 bits */
+ char sesskey[MPPE_KEY_LEN];
+ char mastkey[MPPE_KEY_LEN];
+ RC4_KEY rc4key;
+};
+
+int MPPE_MasterKeyValid = 0;
+char MPPE_MasterKey[MPPE_KEY_LEN];
+
+static void
+MPPEResetOutput(void *v)
+{
+ log_Printf(LogCCP, "MPPE: Output channel reset\n");
+}
+
+static void
+MPPEReduceSessionKey(struct mppe_state *mp)
+{
+ switch(mp->keybits) {
+ case 40:
+ mp->sesskey[2] = 0x9e;
+ mp->sesskey[1] = 0x26;
+ case 56:
+ mp->sesskey[0] = 0xd1;
+ case 128:
+ }
+}
+
+static void
+MPPEKeyChange(struct mppe_state *mp)
+{
+ char InterimKey[MPPE_KEY_LEN];
+ RC4_KEY RC4Key;
+
+ GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey);
+ RC4_set_key(&RC4Key, mp->keylen, InterimKey);
+ RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey);
+
+ MPPEReduceSessionKey(mp);
+}
+
+static struct mbuf *
+MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto,
+ struct mbuf *mp)
+{
+ struct mppe_state *mop = (struct mppe_state *)v;
+ struct mbuf *mo;
+ u_short nproto;
+ int ilen;
+ char *rp;
+
+ log_Printf(LogCCP, "MPPE: Output\n");
+
+ ilen = m_length(mp);
+
+ log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen);
+ if (*proto < 0x21 && *proto > 0xFA) {
+ log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n");
+ return mp;
+ }
+
+ log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp);
+
+ /* Get mbuf for prefixes */
+ mo = m_get(4, MB_CCPOUT);
+ mo->m_next = mp;
+
+ /* Init RC4 keys */
+ RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
+
+ /* Set MPPE packet prefix */
+ rp = MBUF_CTOP(mo);
+ *(u_short *)rp = htons(0x9000 | mop->cohnum);
+
+ /* Save encrypted protocol number */
+ nproto = htons(*proto);
+ RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2);
+
+ /* Encrypt main packet */
+ rp = MBUF_CTOP(mp);
+ RC4(&mop->rc4key, ilen, rp, rp);
+
+ /* Rotate keys */
+ MPPEKeyChange(mop);
+ mop->cohnum ++; mop->cohnum &= 0xFFF;
+
+ /* Chage protocol number */
+ *proto = ccp_Proto(ccp);
+
+ log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n",
+ *proto, m_length(mo));
+
+ return mo;
+}
+
+static void
+MPPEResetInput(void *v)
+{
+ log_Printf(LogCCP, "MPPE: Input channel reset\n");
+}
+
+static struct mbuf *
+MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
+{
+ struct mppe_state *mip = (struct mppe_state *)v;
+ u_short prefix;
+ char *rp;
+ int ilen;
+
+ log_Printf(LogCCP, "MPPE: Input\n");
+
+ ilen = m_length(mp);
+
+ log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen);
+
+ log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp);
+
+ mp = mbuf_Read(mp, &prefix, 2);
+ prefix = ntohs(prefix);
+ if ((prefix & 0xF000) != 0x9000) {
+ log_Printf(LogERROR, "MPPE: Input: Invalid packet\n");
+ m_freem(mp);
+ return NULL;
+ }
+
+ prefix &= 0xFFF;
+ while (prefix != mip->cohnum) {
+ MPPEKeyChange(mip);
+ mip->cohnum ++; mip->cohnum &= 0xFFF;
+ }
+
+ RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
+
+ mp = mbuf_Read(mp, proto, 2);
+ RC4(&mip->rc4key, 2, (char *)proto, (char *)proto);
+ *proto = ntohs(*proto);
+
+ rp = MBUF_CTOP(mp);
+ RC4(&mip->rc4key, m_length(mp), rp, rp);
+
+ log_Printf(LogDEBUG, "MPPE: Input: Decrypted: Proto %02x (%d bytes)\n",
+ *proto, m_length(mp));
+
+ log_DumpBp(LogDEBUG, "MPPE: Input: Decrypted: Packet:", mp);
+
+ return mp;
+}
+
+static void
+MPPEDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi)
+{
+ log_Printf(LogCCP, "MPPE: DictSetup\n");
+}
+
+static const char *
+MPPEDispOpts(struct lcp_opt *o)
+{
+ static char buf[32];
+ sprintf(buf, "value 0x%08x", (int)ntohl(*(u_int32_t *)(o->data)));
+ return buf;
+}
+
+static void
+MPPEInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
+{
+ u_long val;
+
+ o->len = 6;
+
+ log_Printf(LogCCP, "MPPE: InitOptsOutput\n");
+
+ if (!MPPE_MasterKeyValid) {
+ log_Printf(LogWARN, "MPPE: MasterKey is invalid,"
+ " MPPE is capable only with CHAP81 authentication\n");
+ *(u_int32_t *)o->data = htonl(0x0);
+ return;
+ }
+
+ val = 0x1000000;
+ switch(cfg->mppe.keybits) {
+ case 128:
+ val |= 0x40; break;
+ case 56:
+ val |= 0x80; break;
+ case 40:
+ val |= 0x20; break;
+ }
+ *(u_int32_t *)o->data = htonl(val);
+}
+
+static int
+MPPESetOptsOutput(struct lcp_opt *o)
+{
+ u_long *p = (u_long *)(o->data);
+ u_long val = ntohl(*p);
+
+ log_Printf(LogCCP, "MPPE: SetOptsOutput\n");
+
+ if (!MPPE_MasterKeyValid) {
+ if (*p != 0x0) {
+ *p = 0x0;
+ return MODE_NAK;
+ } else {
+ return MODE_ACK;
+ }
+ }
+
+ if (val == 0x01000020 ||
+ val == 0x01000040 ||
+ val == 0x01000080)
+ return MODE_ACK;
+
+ return MODE_NAK;
+}
+
+static int
+MPPESetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
+{
+ u_long *p = (u_long *)(o->data);
+ u_long val = ntohl(*p);
+ u_long mval;
+
+ log_Printf(LogCCP, "MPPE: SetOptsInput\n");
+
+ if (!MPPE_MasterKeyValid) {
+ if (*p != 0x0) {
+ *p = 0x0;
+ return MODE_NAK;
+ } else {
+ return MODE_ACK;
+ }
+ }
+
+ mval = 0x01000000;
+ switch(cfg->mppe.keybits) {
+ case 128:
+ mval |= 0x40; break;
+ case 56:
+ mval |= 0x80; break;
+ case 40:
+ mval |= 0x20; break;
+ }
+
+ if (val == mval)
+ return MODE_ACK;
+
+ *p = htonl(mval);
+
+ return MODE_NAK;
+}
+
+static void *
+MPPEInitInput(struct lcp_opt *o)
+{
+ struct mppe_state *mip;
+ u_int32_t val = ntohl(*(unsigned long *)o->data);
+
+ log_Printf(LogCCP, "MPPE: InitInput\n");
+
+ if (!MPPE_MasterKeyValid) {
+ log_Printf(LogERROR, "MPPE: InitInput: MasterKey is invalid!!!!\n");
+ return NULL;
+ }
+
+ mip = malloc(sizeof(*mip));
+ memset(mip, 0, sizeof(*mip));
+
+ if (val & 0x20) { /* 40-bits */
+ mip->keylen = 8;
+ mip->keybits = 40;
+ } else if (val & 0x80) { /* 56-bits */
+ mip->keylen = 8;
+ mip->keybits = 56;
+ } else { /* 128-bits */
+ mip->keylen = 16;
+ mip->keybits = 128;
+ }
+
+ log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits);
+
+ GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0, 0);
+ GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey);
+
+ MPPEReduceSessionKey(mip);
+
+ MPPEKeyChange(mip);
+
+ mip->cohnum = 0;
+
+ return mip;
+}
+
+static void *
+MPPEInitOutput(struct lcp_opt *o)
+{
+ struct mppe_state *mop;
+ u_int32_t val = ntohl(*(unsigned long *)o->data);
+
+ log_Printf(LogCCP, "MPPE: InitOutput\n");
+
+ if (!MPPE_MasterKeyValid) {
+ log_Printf(LogERROR, "MPPE: InitOutput: MasterKey is invalid!!!!\n");
+ return NULL;
+ }
+
+ mop = malloc(sizeof(*mop));
+ memset(mop, 0, sizeof(*mop));
+
+ if (val & 0x20) { /* 40-bits */
+ mop->keylen = 8;
+ mop->keybits = 40;
+ } else if (val & 0x80) { /* 56-bits */
+ mop->keylen = 8;
+ mop->keybits = 56;
+ } else { /* 128-bits */
+ mop->keylen = 16;
+ mop->keybits = 128;
+ }
+
+ log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits);
+
+ GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1, 0);
+ GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey);
+
+ MPPEReduceSessionKey(mop);
+
+ MPPEKeyChange(mop);
+
+ mop->cohnum = 0;
+
+ return mop;
+}
+
+static void
+MPPETermInput(void *v)
+{
+ log_Printf(LogCCP, "MPPE: TermInput\n");
+ free(v);
+}
+
+static void
+MPPETermOutput(void *v)
+{
+ log_Printf(LogCCP, "MPPE: TermOutput\n");
+ free(v);
+}
+
+const struct ccp_algorithm MPPEAlgorithm = {
+ TY_MPPE,
+ CCP_NEG_MPPE,
+ MPPEDispOpts,
+ {
+ MPPESetOptsInput,
+ MPPEInitInput,
+ MPPETermInput,
+ MPPEResetInput,
+ MPPEInput,
+ MPPEDictSetup
+ },
+ {
+ MPPEInitOptsOutput,
+ MPPESetOptsOutput,
+ MPPEInitOutput,
+ MPPETermOutput,
+ MPPEResetOutput,
+ MPPEOutput
+ },
+};
diff --git a/usr.sbin/ppp/ppp/mppe.h b/usr.sbin/ppp/ppp/mppe.h
new file mode 100644
index 00000000000..499da5e0059
--- /dev/null
+++ b/usr.sbin/ppp/ppp/mppe.h
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $OpenBSD: mppe.h,v 1.1 2000/11/02 00:54:34 brian Exp $
+ */
+
+#define MPPE_KEY_LEN 16
+extern const struct ccp_algorithm MPPEAlgorithm;
+extern int MPPE_MasterKeyValid;
+extern char MPPE_MasterKey[];
diff --git a/usr.sbin/ppp/ppp/nat_cmd.c b/usr.sbin/ppp/ppp/nat_cmd.c
index 0d7a797cf67..1e9a06401fc 100644
--- a/usr.sbin/ppp/ppp/nat_cmd.c
+++ b/usr.sbin/ppp/ppp/nat_cmd.c
@@ -2,7 +2,7 @@
* The code in this file was written by Eivind Eklund <perhaps@yes.no>,
* who places it in the public domain without restriction.
*
- * $OpenBSD: nat_cmd.c,v 1.14 2000/07/11 22:13:03 brian Exp $
+ * $OpenBSD: nat_cmd.c,v 1.15 2000/11/02 00:54:34 brian Exp $
*/
#include <sys/param.h>
@@ -421,7 +421,11 @@ nat_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
break;
case PKT_ALIAS_IGNORED:
- if (log_IsKept(LogTCPIP)) {
+ if (PacketAliasSetMode(0, 0) & PKT_ALIAS_DENY_INCOMING) {
+ log_Printf(LogTCPIP, "NAT engine denied data:\n");
+ m_freem(bp);
+ bp = NULL;
+ } else if (log_IsKept(LogTCPIP)) {
log_Printf(LogTCPIP, "NAT engine ignored data:\n");
PacketCheck(bundle, MBUF_CTOP(bp), bp->m_len, NULL, NULL, NULL);
}
diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8
index 36a2a215732..e1b551651a8 100644
--- a/usr.sbin/ppp/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp/ppp.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ppp.8,v 1.95 2000/09/02 22:12:54 brian Exp $
+.\" $OpenBSD: ppp.8,v 1.96 2000/11/02 00:54:34 brian Exp $
.Dd 20 September 1995
.nr XX \w'\fC00'
.Dt PPP 8
@@ -243,7 +243,7 @@ In direct mode,
acts as server which accepts incoming
.Em PPP
connections on stdin/stdout.
-.It Supports PAP and CHAP (rfc 1994) authentication.
+.It Supports PAP and CHAP (rfc 1994, 2433 and 2759) authentication.
With PAP or CHAP, it is possible to skip the Unix style
.Xr login 1
procedure, and use the
@@ -353,6 +353,14 @@ It is possible to configure
.Nm
to open more than one physical connection to the peer, combining the
bandwidth of all links for better throughput.
+.It Supports MPPE (draft-ietf-pppext-mppe)
+MPPE is Microsoft Point to Point Encryption scheme. It is possible to configure
+.Nm
+to participate in Microsoft's Windows VPN. For now,
+.Nm
+can only get encryption keys from CHAP 81 authentication.
+.Nm
+must be compiled with DES for MPPE to operate.
.El
.Sh PERMISSIONS
.Nm
@@ -2143,6 +2151,11 @@ is able to generate the following log info either via
or directly to the screen:
.Pp
.Bl -tag -width XXXXXXXXX -offset XXX -compact
+.It Li All
+Enable all logging facilities.
+This generates a lot of log.
+The most common use of 'all' is as a basis, where you remove some facilities
+after enabling 'all' ('debug' and 'timer' are usually best disabled.)
.It Li Async
Dump async level packet in hex.
.It Li CBCP
@@ -2654,8 +2667,20 @@ level, and any appropriate
.Dq reconnect
values are honoured as if the peer were responsible for dropping the
connection.
+.It mppe
+Default: Disabled and Denied.
+This is Microsoft Point to Point Encryption scheme. MPPE key size can be
+40-, 56- and 128-bits. Refer to
+.Dq set mppe
+command.
+.It MSChapV2|chap81
+Default: Disabled and Denied.
+It is very similar to standard CHAP (type 0x05)
+except that it issues challenges of a fixed 16 bytes in length and uses a
+combination of MD4, SHA-1 and DES to encrypt the challenge rather than using the
+standard MD5 mechanism.
.It MSChap|chap80nt
-Default: Disabled and Accepted.
+Default: Disabled and Denied.
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
@@ -3143,6 +3168,9 @@ you wish to map to specific machines behind your gateway.
.It nat deny_incoming yes|no
If set to yes, this command will refuse all incoming connections
by dropping the packets in much the same way as a firewall would.
+.Pp
+It should be noted that enabling this option also drops IP packets
+that cannot be identified by libalias. This will be fixed in the future.
.It nat help|?
This command gives a summary of available nat commands.
.It nat log yes|no
@@ -4738,6 +4766,8 @@ This will allow
to do the necessary address translations to enable the process that
triggers the connection to connect once the link is up despite the
peer assigning us a new (dynamic) IP address.
+.It set mppe {40|56|128}
+This option selects particular key length. Default is 128.
.It set mrru Op Ar value
Setting this option enables Multi-link PPP negotiations, also known as
Multi-link Protocol or MP.
diff --git a/usr.sbin/ppp/ppp/radius.c b/usr.sbin/ppp/ppp/radius.c
index 32712f8c6e8..6a404ac27f8 100644
--- a/usr.sbin/ppp/ppp/radius.c
+++ b/usr.sbin/ppp/ppp/radius.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: radius.c,v 1.8 2000/08/28 22:44:41 brian Exp $
+ * $OpenBSD: radius.c,v 1.9 2000/11/02 00:54:34 brian Exp $
*
*/
@@ -496,7 +496,7 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl,
radius_Destroy(r);
- if ((r->cx.rad = rad_auth_open()) == NULL) {
+ if ((r->cx.rad = rad_acct_open()) == NULL) {
log_Printf(LogERROR, "rad_auth_open: %s\n", strerror(errno));
return;
}
diff --git a/usr.sbin/ppp/ppp/server.c b/usr.sbin/ppp/ppp/server.c
index 99075bcc65a..e262abbaef4 100644
--- a/usr.sbin/ppp/ppp/server.c
+++ b/usr.sbin/ppp/ppp/server.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: server.c,v 1.7 2000/06/13 09:57:51 brian Exp $
+ * $OpenBSD: server.c,v 1.8 2000/11/02 00:54:35 brian Exp $
*/
#include <sys/types.h>
@@ -218,7 +218,8 @@ server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask)
if (mask != (mode_t)-1)
umask(mask);
if (listen(s, 5) != 0) {
- log_Printf(LogERROR, "Local: Unable to listen to socket - BUNDLE overload?\n");
+ log_Printf(LogERROR, "Local: Unable to listen to socket -"
+ " BUNDLE overload?\n");
close(s);
ID0unlink(name);
return 5;
diff --git a/usr.sbin/ppp/ppp/tty.c b/usr.sbin/ppp/ppp/tty.c
index 078ca7990b5..f843a5c5fee 100644
--- a/usr.sbin/ppp/ppp/tty.c
+++ b/usr.sbin/ppp/ppp/tty.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: tty.c,v 1.14 2000/02/27 01:38:29 brian Exp $
+ * $OpenBSD: tty.c,v 1.15 2000/11/02 00:54:35 brian Exp $
*/
#include <sys/param.h>
@@ -216,7 +216,9 @@ tty_Raw(struct physical *p)
if (p->type != PHYS_DEDICATED)
ios.c_cflag |= HUPCL;
- tcsetattr(p->fd, TCSANOW, &ios);
+ if (tcsetattr(p->fd, TCSANOW, &ios) == -1)
+ log_Printf(LogWARN, "%s: tcsetattr: Failed configuring device\n",
+ p->link.name);
}
oldflag = fcntl(p->fd, F_GETFL, 0);
@@ -239,11 +241,9 @@ tty_Offline(struct physical *p)
struct termios tio;
tcgetattr(p->fd, &tio);
- if (cfsetspeed(&tio, B0) == -1)
+ if (cfsetspeed(&tio, B0) == -1 || tcsetattr(p->fd, TCSANOW, &tio) == -1)
log_Printf(LogWARN, "%s: Unable to set physical to speed 0\n",
p->link.name);
- else
- tcsetattr(p->fd, TCSANOW, &tio);
}
}
}
@@ -258,8 +258,9 @@ tty_Cooked(struct physical *p)
tcflush(p->fd, TCIOFLUSH);
- if (!physical_IsSync(p))
- tcsetattr(p->fd, TCSAFLUSH, &dev->ios);
+ if (!physical_IsSync(p) && tcsetattr(p->fd, TCSAFLUSH, &dev->ios) == -1)
+ log_Printf(LogWARN, "%s: tcsetattr: Unable to restore device settings\n",
+ p->link.name);
if ((oldflag = fcntl(p->fd, F_GETFL, 0)) != -1)
fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
@@ -436,7 +437,15 @@ tty_Create(struct physical *p)
log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
p->link.name, p->name.full, p->cfg.speed);
}
- tcsetattr(p->fd, TCSADRAIN, &ios);
+
+ if (tcsetattr(p->fd, TCSADRAIN, &ios) == -1) {
+ log_Printf(LogWARN, "%s: tcsetattr: Failed configuring device\n",
+ p->link.name);
+ if (p->type != PHYS_DIRECT && p->cfg.speed > 115200)
+ log_Printf(LogWARN, "%.*s Perhaps the speed is unsupported\n",
+ (int)strlen(p->link.name), "");
+ }
+
log_Printf(LogDEBUG, "%s: physical (put): iflag = %lx, oflag = %lx, "
"cflag = %lx\n", p->link.name, (u_long)ios.c_iflag,
(u_long)ios.c_oflag, (u_long)ios.c_cflag);