]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-pom-ng-rsh.patch
- rel 3
[packages/kernel.git] / kernel-pom-ng-rsh.patch
1 diff -NurpP --minimal linux/include/net/netfilter/nf_conntrack.h linux/include/net/netfilter/nf_conntrack.h
2 --- linux/include/net/netfilter/nf_conntrack.h  2007-05-30 11:57:00.000000000 +0200
3 +++ linux/include/net/netfilter/nf_conntrack.h  2007-05-30 11:58:41.000000000 +0200
4 @@ -29,6 +29,7 @@ union nf_conntrack_expect_proto {
5  };
6  
7  /* Add protocol helper include file here */
8 +#include <linux/netfilter/nf_conntrack_rsh.h>
9  #include <linux/netfilter/nf_conntrack_ftp.h>
10  #include <linux/netfilter/nf_conntrack_pptp.h>
11  #include <linux/netfilter/nf_conntrack_h323.h>
12 @@ -73,6 +73,10 @@
13  #if defined(CONFIG_NF_NAT_MMS) || defined(CONFIG_NF_NAT_MMS_MODULE)
14         struct nf_ct_mms_master ct_mms_info;
15  #endif
16 +#if defined(CONFIG_NF_CONNTRACK_RSH) || defined(CONFIG_NF_CONNTRACK_RSH_MODULE)
17 +       struct nf_ct_rsh_master ct_rsh_info;
18 +#endif
19 +
20  };
21  
22  #include <linux/types.h>
23 diff -NurpP --minimal linux/include/linux/netfilter/nf_conntrack_rsh.h linux/include/linux/netfilter/nf_conntrack_rsh.h
24 --- linux/include/linux/netfilter/nf_conntrack_rsh.h    1970-01-01 01:00:00.000000000 +0100
25 +++ linux/include/linux/netfilter/nf_conntrack_rsh.h    2007-05-30 11:58:41.000000000 +0200
26 @@ -0,0 +1,28 @@
27 +/* RSH extension for IP connection tracking, Version 1.0
28 + * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
29 + * based on HW's ip_conntrack_irc.c     
30 + *
31 + * nf_conntrack_rsh.c,v 1.0 2002/07/17 14:49:26
32 + *
33 + *      This program is free software; you can redistribute it and/or
34 + *      modify it under the terms of the GNU General Public License
35 + *      as published by the Free Software Foundation; either version
36 + *      2 of the License, or (at your option) any later version.
37 + */
38 +#ifndef _IP_CONNTRACK_RSH_H
39 +#define _IP_CONNTRACK_RSH_H
40 +
41 +#define RSH_PORT       514
42 +
43 +/* This structure is per expected connection */
44 +struct nf_ct_rsh_expect
45 +{
46 +       u_int16_t port;
47 +};
48 +
49 +/* This structure exists only once per master */
50 +struct nf_ct_rsh_master {
51 +};
52 +
53 +#endif /* _IP_CONNTRACK_RSH_H */
54 +
55 diff -NurpP --minimal linux/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig
56 --- linux/net/ipv4/netfilter/Kconfig    2007-05-30 11:57:07.000000000 +0200
57 +++ linux/net/ipv4/netfilter/Kconfig    2007-05-30 11:58:41.000000000 +0200
58 @@ -870,5 +870,28 @@ config IP_NF_MMS
59           If you want to compile it as a module, say M here and read
60           <file:Documentation/modules.txt>.  If unsure, say `Y'.
61  
62 +config NF_CONNTRACK_RSH
63 +       tristate  'RSH protocol support'
64 +       depends on NF_CONNTRACK
65 +       help
66 +         The RSH connection tracker is required if the dynamic
67 +         stderr "Server to Client" connection is to occur during a
68 +         normal RSH session.  This typically operates as follows;
69 +       
70 +           Client 0:1023 --> Server 514    (stream 1 - stdin/stdout)
71 +           Client 0:1023 <-- Server 0:1023 (stream 2 - stderr)
72 +       
73 +         This connection tracker will identify new RSH sessions,
74 +         extract the outbound session details, and notify netfilter
75 +         of pending "related" sessions.
76 +       
77 +         Warning: This module could be dangerous. It is not "best
78 +                  practice" to use RSH, use SSH in all instances.
79 +                  (see rfc1244, rfc1948, rfc2179, etc ad-nauseum)
80 +       
81 +       
82 +         If you want to compile it as a module, say M here and read
83 +         <file:Documentation/modules.txt>.  If unsure, say `N'.
84 +
85  endmenu
86  
87 diff -NurpP --minimal linux/net/netfilter/Makefile linux/net/netfilter/Makefile
88 --- linux/net/netfilter/Makefile        2007-05-30 11:57:07.000000000 +0200
89 +++ linux/net/netfilter/Makefile        2007-05-30 11:58:41.000000000 +0200
90 @@ -0,0 +1 @@
91 +obj-$(CONFIG_NF_CONNTRACK_RSH) += nf_conntrack_rsh.o
92 diff -NurpP --minimal linux/net/netfilter/nf_conntrack_rsh.c linux/net/netfilter/nf_conntrack_rsh.c
93 --- linux/net/netfilter/nf_conntrack_rsh.c      1970-01-01 01:00:00.000000000 +0100
94 +++ linux/net/netfilter/nf_conntrack_rsh.c      2007-05-30 11:58:41.000000000 +0200
95 @@ -0,0 +1,361 @@
96 +/* RSH extension for IP connection tracking, Version 1.0
97 + * (C) 2002 by Ian (Larry) Latter <Ian.Latter@mq.edu.au>
98 + * based on HW's ip_conntrack_irc.c    
99 + *
100 + * (C) 2004,2005 by David Stes <stes@pandora.be>
101 + * Modification for Legato NetWorker range [7937-9936] instead of [0:1023]
102 + *
103 + * (C) 2005 by David Stes <stes@pandora.be>
104 + * Upgrade to 2.6.13 API
105 + *
106 + * ip_conntrack_rsh.c,v 1.0 2002/07/17 14:49:26
107 + *
108 + *      This program is free software; you can redistribute it and/or
109 + *      modify it under the terms of the GNU General Public License
110 + *      as published by the Free Software Foundation; either version
111 + *      2 of the License, or (at your option) any later version.
112 + **
113 + *     Module load syntax:
114 + *     insmod ip_conntrack_rsh.o range=1023,ports=port1,port2,...port<MAX_PORTS>
115 + *     
116 + *     please give the ports of all RSH servers You wish to connect to.
117 + *     If You don't specify ports, the default will be port 514
118 + **
119 + *      Note to all:
120 + *        RSH blows ... you should use SSH (openssh.org) to replace it,
121 + *        unfortunately I babysit some sysadmins that won't migrate
122 + *       their legacy crap, in our second tier.
123 + */
124 +
125 +
126 +/*
127 + *  Some docco ripped from the net to teach me all there is to know about
128 + *  RSH, in 16.5 seconds (ie, all of the non-netfilter docco used to write
129 + *  this module).
130 + *
131 + *  I have no idea what "unix rshd man pages" these guys have .. but that
132 + *  is some pretty detailed docco!
133 + **
134 + *
135 + *  4. Of the rsh protocol.
136 + *  -----------------------
137 + * 
138 + *   The rshd listens on TCP port #514. The following info is from the unix
139 + *   rshd man pages :
140 + * 
141 + *   "Service Request Protocol
142 + * 
143 + *    When the rshd daemon receives a service request, it initiates the
144 + *    following protocol:
145 + * 
146 + *     1. The rshd daemon checks the source port number for the request.
147 + *        If the port number is not in the range 0 through 1023, the rshd daemon
148 + *        terminates the connection.
149 + * 
150 + *     2. The rshd daemon reads characters from the socket up to a null byte.
151 + *        The string read is interpreted as an ASCII number (base 10). If this
152 + *        number is nonzero, the rshd daemon interprets it as the port number
153 + *        of a secondary stream to be used as standard error. A second connection
154 + *        is created to the specified port on the client host. The source port
155 + *        on the local host is in the range 0 through 1023.
156 + * 
157 + *     3. The rshd daemon uses the source address of the initial connection
158 + *        request to determine the name of the client host. If the name cannot
159 + *        be determined, the rshd daemon uses the dotted decimal representation
160 + *        of the client host's address.
161 + * 
162 + *     4. The rshd daemon retrieves the following information from the initial
163 + *        socket:
164 + * 
165 + *         * A null-terminated string of at most 16 bytes interpreted as
166 + *           the user name of the user on the client host.
167 + * 
168 + *         * A null-terminated string of at most 16 bytes interpreted as
169 + *           the user name to be used on the local server host.
170 + * 
171 + *         * Another null-terminated string interpreted as a command line
172 + *           to be passed to a shell on the local server host.
173 + * 
174 + *     5. The rshd daemon attempts to validate the user using the following steps:
175 + * 
176 + *         a. The rshd daemon looks up the local user name in the /etc/passwd
177 + *            file and tries to switch to the home directory (using the chdir
178 + *            subroutine). If either the lookup or the directory change fails,
179 + *            the rshd daemon terminates the connection.
180 + * 
181 + *         b. If the local user ID is a nonzero value, the rshd daemon searches
182 + *            the /etc/hosts.equiv file to see if the name of the client
183 + *            workstation is listed. If the client workstation is listed as an
184 + *            equivalent host, the rshd daemon validates the user.
185 + * 
186 + *         c. If the $HOME/.rhosts file exists, the rshd daemon tries to
187 + *            authenticate the user by checking the .rhosts file.
188 + * 
189 + *         d. If either the $HOME/.rhosts authentication fails or the
190 + *            client host is not an equivalent host, the rshd daemon
191 + *            terminates the connection.
192 + * 
193 + *     6. Once rshd validates the user, the rshd daemon returns a null byte
194 + *        on the initial connection and passes the command line to the user's
195 + *        local login shell. The shell then inherits the network connections
196 + *        established by the rshd daemon."
197 + * 
198 + */
199 +
200 +
201 +#include <linux/module.h>
202 +#include <linux/netfilter.h>
203 +#include <linux/ip.h>
204 +#include <net/checksum.h>
205 +#include <net/tcp.h>
206 +
207 +#include <linux/netfilter_ipv4/ip_tables.h>
208 +#include <net/netfilter/nf_conntrack_expect.h>
209 +#include <net/netfilter/nf_conntrack_helper.h>
210 +#include <linux/netfilter/nf_conntrack_rsh.h>
211 +
212 +#define MAX_PORTS 8
213 +static int range; /* defaults to = 1023 */
214 +static unsigned short rangemask; /* defaults to = 0xfc00 */
215 +static int ports[MAX_PORTS];
216 +static int ports_n_c = 0;
217 +
218 +MODULE_AUTHOR("Ian (Larry) Latter <Ian.Latter@mq.edu.au>");
219 +MODULE_DESCRIPTION("RSH connection tracking module");
220 +MODULE_LICENSE("GPL");
221 +#ifdef MODULE_PARM
222 +module_param(range, int, 0400);
223 +MODULE_PARM_DESC(range, "max port of reserved range (default is 1023)");
224 +module_param_array(ports, int, &ports_n_c, 0400);
225 +MODULE_PARM_DESC(ports, "port numbers of RSH servers");
226 +#endif
227 +
228 +static DEFINE_SPINLOCK(rsh_buffer_lock);
229 +static char rsh_buffer[65535];
230 +
231 +unsigned int (*ip_nat_rsh_hook)(struct sk_buff **pskb,
232 +                               enum ip_conntrack_info ctinfo,
233 +                               unsigned int matchoff,
234 +                               struct nf_conntrack_expect *exp);
235 +
236 +#define PRINTK(format, args...) printk(KERN_DEBUG "ip_conntrack_rsh: " \
237 +                                       format, ## args)
238 +
239 +#if 0
240 +#define DEBUGP(format, args...) printk(KERN_DEBUG "ip_conntrack_rsh: " \
241 +                                       format, ## args)
242 +#else
243 +#define DEBUGP(format, args...)
244 +#endif
245 +
246 +#define NIPQUAD(addr) \
247 +       ((unsigned char *)&addr)[0], \
248 +       ((unsigned char *)&addr)[1], \
249 +       ((unsigned char *)&addr)[2], \
250 +       ((unsigned char *)&addr)[3]
251 +
252 +/* FIXME: This should be in userspace.  Later. */
253 +static int help(struct sk_buff **pskb,
254 +               struct nf_conn *ct, enum ip_conntrack_info ctinfo)
255 +{
256 +       struct tcphdr _tcph, *th;
257 +       char *data, *rb_ptr;
258 +       int ret = NF_ACCEPT;
259 +       int dir = CTINFO2DIR(ctinfo);
260 +        struct nf_conntrack_expect *exp;
261 +       unsigned int dataoff, datalen;
262 +       u_int16_t port;
263 +       int maxoctet = 4;
264 +
265 +       /*  note that "maxoctet" is used to maintain sanity (8 was the
266 +        *  original array size used in rshd/glibc) -- is there a
267 +        *  vulnerability in rshd.c in the looped port *= 10?
268 +        */
269 +
270 +       DEBUGP("entered\n");
271 +
272 +       /* bail if packet is not from RSH client */
273 +       if (dir == IP_CT_DIR_REPLY) {
274 +               return NF_ACCEPT; 
275 +       }
276 +
277 +       /* Until there's been traffic both ways, don't look in packets. */
278 +       if (ctinfo != IP_CT_ESTABLISHED
279 +           && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
280 +               DEBUGP("Conntrackinfo = %u\n", ctinfo);
281 +               return NF_ACCEPT;
282 +       }
283 +
284 +       /* Not a full tcp header? */
285 +       th = skb_header_pointer(*pskb, ip_hdr(*pskb)->ihl*4,
286 +                               sizeof(_tcph), &_tcph);
287 +       if (!th) {
288 +               DEBUGP("rsh: skb_header_pointer null\n");
289 +               return NF_ACCEPT;
290 +       }
291 +
292 +       /* No data? */
293 +       dataoff = ip_hdr(*pskb)->ihl*4 + th->doff*4;
294 +       if (dataoff >= (*pskb)->len) {
295 +               return NF_ACCEPT;
296 +       }
297 +       datalen = (*pskb)->len - dataoff;
298 +       spin_lock_bh(&rsh_buffer_lock);
299 +       rb_ptr = skb_header_pointer(*pskb, dataoff, datalen, rsh_buffer);
300 +       BUG_ON(rb_ptr == NULL);
301 +       data = rb_ptr;
302 +
303 +       DEBUGP("rsh: find rsh stderr port datalen %u\n",datalen);
304 +
305 +       maxoctet = 5;
306 +       port = 0;
307 +       for ( ; *data != 0 && maxoctet != 0; data++, maxoctet--) {
308 +               if (*data < 0) {
309 +                       ret = 1; goto out;
310 +               }
311 +               if (*data == 0) {
312 +                       break;
313 +               }
314 +               if (*data < 48 || *data > 57) {
315 +                       DEBUGP("these aren't the packets you're looking for ..\n");
316 +                       ret = NF_ACCEPT; goto out;
317 +               }
318 +               port = port * 10 + ( *data - 48 );
319 +       }
320 +
321 +       /* dont relate sessions that try to expose the client */
322 +       if (port == 0) {
323 +           DEBUGP("skipping, port is 0!\n");
324 +          ret = NF_ACCEPT;goto out;
325 +       }
326 +
327 +       DEBUGP("found port %u\n", port);
328 +       if (port > range) {
329 +               DEBUGP("skipping, expected port size is greater than range!\n");
330 +               return NF_ACCEPT;
331 +       }
332 +
333 +       exp = nf_ct_expect_alloc(ct);
334 +       if (!exp) {
335 +               ret = NF_DROP;
336 +               goto out;
337 +       }
338 +
339 +       /*  new(,related) connection is;
340 +        *          reply + dst (uint)port + src port (0:1023)
341 +        */
342 +
343 +       /* Watch out, Radioactive-Man! */
344 +       exp->tuple.src.u3.ip = ct->tuplehash[!dir].tuple.src.u3.ip;
345 +       exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
346 +       exp->tuple.src.u.tcp.port = 0;
347 +       exp->tuple.dst.u.tcp.port = htons(port);
348 +       exp->tuple.dst.protonum = IPPROTO_TCP;
349 +
350 +       exp->mask.src.u3.ip = 0xffffffff;
351 +
352 +       exp->mask.src.u.tcp.port = htons(rangemask);
353 +
354 +       exp->expectfn = NULL;
355 +       exp->master = ct;
356 +
357 +       DEBUGP("expect related ip   %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
358 +               NIPQUAD(exp->tuple.src.ip),
359 +               ntohs(exp->tuple.src.u.tcp.port),
360 +               NIPQUAD(exp->tuple.dst.ip),
361 +               ntohs(exp->tuple.dst.u.tcp.port));
362 +
363 +       if (ip_nat_rsh_hook)
364 +               ret = ip_nat_rsh_hook(pskb, ctinfo, rb_ptr - data, exp);
365 +       else if (nf_ct_expect_related(exp) != 0) {
366 +               ret = NF_DROP;
367 +       }
368 +
369 +       nf_ct_expect_put(exp);
370 +
371 +out:
372 +       spin_unlock_bh(&rsh_buffer_lock);
373 +       return ret;
374 +}
375 +
376 +static struct nf_conntrack_helper rsh_helpers[MAX_PORTS];
377 +static char rsh_names[MAX_PORTS][10];
378 +static const struct nf_conntrack_expect_policy rsh_exp_policy = {
379 +       .max_expected      = 1,
380 +       .timeout      = 5, /* stes bug timeout=0 */
381 +};
382 +
383 +static void fini(void);
384 +
385 +static int __init init(void)
386 +{
387 +       int port, ret;
388 +       char *tmpname;
389 +
390 +       /* If no port given, default to standard RSH port */
391 +       if (ports[0] == 0)
392 +               ports[0] = RSH_PORT;
393 +
394 +       /* the check on reserved port <1023 doesn't work with Legato */
395 +        /* for Legato NetWorker, the check should be that port <= 9936 */ 
396 +
397 +        if (range == 0) 
398 +               range = 1023;
399 +
400 +       /* Legato uses range [ 7937 : 9936 ] -> 7937 by default */
401 +
402 +        rangemask = 0xffff ^ range; /* defaults to = 0xfc00 */
403 +
404 +       for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
405 +               memset(&rsh_helpers[port], 0, sizeof(struct nf_conntrack_helper));
406 +
407 +               tmpname = &rsh_names[port][0];
408 +               if (ports[port] == RSH_PORT)
409 +                       sprintf(tmpname, "rsh");
410 +               else
411 +                       sprintf(tmpname, "rsh-%d", ports[port]);
412 +               rsh_helpers[port].name = tmpname;
413 +
414 +               rsh_helpers[port].me = THIS_MODULE;
415 +               rsh_helpers[port].expect_policy = &rsh_exp_policy;
416 +
417 +               rsh_helpers[port].tuple.dst.protonum = IPPROTO_TCP;
418 +
419 +               /* RSH must come from ports 0:1023 to ports[port] (514) */
420 +               rsh_helpers[port].tuple.src.u.tcp.port = htons(ports[port]);
421 +
422 +               rsh_helpers[port].help = help;
423 +
424 +               PRINTK("registering helper for port #%d: %d/TCP\n", port, ports[port]);
425 +               PRINTK("helper match ip   %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n",
426 +                       NIPQUAD(rsh_helpers[port].tuple.src.u3.ip),
427 +                       ntohs(rsh_helpers[port].tuple.src.u.tcp.port),
428 +                       NIPQUAD(rsh_helpers[port].tuple.dst.u3.ip),
429 +                       ntohs(rsh_helpers[port].tuple.dst.u.tcp.port));
430 +
431 +               ret = nf_conntrack_helper_register(&rsh_helpers[port]);
432 +
433 +               if (ret) {
434 +                       printk("ERROR registering port %d\n",
435 +                               ports[port]);
436 +                       fini();
437 +                       return -EBUSY;
438 +               }
439 +               ports_n_c++;
440 +       }
441 +       return 0;
442 +}
443 +
444 +/* This function is intentionally _NOT_ defined as __exit, because 
445 + * it is needed by the init function */
446 +static void fini(void)
447 +{
448 +       int port;
449 +       for (port = 0; (port < MAX_PORTS) && ports[port]; port++) {
450 +               DEBUGP("unregistering port %d\n", ports[port]);
451 +               nf_conntrack_helper_unregister(&rsh_helpers[port]);
452 +       }
453 +}
454 +
455 +module_init(init);
456 +module_exit(fini);
This page took 0.056259 seconds and 3 git commands to generate.