Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/netinet Pull up revisions 1.18-1.21 (via patch, req...



details:   https://anonhg.NetBSD.org/src/rev/2962ba43372a
branches:  netbsd-1-5
changeset: 492712:2962ba43372a
user:      he <he%NetBSD.org@localhost>
date:      Sat Feb 09 16:58:52 2002 +0000

description:
Pull up revisions 1.18-1.21 (via patch, requested by martti):
  Updated IPFilter to 3.4.23.

diffstat:

 sys/netinet/ip_ftp_pxy.c |  274 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 208 insertions(+), 66 deletions(-)

diffs (truncated from 540 to 300 lines):

diff -r f9b96a0bd3a8 -r 2962ba43372a sys/netinet/ip_ftp_pxy.c
--- a/sys/netinet/ip_ftp_pxy.c  Sat Feb 09 16:58:31 2002 +0000
+++ b/sys/netinet/ip_ftp_pxy.c  Sat Feb 09 16:58:52 2002 +0000
@@ -1,10 +1,13 @@
-/*     $NetBSD: ip_ftp_pxy.c,v 1.16.4.2 2001/04/05 12:53:33 he Exp $   */
+/*     $NetBSD: ip_ftp_pxy.c,v 1.16.4.3 2002/02/09 16:58:52 he Exp $   */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: ip_ftp_pxy.c,v 1.16.4.3 2002/02/09 16:58:52 he Exp $");
 
 /*
  * Simple FTP transparent proxy for in-kernel use.  For use with the NAT
  * code.
  *
- * Id: ip_ftp_pxy.c,v 2.7.2.13 2000/08/07 12:35:27 darrenr Exp
+ * Id: ip_ftp_pxy.c,v 2.7.2.31 2002/01/09 09:30:04 darrenr Exp
  */
 #if SOLARIS && defined(_KERNEL)
 extern kmutex_t        ipf_rw;
@@ -24,6 +27,22 @@
 #define        IPF_MAX227LEN   51
 #define        IPF_FTPBUFSZ    96      /* This *MUST* be >= 53! */
 
+#define        FTPXY_GO        0
+#define        FTPXY_INIT      1
+#define        FTPXY_USER_1    2
+#define        FTPXY_USOK_1    3
+#define        FTPXY_PASS_1    4
+#define        FTPXY_PAOK_1    5
+#define        FTPXY_AUTH_1    6
+#define        FTPXY_AUOK_1    7
+#define        FTPXY_ADAT_1    8
+#define        FTPXY_ADOK_1    9
+#define        FTPXY_ACCT_1    10
+#define        FTPXY_ACOK_1    11
+#define        FTPXY_USER_2    12
+#define        FTPXY_USOK_2    13
+#define        FTPXY_PASS_2    14
+#define        FTPXY_PAOK_2    15
 
 int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
 int ippr_ftp_complete __P((char *, size_t));
@@ -35,10 +54,12 @@
 int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int));
 int ippr_ftp_process __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
 int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int));
-int ippr_ftp_valid __P((char *, size_t));
+int ippr_ftp_valid __P((int, char *, size_t));
+int ippr_ftp_server_valid __P((char *, size_t));
+int ippr_ftp_client_valid __P((char *, size_t));
 u_short ippr_ftp_atoi __P((char **));
 
-static frentry_t       natfr;
+static frentry_t       ftppxyfr;
 int    ippr_ftp_pasvonly = 0;
 int    ippr_ftp_insecure = 0;
 
@@ -48,9 +69,9 @@
  */
 int ippr_ftp_init()
 {
-       bzero((char *)&natfr, sizeof(natfr));
-       natfr.fr_ref = 1;
-       natfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
+       bzero((char *)&ftppxyfr, sizeof(ftppxyfr));
+       ftppxyfr.fr_ref = 1;
+       ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
        return 0;
 }
 
@@ -77,6 +98,7 @@
        f = &ftp->ftp_side[1];
        f->ftps_rptr = f->ftps_buf;
        f->ftps_wptr = f->ftps_buf;
+       ftp->ftp_passok = FTPXY_INIT;
        return 0;
 }
 
