From owner-skip-info@rt.com Wed Mar 11 04:38:56 1998 Return-Path: Received: from linas.org (firewall.linas.org [10.50.1.1]) by shadygrove.linas.org (8.8.4/8.8.7) with ESMTP id EAA18694 for ; Wed, 11 Mar 1998 04:38:55 -0600 Received: from freeside.fc.net (freeside.fc.net [207.170.70.2]) by linas.org (8.8.4/8.7.3) with ESMTP id DAA31191 for ; Wed, 11 Mar 1998 03:29:16 -0600 Received: from xkey.com (xkey.com [207.126.116.160]) by freeside.fc.net (8.8.8/8.8.8) with SMTP id DAA14074 for ; Wed, 11 Mar 1998 03:26:24 -0600 (CST) Received: (from majordomo@localhost) by xkey.com id WAA14722 for skip-info-outgoing; Tue, 10 Mar 1998 22:34:57 -0800 Received: (from smtp@localhost) by xkey.com id WAA14714 for ; Tue, 10 Mar 1998 22:34:56 -0800 Received: from sigge.signum.se(193.180.23.4) by xkey.com via smtp (V1.3) id sma014712; Tue Mar 10 22:34:47 1998 Received: from semlan (kina@semlan.signum.se [193.180.23.62]) by sigge.signum.se (8.8.5/8.8.5) with ESMTP id HAA02690; Wed, 11 Mar 1998 07:34:30 +0100 (MET) Date: Wed, 11 Mar 1998 07:35:34 +0100 (MET) From: Kristina Holmqvist Reply-To: Kristina Holmqvist Subject: Re: Enskip for linux 2.0.33 To: Radovan Semancik cc: skip-info@skip.org In-Reply-To: <34E6C147.C120395E@pubnet.sk> Message-ID: MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="-1262404073-1497742220-889598136=:25053" Sender: owner-skip-info@rt.com Precedence: bulk Status: RO ---1262404073-1497742220-889598136=:25053 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII > > Is there an enskip linux kernel patch for kernel version 2.0.33 ? You can find both a 2.0.32- and a 2.0.33-patch attached. But I guess that you've already got one... Regards, /Kristina Holmqvist ---1262404073-1497742220-889598136=:25053 Content-Type: TEXT/plain; CHARSET=US-ASCII Content-Description: ENskip-linux-2.0.32.diff --- linux/include/linux/firewall.h.orig Thu Nov 21 10:36:10 1996 +++ linux/include/linux/firewall.h Sun Nov 24 15:08:49 1996 @@ -5,22 +5,23 @@ * Definitions for loadable firewall modules */ -#define FW_BLOCK 0 -#define FW_ACCEPT 1 +#define FW_QUEUE 0 +#define FW_BLOCK 1 +#define FW_ACCEPT 2 #define FW_REJECT (-1) -#define FW_REDIRECT 2 -#define FW_MASQUERADE 3 -#define FW_SKIP 4 +#define FW_REDIRECT 3 +#define FW_MASQUERADE 4 +#define FW_SKIP 5 struct firewall_ops { struct firewall_ops *next; int (*fw_forward)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_input)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_output)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); /* Data falling in the second 486 cache line isn't used directly during a firewall call and scan, only by insert/delete and other unusual cases @@ -32,9 +33,9 @@ #ifdef __KERNEL__ extern int register_firewall(int pf, struct firewall_ops *fw); extern int unregister_firewall(int pf, struct firewall_ops *fw); -extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg); -extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg); -extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg); +extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); +extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); +extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); extern void fwchain_init(void); #endif --- linux/include/linux/ipsec.h.orig Tue Nov 26 18:46:57 1996 +++ linux/include/linux/ipsec.h Tue Nov 26 18:06:33 1996 @@ -0,0 +1,54 @@ +/* + * Definitions for the SECurity layer + * + * Author: + * Robert Muchsel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_IPSEC_H +#define _LINUX_IPSEC_H + +#include +#include + +/* Values for the set/getsockopt calls */ + +/* These defines are compatible with NRL IPv6, however their semantics + is different */ + +#define IPSEC_LEVEL_NONE -1 /* send plaintext, accept any */ +#define IPSEC_LEVEL_DEFAULT 0 /* encrypt/authenticate if possible */ + /* the default MUST be 0, because a */ + /* socket is initialized with 0's */ +#define IPSEC_LEVEL_USE 1 /* use outbound, don't require inbound */ +#define IPSEC_LEVEL_REQUIRE 2 /* require both directions */ +#define IPSEC_LEVEL_UNIQUE 2 /* for compatibility only */ + +#ifdef __KERNEL__ + +/* skb bit flags set on packet input processing */ + +#define RCV_SEC 0x01 /* options on receive */ +#define RCV_AUTH 0x02 /* was authenticated */ +#define RCV_CRYPT 0x04 /* was encrypted */ +#define RCV_TUNNEL 0x08 /* was tunneled */ +#define SND_SEC 0x10 /* options on send, these are */ +#define SND_AUTH 0x20 /* currently unused */ +#define SND_CRYPT 0x40 +#define SND_TUNNEL 0x80 + +static __inline__ int ipsec_sk_policy(struct sock *sk, struct sk_buff *skb) +{ + return ((sk->authentication < IPSEC_LEVEL_REQUIRE) || + (skb->proto_priv[15] & RCV_AUTH)) && + ((sk->encryption < IPSEC_LEVEL_REQUIRE) || + (skb->proto_priv[15] & RCV_CRYPT)); +} + +#endif /* __KERNEL__ */ +#endif /* _LINUX_IPSEC_H */ --- linux/include/net/sock.h.orig Tue Nov 26 15:25:23 1996 +++ linux/include/net/sock.h Tue Nov 26 17:08:36 1996 @@ -340,6 +340,13 @@ void (*data_ready)(struct sock *sk,int bytes); void (*write_space)(struct sock *sk); void (*error_report)(struct sock *sk); + + /* + * Security + */ + + short authentication; + short encryption; }; --- linux/net/core/firewall.c.orig Thu Nov 21 10:37:41 1996 +++ linux/net/core/firewall.c Sun Nov 24 15:08:50 1996 @@ -99,13 +99,13 @@ return -ENOENT; } -int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_forward(fw,pf,dev,phdr,arg); + int rc=fw->fw_forward(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; @@ -117,13 +117,13 @@ * Actual invocation of the chains */ -int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_input(fw,pf,dev,phdr,arg); + int rc=fw->fw_input(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; @@ -131,13 +131,13 @@ return firewall_policy[pf]; } -int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_output(fw,pf,dev,phdr,arg); + int rc=fw->fw_output(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; --- linux/net/core/sock.c.orig Wed Dec 17 07:35:16 1997 +++ linux/net/core/sock.c Wed Dec 17 07:36:05 1997 @@ -235,6 +235,14 @@ sk->bsdism = valbool; return 0; + case SO_SECURITY_AUTHENTICATION: + sk->authentication = val; + return 0; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + sk->encryption = val; + return 0; + #ifdef CONFIG_NET case SO_BINDTODEVICE: /* Bind this socket to a particular device like "eth0", @@ -345,6 +353,14 @@ case SO_BSDCOMPAT: val = sk->bsdism; + break; + + case SO_SECURITY_AUTHENTICATION: + val = sk->authentication; + break; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + val = sk->encryption; break; #ifdef CONFIG_NET --- linux/net/ipv4/ip_output.c.orig Tue Nov 26 16:19:29 1996 +++ linux/net/ipv4/ip_output.c Tue Nov 26 16:02:00 1996 @@ -66,6 +66,7 @@ #include #include #include +#include /* * Allows dynamic re-writing of packet's addresses. @@ -488,9 +489,20 @@ goto no_device; #ifdef CONFIG_FIREWALL - if (call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT) + if (call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) goto out; #endif + /* + * Add an IP checksum (must do this before SECurity because + * of possible tunneling) + */ + + ip_send_check(iph); + + if (call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 4, &skb)ip_hdr; + /* don't update tot_len, as the dev->mtu is already decreased */ /* * Do we need to fragment. Again this is inefficient. @@ -501,11 +513,13 @@ if (tot_len > dev->mtu) goto fragment; +#if 0 /* * Add an IP checksum */ ip_send_check(iph); +#endif /* * More debugging. You cannot queue a packet already on a list @@ -641,6 +655,9 @@ struct hh_cache * hh=NULL; int nfrags=0; __u32 true_daddr = daddr; +#ifdef CONFIG_FIREWALL + int fw_res; +#endif if (opt && opt->srr && !sk->ip_hdrincl) daddr = opt->faddr; @@ -766,12 +783,20 @@ getfrag(frag,saddr,(void *)iph,0,length); dev_unlock_list(); #ifdef CONFIG_FIREWALL - if(call_out_firewall(PF_INET, skb->dev, iph, NULL)< FW_ACCEPT) + if(call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb)dev, NULL, (void *) 5, &skb))dev, iph, NULL) < FW_ACCEPT) + if(!offset && call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) { kfree_skb(skb, FREE_WRITE); dev_unlock_list(); return -EPERM; } #endif + if ((fw_res=call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 6, &skb))dev=dev; skb->arp=1; #ifdef CONFIG_FIREWALL - if (call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT) { + if (call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) { /* The firewall wants us to dump the packet. * We have to check this here, because * the drop in ip_queue_xmit only catches the @@ -587,6 +587,18 @@ break; } #endif + /* We must add these fields before the call to SECurity layer + because the TCP header might be gone afterwards... */ + th->ack_seq = htonl(sk->acked_seq); + clear_delayed_acks(sk); + th->window = ntohs(tcp_select_window(sk)); + tcp_send_check(th, sk->saddr, sk->daddr, size, skb); + + if (call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 3, &skb)data; + size = ntohs(iph->tot_len) - (iph->ihl<<2); + if (rt->rt_hh) { memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len); @@ -604,6 +616,7 @@ skb->arp=0; } +#if 0 /* * This is not the right way to handle this. We have to * issue an up to date window and ack report with this @@ -619,6 +632,7 @@ clear_delayed_acks(sk); th->window = ntohs(tcp_select_window(sk)); tcp_send_check(th, sk->saddr, sk->daddr, size, skb); +#endif /* * If the interface is (still) up and running, kick it. --- linux/net/ipv4/tcp_input.c.orig Tue Nov 26 16:42:14 1996 +++ linux/net/ipv4/tcp_input.c Tue Nov 26 16:44:15 1996 @@ -42,6 +42,7 @@ #include #include #include +#include /* * Policy code extracted so it's now separate @@ -2313,6 +2314,8 @@ sk = __tcp_v4_lookup(th, saddr, th->source, daddr, th->dest, dev); if (!sk) goto no_tcp_socket; + if (!ipsec_sk_policy(sk, skb)) + goto discard_it; /* don't send RST (think!) */ skb->sk = sk; skb->seq = ntohl(th->seq); skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; --- linux/net/ipv4/udp.c.orig Tue Nov 26 16:44:24 1996 +++ linux/net/ipv4/udp.c Tue Nov 26 16:50:24 1996 @@ -114,6 +114,7 @@ #include #include #include +#include /* * Snmp MIB for the UDP layer @@ -1102,6 +1103,12 @@ kfree_skb(skb, FREE_WRITE); return(0); } + if (!ipsec_sk_policy(sk, skb)) /* discard the frame */ + { + skb->sk = NULL; + kfree_skb(skb, FREE_WRITE); + return(0); + } udp_deliver(sk, skb); return 0; } --- linux/include/linux/socket.h.orig Sun May 25 17:17:45 1997 +++ linux/include/linux/socket.h Sun May 25 17:27:39 1997 @@ -63,6 +63,7 @@ #ifdef LINUX_2_1_X #define AF_INET6 10 /* IP version 6 */ #endif +#define pseudo_AF_IPSEC 11 /* used for IPSEC callbacks */ #define AF_MAX 12 /* For now.. */ /* Protocol families, same as address families. */ @@ -76,6 +77,7 @@ #define PF_BRIDGE AF_BRIDGE #define PF_AAL5 AF_AAL5 #define PF_X25 AF_X25 +#define PF_IPSEC pseudo_AF_IPSEC #ifdef LINUX_2_1_X #define PF_INET6 AF_INET6 #endif @@ -132,6 +134,11 @@ #define SOPRI_INTERACTIVE 0 #define SOPRI_NORMAL 1 #define SOPRI_BACKGROUND 2 + +/* Socket options for the security layer (these are compatible with NRL IPv6) */ +#define SO_SECURITY_AUTHENTICATION 0x1009 /* set AH */ +#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x1010 /* set ESP */ +/* #define SO_SECURITY_ENCRYPTION_NETWORK 0x1011 -- unsupported */ #ifdef __KERNEL__ extern void memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); --- linux/net/ipv4/ip_forward.c.orig Sun May 25 17:18:01 1997 +++ linux/net/ipv4/ip_forward.c Sun May 25 17:30:22 1997 @@ -40,6 +40,8 @@ #include #include +#define CONFIG_IP_NO_ICMP_REDIRECT + #ifdef CONFIG_IP_FORWARD /* set the default */ int sysctl_ip_forward = 1; #else @@ -125,6 +127,7 @@ struct sk_buff *skb_in = skb; /* So we can remember if the masquerader did some swaps */ #endif /* CONFIG_IP_MASQUERADE */ #endif /* CONFIG_FIREWALL */ + unsigned short mtu; /* * According to the RFC, we must first decrease the TTL field. If @@ -292,7 +295,7 @@ #endif } #endif - fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL); + fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL, &skb); switch (fw_res) { case FW_ACCEPT: case FW_MASQUERADE: @@ -310,6 +313,9 @@ } #endif + if (call_out_firewall(PF_IPSEC, dev2, NULL, (void *) 2, &skb)len+encap > dev2->mtu && (iph->frag_off & htons(IP_DF))) + mtu = dev2->mtu; + call_fw_firewall(PF_IPSEC, dev2, NULL, &mtu, NULL); + + if (skb->len+encap > mtu && (iph->frag_off & htons(IP_DF))) { ip_statistics.IpFragFails++; - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu), dev); if(rt) ip_rt_put(rt); return -1; @@ -446,7 +455,7 @@ #endif } #ifdef CONFIG_FIREWALL - if((fw_res = call_out_firewall(PF_INET, skb2->dev, iph, NULL)) < FW_ACCEPT) + if((fw_res = call_out_firewall(PF_INET, skb2->dev, iph, NULL, &skb2)) < FW_ACCEPT) { /* FW_ACCEPT and FW_MASQUERADE are treated equal: masquerading is only supported via forward rules */ @@ -517,7 +526,7 @@ * the fragmenter does the right thing. */ - if(skb2->len > dev2->mtu + dev2->hard_header_len) + if(skb2->len > mtu + dev2->hard_header_len) { ip_fragment(NULL,skb2,dev2, is_frag); kfree_skb(skb2,FREE_WRITE); --- linux/net/ipv4/ip_input.c.orig Sun May 25 17:18:01 1997 +++ linux/net/ipv4/ip_input.c Sun May 25 17:37:26 1997 @@ -159,6 +159,7 @@ #ifdef CONFIG_NET_ALIAS #include #endif +#include extern int last_retran; extern void sort_send(struct sock *sk); @@ -384,7 +385,7 @@ #ifdef CONFIG_FIREWALL - if ((fwres=call_in_firewall(PF_INET, skb->dev, iph, &rport))dev, iph, &rport, &skb))saddr,daddr); + if(ipsec_sk_policy(raw_sk, skb1)) + raw_rcv(raw_sk, skb1, dev, iph->saddr,daddr); + else + kfree_skb(skb1, FREE_WRITE); raw_sk = sknext; } while(raw_sk!=NULL); @@ -692,7 +696,10 @@ #endif if(raw_sk!=NULL) /* Shift to last raw user */ - raw_rcv(raw_sk, skb, dev, iph->saddr, daddr); + if(ipsec_sk_policy(raw_sk, skb)) + raw_rcv(raw_sk, skb, dev, iph->saddr, daddr); + else + kfree_skb(skb, FREE_WRITE); else if (!flag) /* Free and report errors */ { if (brd != IS_BROADCAST && brd!=IS_MULTICAST) ---1262404073-1497742220-889598136=:25053 Content-Type: TEXT/plain; CHARSET=US-ASCII Content-Description: ENskip-linux-2.0.33.diff --- linux/include/linux/firewall.h.orig Thu Nov 21 10:36:10 1996 +++ linux/include/linux/firewall.h Sun Nov 24 15:08:49 1996 @@ -5,22 +5,23 @@ * Definitions for loadable firewall modules */ -#define FW_BLOCK 0 -#define FW_ACCEPT 1 +#define FW_QUEUE 0 +#define FW_BLOCK 1 +#define FW_ACCEPT 2 #define FW_REJECT (-1) -#define FW_REDIRECT 2 -#define FW_MASQUERADE 3 -#define FW_SKIP 4 +#define FW_REDIRECT 3 +#define FW_MASQUERADE 4 +#define FW_SKIP 5 struct firewall_ops { struct firewall_ops *next; int (*fw_forward)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_input)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); int (*fw_output)(struct firewall_ops *this, int pf, - struct device *dev, void *phdr, void *arg); + struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); /* Data falling in the second 486 cache line isn't used directly during a firewall call and scan, only by insert/delete and other unusual cases @@ -32,9 +33,9 @@ #ifdef __KERNEL__ extern int register_firewall(int pf, struct firewall_ops *fw); extern int unregister_firewall(int pf, struct firewall_ops *fw); -extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg); -extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg); -extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg); +extern int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); +extern int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); +extern int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb); extern void fwchain_init(void); #endif --- linux/include/linux/ipsec.h.orig Tue Nov 26 18:46:57 1996 +++ linux/include/linux/ipsec.h Tue Nov 26 18:06:33 1996 @@ -0,0 +1,54 @@ +/* + * Definitions for the SECurity layer + * + * Author: + * Robert Muchsel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_IPSEC_H +#define _LINUX_IPSEC_H + +#include +#include + +/* Values for the set/getsockopt calls */ + +/* These defines are compatible with NRL IPv6, however their semantics + is different */ + +#define IPSEC_LEVEL_NONE -1 /* send plaintext, accept any */ +#define IPSEC_LEVEL_DEFAULT 0 /* encrypt/authenticate if possible */ + /* the default MUST be 0, because a */ + /* socket is initialized with 0's */ +#define IPSEC_LEVEL_USE 1 /* use outbound, don't require inbound */ +#define IPSEC_LEVEL_REQUIRE 2 /* require both directions */ +#define IPSEC_LEVEL_UNIQUE 2 /* for compatibility only */ + +#ifdef __KERNEL__ + +/* skb bit flags set on packet input processing */ + +#define RCV_SEC 0x01 /* options on receive */ +#define RCV_AUTH 0x02 /* was authenticated */ +#define RCV_CRYPT 0x04 /* was encrypted */ +#define RCV_TUNNEL 0x08 /* was tunneled */ +#define SND_SEC 0x10 /* options on send, these are */ +#define SND_AUTH 0x20 /* currently unused */ +#define SND_CRYPT 0x40 +#define SND_TUNNEL 0x80 + +static __inline__ int ipsec_sk_policy(struct sock *sk, struct sk_buff *skb) +{ + return ((sk->authentication < IPSEC_LEVEL_REQUIRE) || + (skb->proto_priv[15] & RCV_AUTH)) && + ((sk->encryption < IPSEC_LEVEL_REQUIRE) || + (skb->proto_priv[15] & RCV_CRYPT)); +} + +#endif /* __KERNEL__ */ +#endif /* _LINUX_IPSEC_H */ --- linux/include/net/sock.h.orig Tue Nov 26 15:25:23 1996 +++ linux/include/net/sock.h Tue Nov 26 17:08:36 1996 @@ -340,6 +340,13 @@ void (*data_ready)(struct sock *sk,int bytes); void (*write_space)(struct sock *sk); void (*error_report)(struct sock *sk); + + /* + * Security + */ + + short authentication; + short encryption; }; --- linux/net/core/firewall.c.orig Thu Nov 21 10:37:41 1996 +++ linux/net/core/firewall.c Sun Nov 24 15:08:50 1996 @@ -99,13 +99,13 @@ return -ENOENT; } -int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_fw_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_forward(fw,pf,dev,phdr,arg); + int rc=fw->fw_forward(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; @@ -117,13 +117,13 @@ * Actual invocation of the chains */ -int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_in_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_input(fw,pf,dev,phdr,arg); + int rc=fw->fw_input(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; @@ -131,13 +131,13 @@ return firewall_policy[pf]; } -int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg) +int call_out_firewall(int pf, struct device *dev, void *phdr, void *arg, struct sk_buff **pskb) { struct firewall_ops *fw=firewall_chain[pf]; while(fw!=NULL) { - int rc=fw->fw_output(fw,pf,dev,phdr,arg); + int rc=fw->fw_output(fw,pf,dev,phdr,arg,pskb); if(rc!=FW_SKIP) return rc; fw=fw->next; --- linux/net/core/sock.c.orig Wed Dec 17 07:35:16 1997 +++ linux/net/core/sock.c Wed Dec 17 07:36:05 1997 @@ -235,6 +235,14 @@ sk->bsdism = valbool; return 0; + case SO_SECURITY_AUTHENTICATION: + sk->authentication = val; + return 0; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + sk->encryption = val; + return 0; + #ifdef CONFIG_NET case SO_BINDTODEVICE: /* Bind this socket to a particular device like "eth0", @@ -345,6 +353,14 @@ case SO_BSDCOMPAT: val = sk->bsdism; + break; + + case SO_SECURITY_AUTHENTICATION: + val = sk->authentication; + break; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + val = sk->encryption; break; #ifdef CONFIG_NET --- linux/net/ipv4/ip_output.c.orig Tue Nov 26 16:19:29 1996 +++ linux/net/ipv4/ip_output.c Tue Nov 26 16:02:00 1996 @@ -66,6 +66,7 @@ #include #include #include +#include /* * Allows dynamic re-writing of packet's addresses. @@ -488,9 +489,20 @@ goto no_device; #ifdef CONFIG_FIREWALL - if (call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT) + if (call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) goto out; #endif + /* + * Add an IP checksum (must do this before SECurity because + * of possible tunneling) + */ + + ip_send_check(iph); + + if (call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 4, &skb)ip_hdr; + /* don't update tot_len, as the dev->mtu is already decreased */ /* * Do we need to fragment. Again this is inefficient. @@ -501,11 +513,13 @@ if (tot_len > dev->mtu) goto fragment; +#if 0 /* * Add an IP checksum */ ip_send_check(iph); +#endif /* * More debugging. You cannot queue a packet already on a list @@ -641,6 +655,9 @@ struct hh_cache * hh=NULL; int nfrags=0; __u32 true_daddr = daddr; +#ifdef CONFIG_FIREWALL + int fw_res; +#endif if (opt && opt->srr && !sk->ip_hdrincl) daddr = opt->faddr; @@ -766,12 +783,20 @@ getfrag(frag,saddr,(void *)iph,0,length); dev_unlock_list(); #ifdef CONFIG_FIREWALL - if(call_out_firewall(PF_INET, skb->dev, iph, NULL)< FW_ACCEPT) + if(call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb)dev, NULL, (void *) 5, &skb))dev, iph, NULL) < FW_ACCEPT) + if(!offset && call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) { kfree_skb(skb, FREE_WRITE); dev_unlock_list(); return -EPERM; } #endif + if ((fw_res=call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 6, &skb))dev=dev; skb->arp=1; #ifdef CONFIG_FIREWALL - if (call_out_firewall(PF_INET, skb->dev, iph, NULL) < FW_ACCEPT) { + if (call_out_firewall(PF_INET, skb->dev, iph, NULL, &skb) < FW_ACCEPT) { /* The firewall wants us to dump the packet. * We have to check this here, because * the drop in ip_queue_xmit only catches the @@ -587,6 +587,18 @@ break; } #endif + /* We must add these fields before the call to SECurity layer + because the TCP header might be gone afterwards... */ + th->ack_seq = htonl(sk->acked_seq); + clear_delayed_acks(sk); + th->window = ntohs(tcp_select_window(sk)); + tcp_send_check(th, sk->saddr, sk->daddr, size, skb); + + if (call_out_firewall(PF_IPSEC, skb->dev, NULL, (void *) 3, &skb)data; + size = ntohs(iph->tot_len) - (iph->ihl<<2); + if (rt->rt_hh) { memcpy(skb_push(skb,dev->hard_header_len),rt->rt_hh->hh_data,dev->hard_header_len); @@ -604,6 +616,7 @@ skb->arp=0; } +#if 0 /* * This is not the right way to handle this. We have to * issue an up to date window and ack report with this @@ -619,6 +632,7 @@ clear_delayed_acks(sk); th->window = ntohs(tcp_select_window(sk)); tcp_send_check(th, sk->saddr, sk->daddr, size, skb); +#endif /* * If the interface is (still) up and running, kick it. --- linux/net/ipv4/tcp_input.c.orig Tue Nov 26 16:42:14 1996 +++ linux/net/ipv4/tcp_input.c Tue Nov 26 16:44:15 1996 @@ -42,6 +42,7 @@ #include #include #include +#include /* * Policy code extracted so it's now separate @@ -2313,6 +2314,8 @@ sk = __tcp_v4_lookup(th, saddr, th->source, daddr, th->dest, dev); if (!sk) goto no_tcp_socket; + if (!ipsec_sk_policy(sk, skb)) + goto discard_it; /* don't send RST (think!) */ skb->sk = sk; skb->seq = ntohl(th->seq); skb->end_seq = skb->seq + th->syn + th->fin + len - th->doff*4; --- linux/net/ipv4/udp.c.orig Tue Nov 26 16:44:24 1996 +++ linux/net/ipv4/udp.c Tue Nov 26 16:50:24 1996 @@ -115,6 +115,7 @@ #include #include #include +#include /* * Snmp MIB for the UDP layer @@ -1105,6 +1105,12 @@ kfree_skb(skb, FREE_WRITE); return(0); } + if (!ipsec_sk_policy(sk, skb)) /* discard the frame */ + { + skb->sk = NULL; + kfree_skb(skb, FREE_WRITE); + return(0); + } udp_deliver(sk, skb); return 0; } --- linux/include/linux/socket.h.orig Sun May 25 17:17:45 1997 +++ linux/include/linux/socket.h Sun May 25 17:27:39 1997 @@ -63,6 +63,7 @@ #ifdef LINUX_2_1_X #define AF_INET6 10 /* IP version 6 */ #endif +#define pseudo_AF_IPSEC 11 /* used for IPSEC callbacks */ #define AF_MAX 12 /* For now.. */ /* Protocol families, same as address families. */ @@ -76,6 +77,7 @@ #define PF_BRIDGE AF_BRIDGE #define PF_AAL5 AF_AAL5 #define PF_X25 AF_X25 +#define PF_IPSEC pseudo_AF_IPSEC #ifdef LINUX_2_1_X #define PF_INET6 AF_INET6 #endif @@ -132,6 +134,11 @@ #define SOPRI_INTERACTIVE 0 #define SOPRI_NORMAL 1 #define SOPRI_BACKGROUND 2 + +/* Socket options for the security layer (these are compatible with NRL IPv6) */ +#define SO_SECURITY_AUTHENTICATION 0x1009 /* set AH */ +#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x1010 /* set ESP */ +/* #define SO_SECURITY_ENCRYPTION_NETWORK 0x1011 -- unsupported */ #ifdef __KERNEL__ extern void memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); --- linux/net/ipv4/ip_forward.c Thu Dec 11 03:13:49 1997 +++ linux/net/ipv4/ip_forward.c Thu Jan 22 09:34:39 1998 @@ -41,6 +41,8 @@ #include #include +#define CONFIG_IP_NO_ICMP_REDIRECT + #ifdef CONFIG_IP_FORWARD /* set the default */ int sysctl_ip_forward = 1; #else @@ -126,6 +128,7 @@ struct sk_buff *skb_in = skb; /* So we can remember if the masquerader did some swaps */ #endif /* CONFIG_IP_MASQUERADE */ #endif /* CONFIG_FIREWALL */ + unsigned short mtu; /* * According to the RFC, we must first decrease the TTL field. If @@ -293,7 +296,7 @@ #endif } #endif - fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL); + fw_res=call_fw_firewall(PF_INET, dev2, iph, NULL, &skb); switch (fw_res) { case FW_ACCEPT: case FW_MASQUERADE: @@ -313,6 +316,9 @@ } #endif + if (call_out_firewall(PF_IPSEC, dev2, NULL, (void *) 2, &skb)len+encap > dev2->mtu && (iph->frag_off & htons(IP_DF))) + mtu = dev2->mtu; + call_fw_firewall(PF_IPSEC, dev2, NULL, &mtu, NULL); + + if (skb->len+encap > mtu && (iph->frag_off & htons(IP_DF))) { ip_statistics.IpFragFails++; #ifdef CONFIG_IP_MASQUERADE @@ -371,10 +380,10 @@ if (premasq_len_diff < 0) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(dev2->mtu+premasq_len_diff), dev); + htonl(mtu+premasq_len_diff), dev); else #endif - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu), dev); if(rt) ip_rt_put(rt); return -1; @@ -482,7 +491,7 @@ #endif } #ifdef CONFIG_FIREWALL - if((fw_res = call_out_firewall(PF_INET, skb2->dev, iph, NULL)) < FW_ACCEPT) + if((fw_res = call_out_firewall(PF_INET, skb2->dev, iph, NULL, &skb2)) < FW_ACCEPT) { /* FW_ACCEPT and FW_MASQUERADE are treated equal: masquerading is only supported via forward rules */ @@ -555,7 +564,7 @@ * the fragmenter does the right thing. */ - if(skb2->len > dev2->mtu + dev2->hard_header_len) + if(skb2->len > mtu + dev2->hard_header_len) { ip_fragment(NULL,skb2,dev2, is_frag); kfree_skb(skb2,FREE_WRITE); --- linux/net/ipv4/ip_input.c.orig Sun May 25 17:18:01 1997 +++ linux/net/ipv4/ip_input.c Sun May 25 17:37:26 1997 @@ -159,6 +159,7 @@ #ifdef CONFIG_NET_ALIAS #include #endif +#include extern int last_retran; extern void sort_send(struct sock *sk); @@ -384,7 +385,7 @@ #ifdef CONFIG_FIREWALL - if ((fwres=call_in_firewall(PF_INET, skb->dev, iph, &rport))dev, iph, &rport, &skb))saddr,daddr); + if(ipsec_sk_policy(raw_sk, skb1)) + raw_rcv(raw_sk, skb1, dev, iph->saddr,daddr); + else + kfree_skb(skb1, FREE_WRITE); raw_sk = sknext; } while(raw_sk!=NULL); @@ -692,7 +696,10 @@ #endif if(raw_sk!=NULL) /* Shift to last raw user */ - raw_rcv(raw_sk, skb, dev, iph->saddr, daddr); + if(ipsec_sk_policy(raw_sk, skb)) + raw_rcv(raw_sk, skb, dev, iph->saddr, daddr); + else + kfree_skb(skb, FREE_WRITE); else if (!flag) /* Free and report errors */ { if (brd != IS_BROADCAST && brd!=IS_MULTICAST) ---1262404073-1497742220-889598136=:25053--