Skip to content

Commit b3f9b92

Browse files
Matt Domschdavem330
authored andcommitted
[PPP]: add PPP MPPE encryption module
From: Matt Domsch <Matt_Domsch@dell.com> The patch below implements the Microsoft Point-to-Point Encryption method as a PPP compressor/decompressor. This is necessary for Linux clients and servers to interoperate with Microsoft Point-to-Point Tunneling Protocol (PPTP) servers (either Microsoft PPTP servers or the poptop project) which use MPPE to encrypt data when creating a VPN. This patch differs from the kernel_ppp_mppe DKMS pacakge at pptpclient.sourceforge.net by utilizing the kernel crypto routines rather than providing its own SHA1 and arcfour implementations. Minor changes to ppp_generic.c try to prevent a link from disabling compression (in our case, the encryption) after it has started using compression (encryption). Feedback to <pptpclient-devel@lists.sourceforge.net> please. Signed-off-by: Matt Domsch <Matt_Domsch@dell.com> Cc: James Cameron <james.cameron@hp.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Brice Goglin <Brice.Goglin@ens-lyon.org> Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6722e78 commit b3f9b92

File tree

7 files changed

+902
-26
lines changed

7 files changed

+902
-26
lines changed

drivers/net/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,19 @@ config PPP_BSDCOMP
25232523
module; it is called bsd_comp and will show up in the directory
25242524
modules once you have said "make modules". If unsure, say N.
25252525

2526+
config PPP_MPPE
2527+
tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
2528+
depends on PPP && EXPERIMENTAL
2529+
select CRYPTO
2530+
select CRYPTO_SHA1
2531+
select CRYPTO_ARC4
2532+
---help---
2533+
Support for the MPPE Encryption protocol, as employed by the
2534+
Microsoft Point-to-Point Tunneling Protocol.
2535+
2536+
See http://pptpclient.sourceforge.net/ for information on
2537+
configuring PPTP clients and servers to utilize this method.
2538+
25262539
config PPPOE
25272540
tristate "PPP over Ethernet (EXPERIMENTAL)"
25282541
depends on EXPERIMENTAL && PPP

drivers/net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
112112
obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
113113
obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
114114
obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
115+
obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
115116
obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
116117

117118
obj-$(CONFIG_SLIP) += slip.o

drivers/net/ppp_generic.c

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,14 @@ struct ppp {
137137

138138
/*
139139
* Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
140-
* SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP.
140+
* SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
141+
* SC_MUST_COMP
141142
* Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
142143
* Bits in xstate: SC_COMP_RUN
143144
*/
144145
#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
145146
|SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
146-
|SC_COMP_TCP|SC_REJ_COMP_TCP)
147+
|SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
147148

148149
/*
149150
* Private data structure for each channel.
@@ -1027,6 +1028,56 @@ ppp_xmit_process(struct ppp *ppp)
10271028
ppp_xmit_unlock(ppp);
10281029
}
10291030

1031+
static inline struct sk_buff *
1032+
pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
1033+
{
1034+
struct sk_buff *new_skb;
1035+
int len;
1036+
int new_skb_size = ppp->dev->mtu +
1037+
ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
1038+
int compressor_skb_size = ppp->dev->mtu +
1039+
ppp->xcomp->comp_extra + PPP_HDRLEN;
1040+
new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
1041+
if (!new_skb) {
1042+
if (net_ratelimit())
1043+
printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1044+
return NULL;
1045+
}
1046+
if (ppp->dev->hard_header_len > PPP_HDRLEN)
1047+
skb_reserve(new_skb,
1048+
ppp->dev->hard_header_len - PPP_HDRLEN);
1049+
1050+
/* compressor still expects A/C bytes in hdr */
1051+
len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1052+
new_skb->data, skb->len + 2,
1053+
compressor_skb_size);
1054+
if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1055+
kfree_skb(skb);
1056+
skb = new_skb;
1057+
skb_put(skb, len);
1058+
skb_pull(skb, 2); /* pull off A/C bytes */
1059+
} else if (len == 0) {
1060+
/* didn't compress, or CCP not up yet */
1061+
kfree_skb(new_skb);
1062+
new_skb = skb;
1063+
} else {
1064+
/*
1065+
* (len < 0)
1066+
* MPPE requires that we do not send unencrypted
1067+
* frames. The compressor will return -1 if we
1068+
* should drop the frame. We cannot simply test
1069+
* the compress_proto because MPPE and MPPC share
1070+
* the same number.
1071+
*/
1072+
if (net_ratelimit())
1073+
printk(KERN_ERR "ppp: compressor dropped pkt\n");
1074+
kfree_skb(skb);
1075+
kfree_skb(new_skb);
1076+
new_skb = NULL;
1077+
}
1078+
return new_skb;
1079+
}
1080+
10301081
/*
10311082
* Compress and send a frame.
10321083
* The caller should have locked the xmit path,
@@ -1113,29 +1164,14 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
11131164
/* try to do packet compression */
11141165
if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
11151166
&& proto != PPP_LCP && proto != PPP_CCP) {
1116-
new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
1117-
GFP_ATOMIC);
1118-
if (new_skb == 0) {
1119-
printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1167+
if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
1168+
if (net_ratelimit())
1169+
printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
11201170
goto drop;
11211171
}
1122-
if (ppp->dev->hard_header_len > PPP_HDRLEN)
1123-
skb_reserve(new_skb,
1124-
ppp->dev->hard_header_len - PPP_HDRLEN);
1125-
1126-
/* compressor still expects A/C bytes in hdr */
1127-
len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1128-
new_skb->data, skb->len + 2,
1129-
ppp->dev->mtu + PPP_HDRLEN);
1130-
if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1131-
kfree_skb(skb);
1132-
skb = new_skb;
1133-
skb_put(skb, len);
1134-
skb_pull(skb, 2); /* pull off A/C bytes */
1135-
} else {
1136-
/* didn't compress, or CCP not up yet */
1137-
kfree_skb(new_skb);
1138-
}
1172+
skb = pad_compress_skb(ppp, skb);
1173+
if (!skb)
1174+
goto drop;
11391175
}
11401176

11411177
/*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
11551191
return;
11561192

11571193
drop:
1158-
kfree_skb(skb);
1194+
if (skb)
1195+
kfree_skb(skb);
11591196
++ppp->stats.tx_errors;
11601197
}
11611198

@@ -1552,6 +1589,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
15521589
&& (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
15531590
skb = ppp_decompress_frame(ppp, skb);
15541591

1592+
if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
1593+
goto err;
1594+
15551595
proto = PPP_PROTO(skb);
15561596
switch (proto) {
15571597
case PPP_VJC_COMP:

0 commit comments

Comments
 (0)