@@ -90,9 +112,9 @@
 {
        tcphdr_t *tcp, tcph, *tcp2 = &tcph;
        char newbuf[IPF_FTPBUFSZ], *s;
-       u_short a5, a6, sp, dp;
        u_int a1, a2, a3, a4;
        struct in_addr swip;
+       u_short a5, a6, sp;
        size_t nlen, olen;
        fr_info_t fi;
        int inc, off;
@@ -148,6 +170,7 @@
        } else
                return 0;
        a5 >>= 8;
+       a5 &= 0xff;
        /*
         * Calculate new address parts for PORT command
         */
@@ -157,7 +180,7 @@
        a4 = a1 & 0xff;
        a1 >>= 24;
        olen = s - f->ftps_rptr;
-       /* DO NOT change this to sprintf! */
+       /* DO NOT change this to snprintf! */
        (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
                       "PORT", a1, a2, a3, a4, a5, a6);
 
@@ -205,7 +228,7 @@
 #endif
        if (inc != 0) {
 #if SOLARIS || defined(__sgi)
-               u_32_t  sum1, sum2;
+               register u_32_t sum1, sum2;
 
                sum1 = ip->ip_len;
                sum2 = ip->ip_len + inc;
@@ -216,7 +239,7 @@
                sum2 -= sum1;
                sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 
-               fix_outcksum(&ip->ip_sum, sum2, 0);
+               fix_outcksum(fin, &ip->ip_sum, sum2);
 #endif
                ip->ip_len += inc;
        }
@@ -225,42 +248,47 @@
         * Add skeleton NAT entry for connection which will come back the
         * other way.
         */
-       sp = htons(a5 << 8 | a6);
+       sp = (a5 << 8 | a6);
        /*
         * Don't allow the PORT command to specify a port < 1024 due to
         * security crap.
         */
-       if (ntohs(sp) < 1024)
+       if (sp < 1024)
                return 0;
        /*
         * The server may not make the connection back from port 20, but
         * it is the most likely so use it here to check for a conflicting
         * mapping.
         */
-       dp = htons(fin->fin_data[1] - 1);
-       ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
-                           ip->ip_dst, (dp << 16) | sp);
+       bcopy((char *)fin, (char *)&fi, sizeof(fi));
+       fi.fin_data[0] = sp;
+       fi.fin_data[1] = fin->fin_data[1] - 1;
+       ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+                           ip->ip_dst, 0);
        if (ipn == NULL) {
                int slen;
 
                slen = ip->ip_len;
                ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
-               bcopy((char *)fin, (char *)&fi, sizeof(fi));
                bzero((char *)tcp2, sizeof(*tcp2));
                tcp2->th_win = htons(8192);
-               tcp2->th_sport = sp;
+               tcp2->th_sport = htons(sp);
                tcp2->th_off = 5;
                tcp2->th_dport = 0; /* XXX - don't specify remote port */
-               fi.fin_data[0] = ntohs(sp);
                fi.fin_data[1] = 0;
+               fi.fin_dlen = sizeof(*tcp2);
                fi.fin_dp = (char *)tcp2;
+               fi.fin_fr = &ftppxyfr;
+               fi.fin_out = 1;
                swip = ip->ip_src;
+               fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
                ip->ip_src = nat->nat_inip;
-               ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT,
+               ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
                              NAT_OUTBOUND);
                if (ipn != NULL) {
                        ipn->nat_age = fr_defnatage;
-                       (void) fr_addstate(ip, &fi, FI_W_DPORT);
+                       (void) fr_addstate(ip, &fi, NULL,
+                                          FI_W_DPORT|FI_IGNOREPKT);
                }
                ip->ip_len = slen;
                ip->ip_src = swip;
@@ -295,11 +323,36 @@
        }
        cmd[i] = '\0';
 
