List Info

Thread: linux 2.4, RPC conntrack (2 of 2)




linux 2.4, RPC conntrack (2 of 2)
country flaguser name
Singapore
2007-04-29 17:12:23
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

diff -ur
patch-o-matic-ng-20070207/patchlets/rpc/linux/net/ipv4/ 
netfilter/ip_conntrack_rpc_udp.c
patch-o-matic-ng-20070207-new/ 
patchlets/rpc/linux/net/ipv4/netfilter/ip_conntrack_rpc_udp.
c
- ---
patch-o-matic-ng-20070207/patchlets/rpc/linux/net/ipv4/netfi
lter/ 
ip_conntrack_rpc_udp.c	2004-11-12 05:37:48.000000000 +0800
+++
patch-o-matic-ng-20070207-new/patchlets/rpc/linux/net/ipv4/

netfilter/ip_conntrack_rpc_udp.c	2007-04-29
18:54:37.000000000 +0800
 -10,6
+10,14 
   *	- upgraded conntrack modules to newnat api - kernel
2.4.20+
   *	- extended matching to support filtering on procedures
   *
+ * (c) 2007 by kokseng <koksengieee.org>
+ *	- ip_conntrack_udp now checks against the list of
allowed RPC
+ *	  specirfied by --rpcs before setting up
ip_conntrack_expect.
+ *	  Limitation is it will use the --rpcs list of the last
rule
+ *	  that invoke rpc match module of any table. This is
practical
+ *	  since usually you will need only one such rule.
+ * 	- Helper wil only look at portmap RPC now.
+ *
   * ip_conntrack_rpc_udp.c,v 2.2 2003/01/12 18:30:00
   *
   *	This program is free software; you can redistribute it
and/or
 -58,11
+66,18 
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_rpc.h>
+#include <linux/netfilter_ipv4/ipt_rpc.h>
#define MAX_PORTS 8
static int ports[MAX_PORTS];
static int ports_n_c = 0;
+#ifdef IPT_RPC_CHECK_ALLOWED
+struct rpc_allowed   rpc_allowed_udp;
+struct rpc_allowed * iptRpc_udp = NULL;
+#endif
+
+
#ifdef MODULE_PARM
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS)
"i");
MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC
portmapper  
servers");
 -72,6
