diff options
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/arp.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ccp.c | 24 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ccp.h | 13 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap.c | 165 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap.h | 6 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap_ms.c | 286 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap_ms.h | 18 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 46 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/datalink.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/defs.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/defs.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ether.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/filter.c | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/lcp.c | 42 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/lcp.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/log.c | 23 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/main.c | 6 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/mbuf.c | 36 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/mp.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/mppe.c | 430 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/mppe.h | 32 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/nat_cmd.c | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8 | 36 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/radius.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/server.c | 5 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/tty.c | 25 |
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); |