-       if ((ftp->ftp_passok == 0) && !strncmp(cmd, "USER ", 5))
-                ftp->ftp_passok = 1;
-       else if ((ftp->ftp_passok == 2) && !strncmp(cmd, "PASS ", 5))
-                ftp->ftp_passok = 3;
-       else if ((ftp->ftp_passok == 4) && !ippr_ftp_pasvonly &&
+       ftp->ftp_incok = 0;
+       if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) {
+               if (ftp->ftp_passok == FTPXY_ADOK_1 ||
+                   ftp->ftp_passok == FTPXY_AUOK_1) {
+                       ftp->ftp_passok = FTPXY_USER_2;
+                       ftp->ftp_incok = 1;
+               } else {
+                       ftp->ftp_passok = FTPXY_USER_1;
+                       ftp->ftp_incok = 1;
+               }
+       } else if (!strncmp(cmd, "AUTH ", 5)) {
+               ftp->ftp_passok = FTPXY_AUTH_1;
+               ftp->ftp_incok = 1;
+       } else if (!strncmp(cmd, "PASS ", 5)) {
+               if (ftp->ftp_passok == FTPXY_USOK_1) {
+                       ftp->ftp_passok = FTPXY_PASS_1;
+                       ftp->ftp_incok = 1;
+               } else if (ftp->ftp_passok == FTPXY_USOK_2) {
+                       ftp->ftp_passok = FTPXY_PASS_2;
+                       ftp->ftp_incok = 1;
+               }
+       } else if ((ftp->ftp_passok == FTPXY_AUOK_1) &&
+                  !strncmp(cmd, "ADAT ", 5)) {
+               ftp->ftp_passok = FTPXY_ADAT_1;
+               ftp->ftp_incok = 1;
+       } else if ((ftp->ftp_passok == FTPXY_PAOK_2) &&
+                !strncmp(cmd, "ACCT ", 5)) {
+               ftp->ftp_passok = FTPXY_ACCT_1;
+               ftp->ftp_incok = 1;
+       } else if ((ftp->ftp_passok == FTPXY_GO) && !ippr_ftp_pasvonly &&
                 !strncmp(cmd, "PORT ", 5)) {
                inc = ippr_ftp_port(fin, ip, nat, f, dlen);
        } else if (ippr_ftp_insecure && !ippr_ftp_pasvonly &&
@@ -330,12 +383,13 @@
        int inc;
        char *s;
 
+#define        PASV_REPLEN     24
        /*
         * Check for PASV reply message.
         */
        if (dlen < IPF_MIN227LEN)
                return 0;
-       else if (strncmp(f->ftps_rptr, "227 Entering Passive Mode", 25))
+       else if (strncmp(f->ftps_rptr, "227 Entering Passive Mod", PASV_REPLEN))
                return 0;
 
        tcp = (tcphdr_t *)fin->fin_dp;
@@ -343,7 +397,7 @@
        /*
         * Skip the PORT command + space
         */
-       s = f->ftps_rptr + 25;
+       s = f->ftps_rptr + PASV_REPLEN;
        while (*s && !isdigit(*s))
                s++;
        /*
@@ -371,6 +425,8 @@
 
        if (*s == ')')
                s++;
+       if (*s == '.')
+               s++;
        if (*s == '\n')
                s--;
        /*
@@ -432,7 +488,7 @@
 #endif /* SOLARIS */
        if (inc != 0) {
 #if SOLARIS || defined(__sgi)
-               u_32_t  sum1, sum2;
+               register u_32_t sum1, sum2;
 
                sum1 = ip->ip_len;
                sum2 = ip->ip_len + inc;
@@ -443,7 +499,7 @@
                sum2 -= sum1;
                sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 
-               fix_outcksum(&ip->ip_sum, sum2, 0);
+               fix_outcksum(fin, &ip->ip_sum, sum2);
 #endif /* SOLARIS || defined(__sgi) */
                ip->ip_len += inc;
        }
@@ -453,33 +509,41 @@
         * Add skeleton NAT entry for connection which will come back the
         * other way.
         */
+       bcopy((char *)fin, (char *)&fi, sizeof(fi));
        sp = 0;
+       fi.fin_data[0] = 0;
        dp = htons(fin->fin_data[1] - 1);
-       ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip,
-                           ip->ip_dst, (dp << 16) | sp);
+       fi.fin_data[1] = ntohs(dp);
+       ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
+                           ip->ip_dst, 0);
        if (ipn == NULL) {
                int slen;
 
                slen = ip->ip_len;
                ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
-               bcopy((char *)fin, (char *)&fi, sizeof(fi));
                bzero((char *)tcp2, sizeof(*tcp2));
                tcp2->th_win = htons(8192);
                tcp2->th_sport = 0;             /* XXX - fake it for nat_new */
                tcp2->th_off = 5;
                fi.fin_data[0] = a5 << 8 | a6;
+               fi.fin_dlen = sizeof(*tcp2);



Home | Main Index | Thread Index | Old Index