+87,8 
MODULE_DESCRIPTION("RPC UDP connection tracking
module");
MODULE_LICENSE("GPL");
+#define SHOWMSG(format, args...) printk(KERN_DEBUG  
"ip_conntrack_rpc_udp: " 
+					format, ## args)
#if 0
#define DEBUGP(format, args...) printk(KERN_DEBUG  
"ip_conntrack_rpc_udp: " 
					format, ## args)
 -89,6
+106,11 
LIST_HEAD(request_p_list_udp);
+/* Implemented in ip_conntrack_rpc_tcp.c */
+extern int expect_rpc_packet(const u_int32_t *data,
+			int dir, struct ip_conntrack *ct,
+			struct list_head request_p_list, struct rpc_allowed *
allowed,
+			unsigned uThisProc, unsigned uThisProto, unsigned
uThisPort);
static void delete_request_p(unsigned long request_p_ul)
{
 -133,7
+155,7 
static void alloc_request_p(u_int32_t xid, u_int16_t proto,
u_int32_t  
ip,
- -		     u_int16_t port)
+		     u_int16_t port, u_int32_t rpcproc, u_int32_t rpcver,
 
u_int32_t getproc)
{
	struct request_p *req_p;

 -161,6
+183,7 
		return;			
	}
	*req_p = ((struct request_p) {{ NULL, NULL }, xid, ip,
port, proto,
+		rpcproc, rpcver, getproc, 0, 0, {0,0,0,0},
		{ { NULL, NULL }, jiffies + EXP, (unsigned long)req_p,
			NULL }});

 -177,18
+200,19 
}
- -
static int check_rpc_packet(const u_int32_t *data,
			int dir, struct ip_conntrack *ct,
			struct list_head request_p_list)
{
	struct request_p *req_p;
	u_int32_t xid;
- -	struct ip_conntrack_expect expect, *exp = &expect;
	/* Translstion's buffer for XDR */
	u_int16_t port_buf;
+	u_int32_t rpcproc = 0;
+	u_int32_t rpcver = 2;
+	u_int32_t rpcprog;
	/* Get XID */
	xid = *data;
 -201,16
+225,27 
	/* perform direction dependant RPC work */
	if (dir == IP_CT_DIR_ORIGINAL) {
+		unsigned getproc;
- -		data += 5;
+		DEBUGP(" ------ UDP packet is from the initiator.
[cont]n");
- -		/* Get RPC requestor */
- -		if (IXDR_GET_INT32(data) != 3) {
- -			DEBUGP("RPC packet contains an invalid (non
"get") requestor.  
[skip]n");
+		data += 3;/* 0id,
1:message_type, 2:rpcver, 3:progs, 4: progver,  
5:proc */
+		rpcprog = IXDR_GET_INT32(data);
+		if (rpcprog != IPT_RPC_PORTMAP) {
+			DEBUGP("RPC %u request: only handle portmap RPC.
[skip]n",  
rpcprog);
+			return NF_ACCEPT;
+		}
+		rpcver  = IXDR_GET_INT32((data+1));
+		rpcproc = IXDR_GET_INT32((data+2));
+		DEBUGP("RPC portmap request: procedure(%u)
ver(%u)n", rpcproc,  
rpcver);
+		data +=2;
+
+		/* UDP RPC request only handles GET request */
+		if (rpcproc != 3) {
+			/* Get RPC requestor */
+			DEBUGP("RPC packet contains invalid (%u) requestor.
[skip]n",  
rpcproc);
			return NF_ACCEPT;
		}
- -		DEBUGP("RPC packet contains a "get"
requestor. [cont]n");
- -
		data++;
		/* Jump Credentials and Verfifier */
 -218,13
+253,13 
		data = data + IXDR_GET_INT32(data) + 2;
		/* Get RPC procedure */
- -		DEBUGP("RPC packet contains procedure request
[%u]. [cont]n",
- -			(unsigned int)IXDR_GET_INT32(data));
+		getproc = (unsigned int)IXDR_GET_INT32(data);
+		DEBUGP("RPC portmap GET request for [%u].
[cont]n", getproc);
		/* Get RPC protocol and store against client parameters
*/
		data = data + 2;
		alloc_request_p(xid, IXDR_GET_INT32(data),
ct->tuplehash 
[dir].tuple.src.ip,
- -				ct->tuplehash[dir].tuple.src.u.all);
+				ct->tuplehash[dir].tuple.src.u.all, rpcproc, rpcver,
getproc);
		DEBUGP("allocated RPC req_p for xid=%u proto=%u
%u.%u.%u.%u:%un",
			xid, IXDR_GET_INT32(data),
 -235,6
+270,7 
			(unsigned int)IXDR_GET_INT32(data));
	} else {
+		DEBUGP(" ------ UDP packet is from the receiver.
[cont]n");
		/* Check for returning packet's stored counterpart */
		req_p = LIST_FIND(&request_p_list_udp, request_p_cmp,
 -264,7
+300,7 
		/* Get Verifier length. Jump verifier */
		data++;
- -		data = data + IXDR_GET_INT32(data) + 2;
+		data = data + IXDR_GET_INT32((data+1)) + 2;
		/* Is accpet status "success"? */
		if (IXDR_GET_INT32(data)) {
 -272,59
+308,13 
			return NF_ACCEPT;
		}
- -		/* Get server port number */	
		data++;
- -		port_buf = (u_int16_t) IXDR_GET_INT32(data);
- -
- -		/* If a packet has made it this far then it deserves
an
- -		 * expectation ...  if port == 0, then this service is
- -		 * not going to be registered.
- -		 */
- -		if (port_buf) {
- -			DEBUGP("port found: %un", port_buf);
- -
- -			memset(&expect, 0, sizeof(expect));
- -
- -			/* Watch out, Radioactive-Man! */
- -			exp->tuple.src.ip =
ct->tuplehash[!dir].tuple.src.ip;
- -			exp->tuple.dst.ip =
ct->tuplehash[!dir].tuple.dst.ip;
- -			exp->mask.src.ip = 0xffffffff;
- -			exp->mask.dst.ip = 0xffffffff;
- -
- -			switch (req_p->proto) {
- -				case IPPROTO_UDP:
- -					exp->tuple.src.u.udp.port = 0;
- -					exp->tuple.dst.u.udp.port = htons(port_buf);
- -					exp->tuple.dst.protonum = IPPROTO_UDP;
- -					exp->mask.src.u.udp.port = 0;
- -					exp->mask.dst.u.udp.port = htons(0xffff);
- -					exp->mask.dst.protonum = 0xffff;
- -					break;
- -
- -				case IPPROTO_TCP:
- -					exp->tuple.src.u.tcp.port = 0;
- -					exp->tuple.dst.u.tcp.port = htons(port_buf);
- -					exp->tuple.dst.protonum = IPPROTO_TCP;
- -					exp->mask.src.u.tcp.port = 0;
- -					exp->mask.dst.u.tcp.port = htons(0xffff);
- -					exp->mask.dst.protonum = 0xffff;
- -					break;
- -			}
- -			exp->expectfn = NULL;
- -
- -			ip_conntrack_expect_related(ct, &expect);
- -
- -			DEBUGP("expect related ip  
%u.%u.%u.%u:0-%u.%u.%u.%u:%u proto=%u 
n",
- -				NIPQUAD(exp->tuple.src.ip),
- -				NIPQUAD(exp->tuple.dst.ip),
- -				port_buf, req_p->proto);
- -
- -			DEBUGP("expect related mask
%u.%u.%u.%u:0-%u.%u.%u.%u:65535 proto= 
%un",
- -				NIPQUAD(exp->mask.src.ip),
- -				NIPQUAD(exp->mask.dst.ip),
- -				exp->mask.dst.protonum);
- -
- -		}
+		if (req_p->rpcproc == 3) {
+			/* Get server port number */	
+			port_buf = (u_int16_t) IXDR_GET_INT32(data);
+			expect_rpc_packet(data, dir, ct, request_p_list,
iptRpc_udp,
+				req_p->getproc, req_p->proto, port_buf);
+		} /* fi - proc = get */
		req_cl(req_p);
 -351,7
+341,7 
	const u_int16_t *chsm = (const u_int16_t *)udph + 3;
- -	DEBUGP("new packet to evaluate ..n");
+	DEBUGP(" new UDP packet to evaluate ..n");
	/* Not whole UDP header? */
	if (udplen < sizeof(struct udphdr)) {
 -372,9
+362,6 
	/* perform direction dependant protocol work */
	if (dir == IP_CT_DIR_ORIGINAL) {
- -
- -		DEBUGP("packet is from the initiator.
[cont]n");
- -
		/* Tests if packet len is ok */
		if ((udplen - sizeof(struct udphdr)) != 56) {
			DEBUGP("packet length is not correct.
[skip]n");
 -382,9
+369,6 
		}
	} else {
- -
- -		DEBUGP("packet is from the receiver.
[cont]n");
- -
		/* Until there's been traffic both ways, don't look in
packets. */
		if (ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
			DEBUGP("connection tracking state is; ctinfo=%u
..n", ctinfo);
 -401,9
+385,6 
	}
- -	/* Get to the data */
- -	/* udp *data == *correct */
- -
	/* Check the RPC data */
	crp_ret = check_rpc_packet(data, dir, ct,
request_p_list_udp);
 -426,6
+407,11 
	if (ports[0] == 0)
		ports[0] = RPC_PORT;
+	#ifdef IPT_RPC_CHECK_ALLOWED
+	memset(&rpc_allowed_udp, 0, sizeof(rpc_allowed_udp));
+	iptRpc_udp = & rpc_allowed_udp;
+	#endif
+
	for (port = 0; (port < MAX_PORTS) &&
ports[port]; port++) {
		memset(&rpc_helpers[port], 0, sizeof(struct
ip_conntrack_helper));
 -451,13
+437,13 
		rpc_helpers[port].help = help;
- -		DEBUGP("registering helper for port #%d:
%d/UDPn", port, ports 
[port]);
- -		DEBUGP("helper match ip  
%u.%u.%u.%u:%u->%u.%u.%u.%u:%un",
+		SHOWMSG("registering helper for port #%d:
%d/UDPn", port, ports 
[port]);
+		SHOWMSG("helper match ip  
%u.%u.%u.%u:%u->%u.%u.%u.%u:%un",
			NIPQUAD(rpc_helpers[port].tuple.dst.ip),
			ntohs(rpc_helpers[port].tuple.dst.u.udp.port),
			NIPQUAD(rpc_helpers[port].tuple.src.ip),
			ntohs(rpc_helpers[port].tuple.src.u.udp.port));
- -		DEBUGP("helper match mask
%u.%u.%u.%u:%u->%u.%u.%u.%u:%un",
+		SHOWMSG("helper match mask
%u.%u.%u.%u:%u->%u.%u.%u.%u:%un",
			NIPQUAD(rpc_helpers[port].mask.dst.ip),
			ntohs(rpc_helpers[port].mask.dst.u.udp.port),
			NIPQUAD(rpc_helpers[port].mask.src.ip),
 -486,8
+472,13 
	DEBUGP("cleaning request listn");
	clean_request(&request_p_list_udp);
+	#ifdef IPT_RPC_CHECK_ALLOWED
+	memset(&rpc_allowed_udp, 0, sizeof(rpc_allowed_udp));
+	iptRpc_udp = NULL;
+	#endif
+
	for (port = 0; (port < ports_n_c) &&
ports[port]; port++) {
- -		DEBUGP("unregistering port %dn",
ports[port]);
+		SHOWMSG("unregistering port %dn",
ports[port]);
		ip_conntrack_helper_unregister(&rpc_helpers[port]);
	}
}
 -500,4
+491,5 
EXPORT_SYMBOL(request_p_list_udp);
EXPORT_SYMBOL(ip_conntrack_rpc_udp);
EXPORT_SYMBOL(ipct_rpc_udp_lock);
+EXPORT_SYMBOL(iptRpc_udp);
diff -ur
patch-o-matic-ng-20070207/patchlets/rpc/linux/net/ipv4/ 
netfilter/ipt_rpc.c
patch-o-matic-ng-20070207-new/patchlets/rpc/linux/ 
net/ipv4/netfilter/ipt_rpc.c
- ---
patch-o-matic-ng-20070207/patchlets/rpc/linux/net/ipv4/netfi
lter/ 
ipt_rpc.c	2004-09-04 00:15:14.000000000 +0800
+++
patch-o-matic-ng-20070207-new/patchlets/rpc/linux/net/ipv4/

netfilter/ipt_rpc.c	2007-04-29 19:02:05.000000000 +0800
 -1,4
+1,4 
- -/* RPC extension for IP connection matching, Version 2.2
+/* RPC extension for IP connection matching, Version 2.3
   * (C) 2000 by Marcelo Barbosa Lima <marcelo.limadcc.unicamp.br>
   *	- original rpc tracking module
   *	- "recent" connection handling for kernel
2.3+ netfilter
 -10,19
+10,28 
   *	- upgraded conntrack modules to newnat api - kernel
2.4.20+
   *	- extended matching to support filtering on procedures
   *
+ * (c) 2007 by kokseng <koksengieee.org> (versione
2.3)
+ * 	- add support for portmapper DUMP procedure by handling
multiple
+ *	  fragments reply, and registering replies as expected
connections.
+*	- ip_conntrack_tcp/_udp now checks against the list of
allowed RPC
+ *	  specirfied by --rpcs before setting up
ip_conntrack_expect.
+ *	  Limitation is it will use the --rpcs list of the last
rule
+ *	  that invoke rpc match module of any table. This is
practical
+ *	  since usually you will need only one such rule.
+ * 	- Helper wil only look at portmap RPC now.
+ *	- Please use tcp for NFS in order for the protocol to
work properly
+ *	  with ip_conntrack.
+ *
   * ipt_rpc.c,v 2.2 2003/01/12 18:30:00
   *
   *	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.
- - **
+ *
   *	Module load syntax:
- - *	insmod ipt_rpc.o
ports=port1,port2,...port<MAX_PORTS>
+ *	insmod ipt_rpc.o
ports=port1,port2,...port<MAX_PORTS>
   *
- - *	Please give the ports of all RPC servers you wish to
connect to.
- - *	If you don't specify ports, the default will be port
111.
- - **
   *	Note to all:
   *
   *	RPCs should not be exposed to the internet - ask the
Pentagon;
 -57,6
+66,7 
static int ports[MAX_PORTS];
static int ports_n_c = 0;
+
#ifdef MODULE_PARM
MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS)
"i");
MODULE_PARM_DESC(ports, "port numbers (TCP/UDP) of RPC
portmapper  
servers");
 -66,6
+76,9 
MODULE_DESCRIPTION("RPC connection matching
module");
MODULE_LICENSE("GPL");
+#define SHOWMSG(format, args...) printk(KERN_DEBUG
"ipt_rpc: " 
+					format, ## args)
+
#if 0
#define DEBUGP(format, args...) printk(KERN_DEBUG
"ipt_rpc: " 
					format, ## args)
 -73,7
+86,7 
#define DEBUGP(format, args...)
#endif
- -EXPORT_NO_SYMBOLS;
+EXPORT_NO_SYMBOLS;
/* vars from ip_conntrack_rpc_tcp */
extern struct list_head request_p_list_tcp;
 -83,6
+96,12 
extern struct list_head request_p_list_udp;
extern struct module *ip_conntrack_rpc_udp;
+/* RPC allowed  */
+#ifdef IPT_RPC_CHECK_ALLOWED
+extern struct rpc_allowed * iptRpc_tcp;
+extern struct rpc_allowed * iptRpc_udp;
+#endif
+
DECLARE_RWLOCK_EXTERN(ipct_rpc_tcp_lock);
DECLARE_RWLOCK_EXTERN(ipct_rpc_udp_lock);
 -106,7
+125,6 
const int IPT_RPC_CHAR_LEN = 11;
- -
static int k_atoi(char *string)
{
	unsigned int result = 0;
 -125,14
+143,13 
	return(result);
}
- -
static int match_rpcs(char *c_procs, int i_procs, int proc)
{
	int   proc_ctr;
	char *proc_ptr;
	unsigned int proc_num;
- -	DEBUGP("entered match_rpcs [%i] [%i] ..n",
i_procs, proc);
+	DEBUGP("match_rpcs [%i] [%i] ..n", i_procs,
proc);
	if (i_procs == -1)
		return 1;
 -150,7
+167,6 
	return 0;
}
- -
static int check_rpc_packet(const u_int32_t *data, const
void  
*matchinfo,
			int *hotdrop, int dir, struct ip_conntrack *ct,
			int offset, struct list_head request_p_list)
 -381,6
+397,17 
	if (matchsize != IPT_ALIGN(sizeof(struct ipt_rpc_info)))
		return 0;
+	#ifdef IPT_RPC_CHECK_ALLOWED
+	if (iptRpc_tcp) {
+		iptRpc_tcp->fMatchRpcs = match_rpcs;
+		iptRpc_tcp->rpc_info = matchinfo;
+	}
+	if (iptRpc_udp) {
+		iptRpc_udp->fMatchRpcs = match_rpcs;
+		iptRpc_udp->rpc_info = matchinfo;
+	}
+	#endif
+	
	return 1;
}
 -398,9
+425,9 
	if (ports[0] == 0)
		ports[0] = RPC_PORT;
- -	DEBUGP("registering match [%s] for;n",
rpc_match.name);
+	SHOWMSG("registering match [%s] for;n",
rpc_match.name);
	for (port = 0; (port < MAX_PORTS) &&
ports[port]; port++) {
- -		DEBUGP("  port %i (UDP|TCP);n",
ports[port]);
+		SHOWMSG("  port %i (UDP|TCP);n",
ports[port]);
		ports_n_c++;
	}
	
 -410,7
+437,7 
static void fini(void)
{
- -	DEBUGP("unregistering matchn");
+	SHOWMSG("unregistering matchn");
	ipt_unregister_match(&rpc_match);
}

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (Darwin)

iD8DBQFGNRhHYmb/DX8rx/kRAsk6AJ0ZhDKRPXsYCUJFylP96Ck5cnRWcACg
prMg
Btki58qT98L/TzCMGqQC+N8=
=DnzY
-----END PGP SIGNATURE-----


[1]

about | contact  Other archives ( Real Estate discussion Medical topics )