ip_ftp_pxy.c revision 33f2fefd46350ca5992567761c46a5b70f864340
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (C) 1997-2003 by Darren Reed
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the IPFILTER.LICENCE file for details on licencing.
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling *
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * $Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp $
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Simple FTP transparent proxy for in-kernel use. For use with the NAT
fa9e4066f08beec538e775443c5be79dd423fcabahrens * code.
fa9e4066f08beec538e775443c5be79dd423fcabahrens*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_FTP_PROXY
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_MINPORTLEN 18
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_MAXPORTLEN 30
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_MIN227LEN 39
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_MAX227LEN 51
99653d4ee642c6528e88224f12409a5f23060994eschrock#define IPF_MIN229LEN 47
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define IPF_MAX229LEN 51
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
ce72e614c133351311e87bbbe4eba8fea9e77768Yuri Pankov#define FTPXY_GO 0
e42d205944d245bf5d1c4fc45261cbe09e28a7b9Matthew Ahrens#define FTPXY_INIT 1
e1d5e507a890a0408b8299bf95cad4678fc2390eFrederik Wessels#define FTPXY_USER_1 2
9edf9ebd727ac2046be0269a5e275785e2131bcbPrasad Joshi#define FTPXY_USOK_1 3
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_PASS_1 4
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_PAOK_1 5
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_AUTH_1 6
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_AUOK_1 7
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_ADAT_1 8
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_ADOK_1 9
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_ACCT_1 10
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_ACOK_1 11
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_USER_2 12
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_USOK_2 13
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_PASS_2 14
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_PAOK_2 15
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Values for FTP commands. Numerics cover 0-999
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define FTPXY_C_PASV 1000
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarkstypedef struct ifs_ftppxy {
4263d13f00c9691fa14620eff82abef795be0693George Wilson frentry_t ftppxyfr;
b1b8ab34de515a5e83206da22c3d7e563241b021lling int ftp_proxy_init;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ippr_ftp_pasvonly;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ippr_ftp_insecure;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Do not require logins before transfers */
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ippr_ftp_pasvrdr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ippr_ftp_forcepasv;
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin /* PASV must be last command prior to 227 */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1 - security
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems * 2 - errors
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems * 3 - error debugging
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 4 - parsing errors
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 5 - parsing info
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 6 - parsing debug
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock int ippr_ftp_debug;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ipftuneable_t ftptune;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} ifs_ftppxy_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_complete __P((char *, size_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_in __P((fr_info_t *, ap_session_t *, nat_t *, void *));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockint ippr_ftp_init __P((void **, ipf_stack_t *));
4263d13f00c9691fa14620eff82abef795be0693George Wilsonvoid ippr_ftp_fini __P((void **, ipf_stack_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_new __P((fr_info_t *, ap_session_t *, nat_t *, void *));
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amoreint ippr_ftp_out __P((fr_info_t *, ap_session_t *, nat_t *, void *));
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amoreint ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_epsv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musanteint ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_process __P((fr_info_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *));
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_valid __P((ftpinfo_t *, int, char *, size_t, ifs_ftppxy_t *));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockint ippr_ftp_server_valid __P((ftpside_t *, char *, size_t, ifs_ftppxy_t *));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockint ippr_ftp_client_valid __P((ftpside_t *, char *, size_t, ifs_ftppxy_t *));
06eeb2ad640ce72d394ac521094bed7681044408eku_short ippr_ftp_atoi __P((char **));
06eeb2ad640ce72d394ac521094bed7681044408ekint ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *,
b1b8ab34de515a5e83206da22c3d7e563241b021lling u_int, char *, char *, u_int, ifs_ftppxy_t *));
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize local structures.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_init(private, ifs)
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid **private;
29ab75c9a733dad2978c4860efd954b5625e3467rmipf_stack_t *ifs;
29ab75c9a733dad2978c4860efd954b5625e3467rm{
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifs_ftppxy_t *ifsftp;
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens KMALLOC(ifsftp, ifs_ftppxy_t *);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens bzero((char *)&ifsftp->ftppxyfr, sizeof(ifsftp->ftppxyfr));
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ftppxyfr.fr_ref = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens MUTEX_INIT(&ifsftp->ftppxyfr.fr_lock, "FTP Proxy Mutex");
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ftp_proxy_init = 1;
29ab75c9a733dad2978c4860efd954b5625e3467rm ifsftp->ippr_ftp_pasvonly = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ippr_ftp_insecure = 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ippr_ftp_pasvrdr = 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ippr_ftp_forcepasv = 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock#if defined(_KERNEL)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock ifsftp->ippr_ftp_debug = 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock#else
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ippr_ftp_debug = 2;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock#endif
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock bzero((char *)&ifsftp->ftptune, sizeof(ifsftp->ftptune));
06eeb2ad640ce72d394ac521094bed7681044408ek ifsftp->ftptune.ipft_pint = (uint_t *)&ifsftp->ippr_ftp_debug;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ftptune.ipft_name = "ippr_ftp_debug";
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ftptune.ipft_max = 10;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ftptune.ipft_sz = sizeof(ifsftp->ippr_ftp_debug);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ftptune.ipft_next = NULL;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock (void) fr_addipftune(&ifsftp->ftptune, ifs);
99653d4ee642c6528e88224f12409a5f23060994eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock *private = (void *)ifsftp;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
b1b8ab34de515a5e83206da22c3d7e563241b021lling return 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
4263d13f00c9691fa14620eff82abef795be0693George Wilsonvoid ippr_ftp_fini(private, ifs)
4263d13f00c9691fa14620eff82abef795be0693George Wilsonvoid **private;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrockipf_stack_t *ifs;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock{
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifs_ftppxy_t *ifsftp = *((ifs_ftppxy_t **)private);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fr_delipftune(&ifsftp->ftptune, ifs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (ifsftp->ftp_proxy_init == 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens MUTEX_DESTROY(&ifsftp->ftppxyfr.fr_lock);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ftp_proxy_init = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock KFREE(ifsftp);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock *private = NULL;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock}
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_new(fin, aps, nat, private)
fa9e4066f08beec538e775443c5be79dd423fcabahrensfr_info_t *fin;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrockap_session_t *aps;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrocknat_t *nat;
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid *private;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock ftpinfo_t *ftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftpside_t *f;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock KMALLOC(ftp, ftpinfo_t *);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (ftp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return -1;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock fin = fin; /* LINT */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock nat = nat; /* LINT */
4263d13f00c9691fa14620eff82abef795be0693George Wilson
fa9e4066f08beec538e775443c5be79dd423fcabahrens aps->aps_data = ftp;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock aps->aps_psiz = sizeof(ftpinfo_t);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock bzero((char *)ftp, sizeof(*ftp));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante f = &ftp->ftp_side[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_rptr = f->ftps_buf;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock f->ftps_wptr = f->ftps_buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f = &ftp->ftp_side[1];
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock f->ftps_rptr = f->ftps_buf;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock f->ftps_wptr = f->ftps_buf;
06eeb2ad640ce72d394ac521094bed7681044408ek ftp->ftp_passok = FTPXY_INIT;
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore ftp->ftp_incok = 0;
06eeb2ad640ce72d394ac521094bed7681044408ek return 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_port(fin, ip, nat, f, dlen, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrensfr_info_t *fin;
fa9e4066f08beec538e775443c5be79dd423fcabahrensip_t *ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrensnat_t *nat;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrensftpside_t *f;
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ekint dlen;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrensifs_ftppxy_t *ifsftp;
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems{
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems tcphdr_t *tcp, tcph, *tcp2 = &tcph;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock char newbuf[IPF_FTPBUFSZ], *s;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock struct in_addr swip, swip2;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock u_int a1, a2, a3, a4;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock int inc, off, flags;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock u_short a5, a6, sp;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock size_t nlen, olen;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock fr_info_t fi;
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens nat_t *nat2;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock mb_t *m;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley ipf_stack_t *ifs = fin->fin_ifs;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden m = fin->fin_m;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh tcp = (tcphdr_t *)fin->fin_dp;
990b4856d0eaada6f8140335733a1b1771ed2746lling off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock /*
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * Check for client sending out PORT message.
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (dlen < IPF_MINPORTLEN) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (ifsftp->ippr_ftp_debug > 1)
06eeb2ad640ce72d394ac521094bed7681044408ek printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks dlen);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return 0;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm }
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson /*
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * Skip the PORT command + space
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson */
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson s = f->ftps_rptr + 5;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock /*
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson * Pick out the address components, two at a time.
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson */
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson a1 = ippr_ftp_atoi(&s);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (s == NULL) {
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems if (ifsftp->ippr_ftp_debug > 1)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 1);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return 0;
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling a2 = ippr_ftp_atoi(&s);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (s == NULL) {
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling if (ifsftp->ippr_ftp_debug > 1)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2);
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling return 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock }
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * Check that IP address in the PORT/PASV reply is the same as the
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * sender of the command - prevents using PORT for port scanning.
4263d13f00c9691fa14620eff82abef795be0693George Wilson */
31d7e8fa33fae995f558673adb22641b5aa8b6e1George Wilson a1 <<= 16;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock a1 |= a2;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (((nat->nat_dir == NAT_OUTBOUND) &&
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock (a1 != ntohl(nat->nat_inip.s_addr))) ||
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ((nat->nat_dir == NAT_INBOUND) &&
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (a1 != ntohl(nat->nat_oip.s_addr)))) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (ifsftp->ippr_ftp_debug > 0)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1");
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return APR_ERR(1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko a5 = ippr_ftp_atoi(&s);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko if (s == NULL) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (ifsftp->ippr_ftp_debug > 1)
b1b8ab34de515a5e83206da22c3d7e563241b021lling printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (*s == ')')
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante s++;
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore /*
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * check for CR-LF at the end.
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (*s == '\n')
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock s--;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if ((*s == '\r') && (*(s + 1) == '\n')) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock s += 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a6 = a5 & 0xff;
b1b8ab34de515a5e83206da22c3d7e563241b021lling } else {
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (ifsftp->ippr_ftp_debug > 1)
b1b8ab34de515a5e83206da22c3d7e563241b021lling printf("ippr_ftp_port:missing %s\n", "cr-lf");
990b4856d0eaada6f8140335733a1b1771ed2746lling return 0;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling a5 >>= 8;
b1b8ab34de515a5e83206da22c3d7e563241b021lling a5 &= 0xff;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sp = a5 << 8 | a6;
b1b8ab34de515a5e83206da22c3d7e563241b021lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Don't allow the PORT command to specify a port < 1024 due to
990b4856d0eaada6f8140335733a1b1771ed2746lling * security crap.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (sp < 1024) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (ifsftp->ippr_ftp_debug > 0)
b1b8ab34de515a5e83206da22c3d7e563241b021lling printf("ippr_ftp_port:sp(%d) < 1024\n", sp);
b1b8ab34de515a5e83206da22c3d7e563241b021lling return 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling /*
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Calculate new address parts for PORT command
990b4856d0eaada6f8140335733a1b1771ed2746lling */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (nat->nat_dir == NAT_INBOUND)
b1b8ab34de515a5e83206da22c3d7e563241b021lling a1 = ntohl(nat->nat_oip.s_addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 = ntohl(ip->ip_src.s_addr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens a2 = (a1 >> 16) & 0xff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a3 = (a1 >> 8) & 0xff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a4 = a1 & 0xff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 >>= 24;
99653d4ee642c6528e88224f12409a5f23060994eschrock olen = s - f->ftps_rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* DO NOT change this to snprintf! */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if defined(SNPRINTF) && defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) SNPRINTF(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "PORT", a1, a2, a3, a4, a5, a6);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "PORT", a1, a2, a3, a4, a5, a6);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens nlen = strlen(newbuf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = nlen - olen;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((inc + ip->ip_len) > 65535) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if !defined(_KERNEL)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock bcopy(newbuf, MTOD(m, char *) + off, nlen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens# if defined(MENTAT)
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (inc < 0)
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void)adjmsg(m, inc);
990b4856d0eaada6f8140335733a1b1771ed2746lling# else /* defined(MENTAT) */
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
b1b8ab34de515a5e83206da22c3d7e563241b021lling * m_adj takes care of pkthdr.len, if required and treats inc<0 to
b1b8ab34de515a5e83206da22c3d7e563241b021lling * mean remove -len bytes from the end of the packet.
b1b8ab34de515a5e83206da22c3d7e563241b021lling * The mbuf chain will be extended if necessary by m_copyback().
b1b8ab34de515a5e83206da22c3d7e563241b021lling */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (inc < 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling m_adj(m, inc);
b1b8ab34de515a5e83206da22c3d7e563241b021lling# endif /* defined(MENTAT) */
b1b8ab34de515a5e83206da22c3d7e563241b021lling#endif /* !defined(_KERNEL) */
990b4856d0eaada6f8140335733a1b1771ed2746lling COPYBACK(m, off, nlen, newbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (inc != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ip->ip_len += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fin->fin_dlen += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fin->fin_plen += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
b1b8ab34de515a5e83206da22c3d7e563241b021lling /*
b1b8ab34de515a5e83206da22c3d7e563241b021lling * The server may not make the connection back from port 20, but
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * it is the most likely so use it here to check for a conflicting
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * mapping.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock */
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock bcopy((char *)fin, (char *)&fi, sizeof(fi));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock fi.fin_flx |= FI_IGNORE;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock fi.fin_data[0] = sp;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock fi.fin_data[1] = fin->fin_data[1] - 1;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add skeleton NAT entry for connection which will come back the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * other way.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nat->nat_dir == NAT_OUTBOUND)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin nat->nat_inip, nat->nat_oip);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat->nat_inip, nat->nat_oip);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock if (nat2 == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int slen;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens slen = ip->ip_len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens bzero((char *)tcp2, sizeof(*tcp2));
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcp2->th_win = htons(8192);
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcp2->th_sport = htons(sp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens TCP_OFF_A(tcp2, 5);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock tcp2->th_flags = TH_SYN;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin tcp2->th_dport = 0; /* XXX - don't specify remote port */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_data[1] = 0;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_dlen = sizeof(*tcp2);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_plen = fi.fin_hlen + sizeof(*tcp2);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_dp = (char *)tcp2;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_fr = &ifsftp->ftppxyfr;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin fi.fin_out = nat->nat_dir;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin swip = ip->ip_src;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin swip2 = ip->ip_dst;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock if (nat->nat_dir == NAT_OUTBOUND) {
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_src = nat->nat_inip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (nat->nat_dir == NAT_INBOUND) {
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden fi.fin_fi.fi_saddr = nat->nat_oip.s_addr;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden ip->ip_src = nat->nat_oip;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden }
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden flags = NAT_SLAVE|IPN_TCP|SI_W_DPORT;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden if (nat->nat_dir == NAT_INBOUND)
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden flags |= NAT_NOTRULEPORT;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden nat2 = nat_new(&fi, nat->nat_ptr, NULL, flags, nat->nat_dir);
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden if (nat2 != NULL) {
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden (void) nat_proto(&fi, nat2, IPN_TCP);
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden nat_update(&fi, nat2, nat->nat_ptr);
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_ifp = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nat->nat_dir == NAT_INBOUND) {
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
990b4856d0eaada6f8140335733a1b1771ed2746lling ip->ip_dst = nat->nat_inip;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ip->ip_len = slen;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ip->ip_src = swip;
990b4856d0eaada6f8140335733a1b1771ed2746lling ip->ip_dst = swip2;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh } else {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ipstate_t *is;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling nat_update(&fi, nat2, nat->nat_ptr);
990b4856d0eaada6f8140335733a1b1771ed2746lling READ_ENTER(&ifs->ifs_ipf_state);
990b4856d0eaada6f8140335733a1b1771ed2746lling is = nat2->nat_state;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (is != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling MUTEX_ENTER(&is->is_lock);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void)fr_tcp_age(&is->is_sti, &fi, ifs->ifs_ips_tqtqb,
990b4856d0eaada6f8140335733a1b1771ed2746lling is->is_flags);
990b4856d0eaada6f8140335733a1b1771ed2746lling MUTEX_EXIT(&is->is_lock);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh RWLOCK_EXIT(&ifs->ifs_ipf_state);
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden }
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden return APR_INC(inc);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden}
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhint ippr_ftp_client(fin, ip, nat, ftp, dlen, ifsftp)
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhfr_info_t *fin;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhnat_t *nat;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Sidenftpinfo_t *ftp;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Sidenip_t *ip;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Sidenint dlen;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Sidenifs_ftppxy_t *ifsftp;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden{
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden char *rptr, *wptr, cmd[6], c;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden ftpside_t *f;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden int inc, i;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden inc = 0;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden f = &ftp->ftp_side[0];
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden rptr = f->ftps_rptr;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden wptr = f->ftps_wptr;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden for (i = 0; (i < 5) && (i < dlen); i++) {
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden c = rptr[i];
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ISALPHA(c)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[i] = TOUPPER(c);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[i] = c;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens }
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens cmd[i] = '\0';
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens ftp->ftp_incok = 0;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (ftp->ftp_passok == FTPXY_ADOK_1 ||
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_passok == FTPXY_AUOK_1) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ftp->ftp_passok = FTPXY_USER_2;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ftp->ftp_incok = 1;
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_passok = FTPXY_USER_1;
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_incok = 1;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling } else if (!strncmp(cmd, "AUTH ", 5)) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ftp->ftp_passok = FTPXY_AUTH_1;
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_incok = 1;
990b4856d0eaada6f8140335733a1b1771ed2746lling } else if (!strncmp(cmd, "PASS ", 5)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (ftp->ftp_passok == FTPXY_USOK_1) {
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_passok = FTPXY_PASS_1;
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_incok = 1;
990b4856d0eaada6f8140335733a1b1771ed2746lling } else if (ftp->ftp_passok == FTPXY_USOK_2) {
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_passok = FTPXY_PASS_2;
990b4856d0eaada6f8140335733a1b1771ed2746lling ftp->ftp_incok = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if ((ftp->ftp_passok == FTPXY_AUOK_1) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens !strncmp(cmd, "ADAT ", 5)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_passok = FTPXY_ADAT_1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_incok = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if ((ftp->ftp_passok == FTPXY_PAOK_1 ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_passok == FTPXY_PAOK_2) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens !strncmp(cmd, "ACCT ", 5)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_passok = FTPXY_ACCT_1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_incok = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if ((ftp->ftp_passok == FTPXY_GO) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens !ifsftp->ippr_ftp_pasvonly &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens !strncmp(cmd, "PORT ", 5)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_port(fin, ip, nat, f, dlen, ifsftp);
99653d4ee642c6528e88224f12409a5f23060994eschrock } else if (ifsftp->ippr_ftp_insecure && !ifsftp->ippr_ftp_pasvonly &&
99653d4ee642c6528e88224f12409a5f23060994eschrock !strncmp(cmd, "PORT ", 5)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_port(fin, ip, nat, f, dlen, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((*rptr++ != '\n') && (rptr < wptr))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_rptr = rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return inc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_pasv(fin, ip, nat, ftp, dlen, ifsftp)
99653d4ee642c6528e88224f12409a5f23060994eschrockfr_info_t *fin;
fa9e4066f08beec538e775443c5be79dd423fcabahrensip_t *ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrensnat_t *nat;
99653d4ee642c6528e88224f12409a5f23060994eschrockftpinfo_t *ftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint dlen;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens u_int a1, a2, a3, a4, data_ip;
99653d4ee642c6528e88224f12409a5f23060994eschrock char newbuf[IPF_FTPBUFSZ];
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *s, *brackets[2];
fa9e4066f08beec538e775443c5be79dd423fcabahrens u_short a5, a6;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftpside_t *f;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_forcepasv != 0 &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_side[0].ftps_cmds);
99653d4ee642c6528e88224f12409a5f23060994eschrock return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens f = &ftp->ftp_side[1];
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define PASV_REPLEN 24
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check for PASV reply message.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dlen < IPF_MIN227LEN) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n",
99653d4ee642c6528e88224f12409a5f23060994eschrock dlen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (strncmp(f->ftps_rptr,
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock "227 Entering Passive Mod", PASV_REPLEN)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_pasv:%d reply wrong\n", 227);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens brackets[0] = "";
fa9e4066f08beec538e775443c5be79dd423fcabahrens brackets[1] = "";
705040ed336e23b47ac6a3421d1f23ab5e86871bEric Taylor /*
705040ed336e23b47ac6a3421d1f23ab5e86871bEric Taylor * Skip the PASV reply + space
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = f->ftps_rptr + PASV_REPLEN;
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && !ISDIGIT(*s)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '(') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens brackets[0] = "(";
fa9e4066f08beec538e775443c5be79dd423fcabahrens brackets[1] = ")";
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Pick out the address components, two at a time.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 = ippr_ftp_atoi(&s);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (s == NULL) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (ifsftp->ippr_ftp_debug > 1)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin return 0;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin a2 = ippr_ftp_atoi(&s);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (s == NULL) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (ifsftp->ippr_ftp_debug > 1)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin return 0;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * check that IP address in the PASV reply is the same as the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * sender of the command - prevents using PASV for port scanning.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 <<= 16;
99653d4ee642c6528e88224f12409a5f23060994eschrock a1 |= a2;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (((nat->nat_dir == NAT_INBOUND) &&
99653d4ee642c6528e88224f12409a5f23060994eschrock (a1 != ntohl(nat->nat_inip.s_addr))) ||
99653d4ee642c6528e88224f12409a5f23060994eschrock ((nat->nat_dir == NAT_OUTBOUND) &&
99653d4ee642c6528e88224f12409a5f23060994eschrock (a1 != ntohl(nat->nat_oip.s_addr)))) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ifsftp->ippr_ftp_debug > 0)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1");
99653d4ee642c6528e88224f12409a5f23060994eschrock return 0;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
99653d4ee642c6528e88224f12409a5f23060994eschrock a5 = ippr_ftp_atoi(&s);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (s == NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ifsftp->ippr_ftp_debug > 1)
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3);
99653d4ee642c6528e88224f12409a5f23060994eschrock return 0;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == ')')
99653d4ee642c6528e88224f12409a5f23060994eschrock s++;
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == '.')
99653d4ee642c6528e88224f12409a5f23060994eschrock s++;
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == '\n')
99653d4ee642c6528e88224f12409a5f23060994eschrock s--;
99653d4ee642c6528e88224f12409a5f23060994eschrock /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * check for CR-LF at the end.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((*s == '\r') && (*(s + 1) == '\n')) {
99653d4ee642c6528e88224f12409a5f23060994eschrock s += 2;
99653d4ee642c6528e88224f12409a5f23060994eschrock } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ifsftp->ippr_ftp_debug > 1)
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("ippr_ftp_pasv:missing %s", "cr-lf\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock return 0;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock a6 = a5 & 0xff;
99653d4ee642c6528e88224f12409a5f23060994eschrock a5 >>= 8;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan /*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Calculate new address parts for 227 reply
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan */
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nat->nat_dir == NAT_INBOUND) {
99653d4ee642c6528e88224f12409a5f23060994eschrock data_ip = nat->nat_outip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 = ntohl(data_ip);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens data_ip = htonl(a1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden a2 = (a1 >> 16) & 0xff;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh a3 = (a1 >> 8) & 0xff;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh a4 = a1 & 0xff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens a1 >>= 24;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if defined(SNPRINTF) && defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) SNPRINTF(newbuf, sizeof(newbuf), "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
fa9e4066f08beec538e775443c5be79dd423fcabahrens a5, a6, brackets[1]);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden#else
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) sprintf(newbuf, "%s %s%u,%u,%u,%u,%u,%u%s\r\n",
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden a5, a6, brackets[1]);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6),
b1b8ab34de515a5e83206da22c3d7e563241b021lling newbuf, s, data_ip, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_pasvreply(fin, ip, nat, f, port, newmsg, s, data_ip, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrensfr_info_t *fin;
fa9e4066f08beec538e775443c5be79dd423fcabahrensip_t *ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrensnat_t *nat;
fa9e4066f08beec538e775443c5be79dd423fcabahrensftpside_t *f;
99653d4ee642c6528e88224f12409a5f23060994eschrocku_int port;
99653d4ee642c6528e88224f12409a5f23060994eschrockchar *newmsg;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenchar *s;
fa9e4066f08beec538e775443c5be79dd423fcabahrensu_int data_ip;
990b4856d0eaada6f8140335733a1b1771ed2746llingifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
990b4856d0eaada6f8140335733a1b1771ed2746lling int inc, off, nflags, sflags;
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcphdr_t *tcp, tcph, *tcp2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct in_addr swip, swip2;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh struct in_addr data_addr;
990b4856d0eaada6f8140335733a1b1771ed2746lling size_t nlen, olen;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock fr_info_t fi;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat_t *nat2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens mb_t *m;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ipf_stack_t *ifs = fin->fin_ifs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens m = fin->fin_m;
99653d4ee642c6528e88224f12409a5f23060994eschrock tcp = (tcphdr_t *)fin->fin_dp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock data_addr.s_addr = data_ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcp2 = &tcph;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden inc = 0;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
fa9e4066f08beec538e775443c5be79dd423fcabahrens olen = s - f->ftps_rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nlen = strlen(newmsg);
990b4856d0eaada6f8140335733a1b1771ed2746lling inc = nlen - olen;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((inc + ip->ip_len) > 65535) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (ifsftp->ippr_ftp_debug > 0)
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n",
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock inc);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock return 0;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock }
990b4856d0eaada6f8140335733a1b1771ed2746lling
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh#if !defined(_KERNEL)
990b4856d0eaada6f8140335733a1b1771ed2746lling bcopy(newmsg, MTOD(m, char *) + off, nlen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens# if defined(MENTAT)
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews if (inc < 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void)adjmsg(m, inc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens# else /* defined(MENTAT) */
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * m_adj takes care of pkthdr.len, if required and treats inc<0 to
990b4856d0eaada6f8140335733a1b1771ed2746lling * mean remove -len bytes from the end of the packet.
990b4856d0eaada6f8140335733a1b1771ed2746lling * The mbuf chain will be extended if necessary by m_copyback().
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (inc < 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling m_adj(m, inc);
990b4856d0eaada6f8140335733a1b1771ed2746lling# endif /* defined(MENTAT) */
990b4856d0eaada6f8140335733a1b1771ed2746lling#endif /* !defined(_KERNEL) */
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh COPYBACK(m, off, nlen, newmsg);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (inc != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ip->ip_len += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fin->fin_dlen += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fin->fin_plen += inc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /*
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * Add skeleton NAT entry for connection which will come back the
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * other way.
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden bcopy((char *)fin, (char *)&fi, sizeof(fi));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fi.fin_flx |= FI_IGNORE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fi.fin_data[0] = 0;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden fi.fin_data[1] = port;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nflags = IPN_TCP|SI_W_SPORT;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (ifsftp->ippr_ftp_pasvrdr && f->ftps_ifp)
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nflags |= SI_W_DPORT;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (nat->nat_dir == NAT_OUTBOUND)
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nat2 = nat_outlookup(&fi, nflags|NAT_SEARCH,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nat->nat_p, nat->nat_inip, nat->nat_oip);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh else
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nat2 = nat_inlookup(&fi, nflags|NAT_SEARCH,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nat->nat_p, nat->nat_inip, nat->nat_oip);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (nat2 == NULL) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh int slen;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews slen = ip->ip_len;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews ip->ip_len = fin->fin_hlen + sizeof(*tcp2);
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews bzero((char *)tcp2, sizeof(*tcp2));
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews tcp2->th_win = htons(8192);
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews tcp2->th_sport = 0; /* XXX - fake it for nat_new */
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews TCP_OFF_A(tcp2, 5);
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews tcp2->th_flags = TH_SYN;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews fi.fin_data[1] = port;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews fi.fin_dlen = sizeof(*tcp2);
990b4856d0eaada6f8140335733a1b1771ed2746lling tcp2->th_dport = htons(port);
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews fi.fin_data[0] = 0;
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_dp = (char *)tcp2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_plen = fi.fin_hlen + sizeof(*tcp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_fr = &ifsftp->ftppxyfr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_out = nat->nat_dir;
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens swip = ip->ip_src;
fa9e4066f08beec538e775443c5be79dd423fcabahrens swip2 = ip->ip_dst;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nat->nat_dir == NAT_OUTBOUND) {
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_fi.fi_daddr = data_addr.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_fi.fi_saddr = nat->nat_inip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_dst = data_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_src = nat->nat_inip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (nat->nat_dir == NAT_INBOUND) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_fi.fi_saddr = nat->nat_oip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_fi.fi_daddr = nat->nat_outip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_src = nat->nat_oip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_dst = nat->nat_outip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
990b4856d0eaada6f8140335733a1b1771ed2746lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens sflags = nflags;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nflags |= NAT_SLAVE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nat->nat_dir == NAT_INBOUND)
990b4856d0eaada6f8140335733a1b1771ed2746lling nflags |= NAT_NOTRULEPORT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nat2 != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) nat_proto(&fi, nat2, IPN_TCP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat_update(&fi, nat2, nat->nat_ptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_ifp = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nat->nat_dir == NAT_INBOUND) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens fi.fin_fi.fi_daddr = nat->nat_inip.s_addr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_dst = nat->nat_inip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fr_addstate(&fi, &nat2->nat_state, sflags);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_len = slen;
990b4856d0eaada6f8140335733a1b1771ed2746lling ip->ip_src = swip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip->ip_dst = swip2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ipstate_t *is;
705040ed336e23b47ac6a3421d1f23ab5e86871bEric Taylor
705040ed336e23b47ac6a3421d1f23ab5e86871bEric Taylor nat_update(&fi, nat2, nat->nat_ptr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens READ_ENTER(&ifs->ifs_ipf_state);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh is = nat2->nat_state;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (is != NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock MUTEX_ENTER(&is->is_lock);
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin (void) fr_tcp_age(&is->is_sti, &fi, ifs->ifs_ips_tqtqb,
99653d4ee642c6528e88224f12409a5f23060994eschrock is->is_flags);
99653d4ee642c6528e88224f12409a5f23060994eschrock MUTEX_EXIT(&is->is_lock);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
990b4856d0eaada6f8140335733a1b1771ed2746lling RWLOCK_EXIT(&ifs->ifs_ipf_state);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock return inc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock
990b4856d0eaada6f8140335733a1b1771ed2746llingint ippr_ftp_server(fin, ip, nat, ftp, dlen, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrensfr_info_t *fin;
fa9e4066f08beec538e775443c5be79dd423fcabahrensip_t *ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrensnat_t *nat;
fa9e4066f08beec538e775443c5be79dd423fcabahrensftpinfo_t *ftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint dlen;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *rptr, *wptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftpside_t *f;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int inc;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f = &ftp->ftp_side[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens rptr = f->ftps_rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens wptr = f->ftps_wptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling if (*rptr == ' ')
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto server_cmd_ok;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftp->ftp_passok == FTPXY_GO) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!strncmp(rptr, "227 ", 4))
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (!strncmp(rptr, "229 ", 4))
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_epsv(fin, ip, nat, f, dlen, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (ifsftp->ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (ifsftp->ippr_ftp_insecure && !strncmp(rptr, "229 ", 4)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_epsv(fin, ip, nat, f, dlen, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (*rptr == '5' || *rptr == '4')
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_passok = FTPXY_INIT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (ftp->ftp_incok) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*rptr == '3') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftp->ftp_passok == FTPXY_ACCT_1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_passok = FTPXY_GO;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh else
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh ftp->ftp_passok++;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh } else if (*rptr == '2') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (ftp->ftp_passok)
fa9e4066f08beec538e775443c5be79dd423fcabahrens {
990b4856d0eaada6f8140335733a1b1771ed2746lling case FTPXY_USER_1 :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh case FTPXY_USER_2 :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh case FTPXY_PASS_1 :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh case FTPXY_PASS_2 :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh case FTPXY_ACCT_1 :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh ftp->ftp_passok = FTPXY_GO;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh break;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh default :
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh ftp->ftp_passok += 3;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh break;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh }
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh }
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh }
11022c7cf39f3b863e749f3866f6ddcb445c2d05timhserver_cmd_ok:
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh ftp->ftp_incok = 0;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((*rptr++ != '\n') && (rptr < wptr))
fa9e4066f08beec538e775443c5be79dd423fcabahrens ;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_rptr = rptr;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews return inc;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews}
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews/*
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews * Look to see if the buffer starts with something which we recognise as
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews * being the correct syntax for the FTP protocol.
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews */
8b713775314bbbf24edd503b4869342d8711ce95Will Andrewsint ippr_ftp_client_valid(ftps, buf, len, ifsftp)
8b713775314bbbf24edd503b4869342d8711ce95Will Andrewsftpside_t *ftps;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrewschar *buf;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrewssize_t len;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens register char *s, c, pc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register size_t i = len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char cmd[5];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftps->ftps_junk == 1)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin return 1;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (i < 5) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens i--;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden c = *s++;
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ISALPHA(c)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[0] = TOUPPER(c);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden c = *s++;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden i--;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ISALPHA(c)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[1] = TOUPPER(c);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden c = *s++;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden i--;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ISALPHA(c)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[2] = TOUPPER(c);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden c = *s++;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden i--;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ISALPHA(c)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden cmd[3] = TOUPPER(c);
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews c = *s++;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews i--;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews if ((c != ' ') && (c != '\r'))
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto bad_client_command;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else if ((c != ' ') && (c != '\r'))
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto bad_client_command;
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews } else
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews goto bad_client_command;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh } else
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto bad_client_command;
99653d4ee642c6528e88224f12409a5f23060994eschrock } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrensbad_client_command:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ippr_ftp_client_valid",
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftps->ftps_junk, (int)len, (int)i, c,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (int)len, buf);
99653d4ee642c6528e88224f12409a5f23060994eschrock return 1;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; i; i--) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens pc = c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens c = *s++;
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((pc == '\r') && (c == '\n')) {
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock cmd[4] = '\0';
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (!strcmp(cmd, "PASV"))
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock ftps->ftps_cmds = FTPXY_C_PASV;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
990b4856d0eaada6f8140335733a1b1771ed2746lling ftps->ftps_cmds = 0;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh return 0;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling#if !defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens (int)len, (int)len, buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_server_valid(ftps, buf, len, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrensftpside_t *ftps;
fa9e4066f08beec538e775443c5be79dd423fcabahrenschar *buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrenssize_t len;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
99653d4ee642c6528e88224f12409a5f23060994eschrock{
fa9e4066f08beec538e775443c5be79dd423fcabahrens register char *s, c, pc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register size_t i = len;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cmd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cmd = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftps->ftps_junk == 1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 1;
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (i < 5) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 2;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens c = *s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens i--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (c == ' ')
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto search_eol;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ISDIGIT(c)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cmd = (c - '0') * 100;
fa9e4066f08beec538e775443c5be79dd423fcabahrens c = *s++;
99653d4ee642c6528e88224f12409a5f23060994eschrock i--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ISDIGIT(c)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cmd += (c - '0') * 10;
fa9e4066f08beec538e775443c5be79dd423fcabahrens c = *s++;
99653d4ee642c6528e88224f12409a5f23060994eschrock i--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ISDIGIT(c)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cmd += (c - '0');
fa9e4066f08beec538e775443c5be79dd423fcabahrens c = *s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens i--;
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((c != '-') && (c != ' '))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto bad_server_command;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto bad_server_command;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto bad_server_command;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrensbad_server_command:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ippr_ftp_server_valid",
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl ftps->ftps_junk, (int)len, (int)i,
fa9e4066f08beec538e775443c5be79dd423fcabahrens c, (int)len, buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrenssearch_eol:
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; i; i--) {
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens pc = c;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens c = *s++;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens if ((pc == '\r') && (c == '\n')) {
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens ftps->ftps_cmds = cmd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_server_valid:junk after cmd[%*s]\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens (int)len, buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_valid(ftp, side, buf, len, ifsftp)
b1b8ab34de515a5e83206da22c3d7e563241b021llingftpinfo_t *ftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint side;
fa9e4066f08beec538e775443c5be79dd423fcabahrenschar *buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrenssize_t len;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftpside_t *ftps;
99653d4ee642c6528e88224f12409a5f23060994eschrock int ret;
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftps = &ftp->ftp_side[side];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (side == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = ippr_ftp_client_valid(ftps, buf, len, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = ippr_ftp_server_valid(ftps, buf, len, ifsftp);
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson return ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson * For map rules, the following applies:
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson * rv == 0 for outbound processing,
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson * rv == 1 for inbound processing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For rdr rules, the following applies:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * rv == 0 for inbound processing,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * rv == 1 for outbound processing.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_process(fin, nat, ftp, rv, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrensfr_info_t *fin;
fa9e4066f08beec538e775443c5be79dd423fcabahrensnat_t *nat;
fa9e4066f08beec538e775443c5be79dd423fcabahrensftpinfo_t *ftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint rv;
fa9e4066f08beec538e775443c5be79dd423fcabahrensifs_ftppxy_t *ifsftp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *rptr, *wptr, *s;
99653d4ee642c6528e88224f12409a5f23060994eschrock u_32_t thseq, thack;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ap_session_t *aps;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftpside_t *f, *t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcphdr_t *tcp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip_t *ip;
99653d4ee642c6528e88224f12409a5f23060994eschrock mb_t *m;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens m = fin->fin_m;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ip = fin->fin_ip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens tcp = (tcphdr_t *)fin->fin_dp;
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens f = &ftp->ftp_side[rv];
fa9e4066f08beec538e775443c5be79dd423fcabahrens t = &ftp->ftp_side[1 - rv];
fa9e4066f08beec538e775443c5be79dd423fcabahrens thseq = ntohl(tcp->th_seq);
fa9e4066f08beec538e775443c5be79dd423fcabahrens thack = ntohl(tcp->th_ack);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens#ifdef __sgi
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens mlen = fin->fin_plen - off;
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson#else
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens mlen = MSGDSIZE(m) - off;
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson#endif
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens if (ifsftp->ippr_ftp_debug > 4)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_process: mlen %d\n", mlen);
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mlen <= 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((tcp->th_flags & TH_OPENING) == TH_OPENING) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_seq[0] = thseq + 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens t->ftps_seq[0] = thack;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens aps = nat->nat_aps;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens sel = aps->aps_sel[1 - rv];
fa9e4066f08beec538e775443c5be79dd423fcabahrens sel2 = aps->aps_sel[rv];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rv == 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock seqoff = aps->aps_seqoff[sel];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aps->aps_seqmin[sel] > seqoff + thseq)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson seqoff = aps->aps_seqoff[!sel];
fa9e4066f08beec538e775443c5be79dd423fcabahrens ackoff = aps->aps_ackoff[sel2];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aps->aps_ackmin[sel2] > ackoff + thack)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ackoff = aps->aps_ackoff[!sel2];
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens seqoff = aps->aps_ackoff[sel];
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 2)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock aps->aps_ackmin[sel]);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock if (aps->aps_ackmin[sel] > seqoff + thseq)
99653d4ee642c6528e88224f12409a5f23060994eschrock seqoff = aps->aps_ackoff[!sel];
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock ackoff = aps->aps_seqoff[sel2];
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ifsftp->ippr_ftp_debug > 2)
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
99653d4ee642c6528e88224f12409a5f23060994eschrock aps->aps_seqmin[sel2]);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ackoff > 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (aps->aps_seqmin[sel2] > ackoff + thack)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan ackoff = aps->aps_seqoff[!sel2];
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan } else {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (aps->aps_seqmin[sel2] > thack)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan ackoff = aps->aps_seqoff[!sel2];
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (ifsftp->ippr_ftp_debug > 2) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens rv ? "IN" : "OUT", tcp->th_flags, thseq, seqoff,
99653d4ee642c6528e88224f12409a5f23060994eschrock thack, ackoff, mlen, fin->fin_plen, off);
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("sel %d seqmin %x/%x offset %d/%d\n", sel,
99653d4ee642c6528e88224f12409a5f23060994eschrock aps->aps_seqmin[sel], aps->aps_seqmin[sel2],
99653d4ee642c6528e88224f12409a5f23060994eschrock aps->aps_seqoff[sel], aps->aps_seqoff[sel2]);
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("sel %d ackmin %x/%x offset %d/%d\n", sel2,
99653d4ee642c6528e88224f12409a5f23060994eschrock aps->aps_ackmin[sel], aps->aps_ackmin[sel2],
fa9e4066f08beec538e775443c5be79dd423fcabahrens aps->aps_ackoff[sel], aps->aps_ackoff[sel2]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * XXX - Ideally, this packet should get dropped because we now know
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * that it is out of order (and there is no real danger in doing so
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * apart from causing packets to go through here ordered).
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 2) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (t->ftps_seq[0] == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson t->ftps_seq[0] = thack;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ackoff == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (t->ftps_seq[0] == thack)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson else if (t->ftps_seq[1] == thack) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson t->ftps_seq[0] = thack;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (t->ftps_seq[0] + ackoff == thack)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson else if (t->ftps_seq[0] == thack + ackoff)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson else if (t->ftps_seq[1] + ackoff == thack) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson t->ftps_seq[0] = thack - ackoff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else if (t->ftps_seq[1] == thack + ackoff) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson t->ftps_seq[0] = thack - ackoff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 2) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (!ok)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s ok\n", "not");
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (!mlen) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (t->ftps_seq[0] + ackoff != thack) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 1) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s:seq[0](%x) + (%x) != (%x)\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process", t->ftps_seq[0],
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ackoff, thack);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return APR_ERR(1);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 2) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_seq[0], f->ftps_seq[1]);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (tcp->th_flags & TH_FIN) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (thseq == f->ftps_seq[1]) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_seq[0] = f->ftps_seq[1] - seqoff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_seq[1] = thseq + 1 - seqoff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 1) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson thseq, seqoff, f->ftps_seq[0]);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return APR_ERR(1);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling f->ftps_len = 0;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if ((thseq == f->ftps_seq[0]) || (thseq == f->ftps_seq[1])) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /*
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Retransmitted data packet.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else if ((thseq + mlen == f->ftps_seq[0]) ||
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson (thseq + mlen == f->ftps_seq[1])) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson ok = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ok == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson inc = thseq - f->ftps_seq[0];
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 1) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("inc %d sel %d rv %d\n", inc, sel, rv);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("th_seq %x ftps_seq %x/%x\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson thseq, f->ftps_seq[0], f->ftps_seq[1]);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson aps->aps_ackoff[sel]);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson aps->aps_seqoff[sel]);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return APR_ERR(1);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson inc = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson rptr = f->ftps_rptr;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson wptr = f->ftps_wptr;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_seq[0] = thseq;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_seq[1] = f->ftps_seq[0] + mlen;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_len = mlen;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson while (mlen > 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr));
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson COPYDATA(m, off, len, wptr);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson mlen -= len;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson off += len;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson wptr += len;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 3)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s:len %d/%d off %d wptr %lx junk %d [%*s]\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson len, mlen, off, (u_long)wptr, f->ftps_junk,
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson len, rptr);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden f->ftps_wptr = wptr;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (f->ftps_junk != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden i = f->ftps_junk;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr,
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson wptr - rptr, ifsftp);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 5)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s:junk %d -> %d\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process", i, f->ftps_junk);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (f->ftps_junk != 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (wptr - rptr == sizeof(f->ftps_buf)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 4)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s:full buffer\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process");
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_rptr = f->ftps_buf;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_wptr = f->ftps_buf;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson rptr = f->ftps_rptr;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson wptr = f->ftps_wptr;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /*
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Because we throw away data here that
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * we would otherwise parse, set the
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * junk flag to indicate just ignore
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * any data upto the next CRLF.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_junk = 1;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson continue;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson while ((f->ftps_junk == 0) && (wptr > rptr)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson len = wptr - rptr;
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len, ifsftp);
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock if (ifsftp->ippr_ftp_debug > 3) {
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock printf("%s=%d len %d rv %d ptr %lx/%lx ",
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "ippr_ftp_valid",
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante f->ftps_junk, len, rv, (u_long)rptr,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (u_long)wptr);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante printf("buf [%*s]\n", len, rptr);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (f->ftps_junk == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_rptr = rptr;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (rv)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling inc += ippr_ftp_server(fin, ip, nat,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ftp, len, ifsftp);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling else
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling inc += ippr_ftp_client(fin, ip, nat,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ftp, len, ifsftp);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling rptr = f->ftps_rptr;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling wptr = f->ftps_wptr;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /*
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Off to a bad start so lets just forget about using the
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * ftp proxy for this connection.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /* f->ftps_seq[1] += inc; */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (ifsftp->ippr_ftp_debug > 1)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson printf("%s:cmds == 0 junk == 1\n",
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "ippr_ftp_process");
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return APR_ERR(2);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((f->ftps_junk != 0) && (rptr < wptr)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson for (s = rptr; s < wptr; s++) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if ((*s == '\r') && (s + 1 < wptr) &&
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson (*(s + 1) == '\n')) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson rptr = s + 2;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson f->ftps_junk = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rptr == wptr) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens rptr = wptr = f->ftps_buf;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Compact the buffer back to the start. The junk
fa9e4066f08beec538e775443c5be79dd423fcabahrens * flag should already be set and because we're not
fa9e4066f08beec538e775443c5be79dd423fcabahrens * throwing away any data, it is preserved from its
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock * current state.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rptr > f->ftps_buf) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson bcopy(rptr, f->ftps_buf, len);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson wptr -= rptr - f->ftps_buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens rptr = f->ftps_buf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_rptr = rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_wptr = wptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
990b4856d0eaada6f8140335733a1b1771ed2746lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* f->ftps_seq[1] += inc; */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (tcp->th_flags & TH_FIN)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock f->ftps_seq[1]++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ifsftp->ippr_ftp_debug > 3) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens#ifdef __sgi
fa9e4066f08beec538e775443c5be79dd423fcabahrens mlen = fin->fin_plen;
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens mlen = MSGDSIZE(m);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens mlen -= off;
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ftps_seq[1] = %x inc %d len %d\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_seq[1], inc, mlen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_rptr = rptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->ftps_wptr = wptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return APR_INC(inc);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockint ippr_ftp_out(fin, aps, nat, private)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenfr_info_t *fin;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenap_session_t *aps;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidennat_t *nat;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenvoid *private;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock ftpinfo_t *ftp;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock int rev;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp = aps->aps_data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ftp->ftp_side[1 - rev].ftps_ifp == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ftp->ftp_side[1 - rev].ftps_ifp = fin->fin_ifp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ippr_ftp_process(fin, nat, ftp, rev, (ifs_ftppxy_t *)private);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinint ippr_ftp_in(fin, aps, nat, private)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinfr_info_t *fin;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinap_session_t *aps;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinnat_t *nat;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonvoid *private;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin{
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin ftpinfo_t *ftp;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson int rev;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock ftp = aps->aps_data;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock if (ftp == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return 0;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (ftp->ftp_side[rev].ftps_ifp == NULL)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan ftp->ftp_side[rev].ftps_ifp = fin->fin_ifp;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return ippr_ftp_process(fin, nat, ftp, 1 - rev, (ifs_ftppxy_t *)private);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan}
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
99653d4ee642c6528e88224f12409a5f23060994eschrock/*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * ippr_ftp_atoi - implement a version of atoi which processes numbers in
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * pairs separated by commas (which are expected to be in the range 0 - 255),
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * returning a 16 bit number combining either side of the , as the MSB and
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * LSB.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanu_short ippr_ftp_atoi(ptr)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanchar **ptr;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan{
99653d4ee642c6528e88224f12409a5f23060994eschrock register char *s = *ptr, c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register u_char i = 0, j = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson while (((c = *s++) != '\0') && ISDIGIT(c)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson i *= 10;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson i += c - '0';
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (c != ',') {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson *ptr = NULL;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson while (((c = *s++) != '\0') && ISDIGIT(c)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson j *= 10;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson j += c - '0';
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson }
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson *ptr = s;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson i &= 0xff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson j &= 0xff;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return (i << 8) | j;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson}
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonint ippr_ftp_epsv(fin, ip, nat, f, dlen, ifsftp)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonfr_info_t *fin;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonip_t *ip;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonnat_t *nat;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonftpside_t *f;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonint dlen;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonifs_ftppxy_t *ifsftp;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson{
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson char newbuf[IPF_FTPBUFSZ];
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson char *s;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson u_short ap = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson#define EPSV_REPLEN 33
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /*
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Check for EPSV reply message.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (dlen < IPF_MIN229LEN)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return (0);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley else if (strncmp(f->ftps_rptr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "229 Entering Extended Passive Mode", EPSV_REPLEN))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Skip the EPSV command + space
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens s = f->ftps_rptr + 33;
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && !ISDIGIT(*s))
fa9e4066f08beec538e775443c5be79dd423fcabahrens s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * As per RFC 2428, there are no addres components in the EPSV
fa9e4066f08beec538e775443c5be79dd423fcabahrens * response. So we'll go straight to getting the port.
46657f8d750bdb71753495ce2919170f126b8e34mmusante */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && ISDIGIT(*s)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ap *= 10;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald ap += *s++ - '0';
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!s)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '|')
fa9e4066f08beec538e775443c5be79dd423fcabahrens s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == ')')
fa9e4066f08beec538e775443c5be79dd423fcabahrens s++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '\n')
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling s--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * check for CR-LF at the end.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((*s == '\r') && (*(s + 1) == '\n')) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens s += 2;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald } else
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald return 0;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm#if defined(SNPRINTF) && defined(_KERNEL)
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n",
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm "229 Entering Extended Passive Mode", ap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sprintf(newbuf, "%s (|||%u|)\r\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "229 Entering Extended Passive Mode", ap);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s,
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald ip->ip_src.s_addr, ifsftp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens