ip_ftp_pxy.c revision 33f2fefd46350ca5992567761c46a5b70f864340
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright (C) 1997-2003 by Darren Reed
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the IPFILTER.LICENCE file for details on licencing.
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * $Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp $
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Simple FTP transparent proxy for in-kernel use. For use with the NAT
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Values for FTP commands. Numerics cover 0-999
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarkstypedef struct ifs_ftppxy {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Do not require logins before transfers */
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin /* PASV must be last command prior to 227 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 1 - security
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems * 3 - error debugging
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 4 - parsing errors
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 5 - parsing info
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 6 - parsing debug
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_in __P((fr_info_t *, ap_session_t *, nat_t *, void *));
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,
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_epsv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musanteint ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_process __P((fr_info_t *, nat_t *, ftpinfo_t *, int,
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int,
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 *));
06eeb2ad640ce72d394ac521094bed7681044408ekint ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize local structures.
fa9e4066f08beec538e775443c5be79dd423fcabahrens bzero((char *)&ifsftp->ftppxyfr, sizeof(ifsftp->ftppxyfr));
fa9e4066f08beec538e775443c5be79dd423fcabahrens ifsftp->ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens MUTEX_INIT(&ifsftp->ftppxyfr.fr_lock, "FTP Proxy Mutex");
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock bzero((char *)&ifsftp->ftptune, sizeof(ifsftp->ftptune));
06eeb2ad640ce72d394ac521094bed7681044408ek ifsftp->ftptune.ipft_pint = (uint_t *)&ifsftp->ippr_ftp_debug;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifsftp->ftptune.ipft_sz = sizeof(ifsftp->ippr_ftp_debug);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock ifs_ftppxy_t *ifsftp = *((ifs_ftppxy_t **)private);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock/*ARGSUSED*/
26fd77009b17f8c8fb32eb362584cfd635e87ad9Krishnendu Sadhukhan - Sun Microsystems tcphdr_t *tcp, tcph, *tcp2 = &tcph;
990b4856d0eaada6f8140335733a1b1771ed2746lling off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * Check for client sending out PORT message.
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * Skip the PORT command + space
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson * Pick out the address components, two at a time.
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 if (s == NULL) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2);
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.
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1");
b1b8ab34de515a5e83206da22c3d7e563241b021lling printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (*s == ')')
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * check for CR-LF at the end.
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (*s == '\n')
990b4856d0eaada6f8140335733a1b1771ed2746lling * Don't allow the PORT command to specify a port < 1024 due to
990b4856d0eaada6f8140335733a1b1771ed2746lling * security crap.
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Calculate new address parts for PORT command
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* DO NOT change this to snprintf! */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) SNPRINTF(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if !defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens# if defined(MENTAT)
990b4856d0eaada6f8140335733a1b1771ed2746lling# else /* defined(MENTAT) */
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# endif /* defined(MENTAT) */
b1b8ab34de515a5e83206da22c3d7e563241b021lling#endif /* !defined(_KERNEL) */
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
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add skeleton NAT entry for connection which will come back the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * other way.
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin tcp2->th_dport = 0; /* XXX - don't specify remote port */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
57221772c3fc05faba04bf48ddff45abf2bbf2bdChristopher Siden nat2 = nat_new(&fi, nat->nat_ptr, NULL, flags, nat->nat_dir);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void)fr_tcp_age(&is->is_sti, &fi, ifs->ifs_ips_tqtqb,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) {
99653d4ee642c6528e88224f12409a5f23060994eschrock } else if (ifsftp->ippr_ftp_insecure && !ifsftp->ippr_ftp_pasvonly &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check for PASV reply message.
705040ed336e23b47ac6a3421d1f23ab5e86871bEric Taylor * Skip the PASV reply + space
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && !ISDIGIT(*s)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '(') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Pick out the address components, two at a time.
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (s == NULL) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (s == NULL) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2);
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.
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1");
99653d4ee642c6528e88224f12409a5f23060994eschrock if (s == NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == ')')
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == '.')
99653d4ee642c6528e88224f12409a5f23060994eschrock if (*s == '\n')
99653d4ee642c6528e88224f12409a5f23060994eschrock * check for CR-LF at the end.
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Calculate new address parts for 227 reply
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,
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,
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6),
fa9e4066f08beec538e775443c5be79dd423fcabahrensint ippr_ftp_pasvreply(fin, ip, nat, f, port, newmsg, s, data_ip, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n",
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh#if !defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens# if defined(MENTAT)
fa9e4066f08beec538e775443c5be79dd423fcabahrens# else /* defined(MENTAT) */
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# endif /* defined(MENTAT) */
990b4856d0eaada6f8140335733a1b1771ed2746lling#endif /* !defined(_KERNEL) */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * Add skeleton NAT entry for connection which will come back the
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden bcopy((char *)fin, (char *)&fi, sizeof(fi));
8b713775314bbbf24edd503b4869342d8711ce95Will Andrews tcp2->th_sport = 0; /* XXX - fake it for nat_new */
990b4856d0eaada6f8140335733a1b1771ed2746lling fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir);
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin (void) fr_tcp_age(&is->is_sti, &fi, ifs->ifs_ips_tqtqb,
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens inc = ippr_ftp_pasv(fin, ip, nat, ftp, 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)) {
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 Andrewsint ippr_ftp_client_valid(ftps, buf, len, ifsftp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens register char *s, c, pc;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (i < 5) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ippr_ftp_client_valid",
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; i; i--) {
990b4856d0eaada6f8140335733a1b1771ed2746lling#if !defined(_KERNEL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens register char *s, c, pc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (i < 5) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (c == ' ')
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*s]\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ippr_ftp_server_valid",
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; i; i--) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("ippr_ftp_server_valid:junk after cmd[%*s]\n",
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.
fa9e4066f08beec538e775443c5be79dd423fcabahrens int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff;
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mlen <= 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rv == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq,
99653d4ee642c6528e88224f12409a5f23060994eschrock printf("ackoff %d thack %x seqmin %x\n", ackoff, thack,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n",
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 rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (t->ftps_seq[0] == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else if (t->ftps_seq[1] == thack + ackoff) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("FIN: thseq %x seqoff %d ftps_seq %x\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if ((thseq == f->ftps_seq[0]) || (thseq == f->ftps_seq[1])) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Retransmitted data packet.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson } else if ((thseq + mlen == f->ftps_seq[0]) ||
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("inc %d sel %d rv %d\n", inc, sel, rv);
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel],
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel],
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson while (mlen > 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr));
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson printf("%s:len %d/%d off %d wptr %lx junk %d [%*s]\n",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (f->ftps_junk != 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson "ippr_ftp_process");
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 while ((f->ftps_junk == 0) && (wptr > rptr)) {
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len, ifsftp);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "ippr_ftp_valid",
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (f->ftps_junk == 0) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Off to a bad start so lets just forget about using the
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * ftp proxy for this connection.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /* f->ftps_seq[1] += inc; */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "ippr_ftp_process");
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 /* f->ftps_seq[1] += inc; */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ippr_ftp_process(fin, nat, ftp, rev, (ifs_ftppxy_t *)private);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return ippr_ftp_process(fin, nat, ftp, 1 - rev, (ifs_ftppxy_t *)private);
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
99653d4ee642c6528e88224f12409a5f23060994eschrock register char *s = *ptr, c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens register u_char i = 0, j = 0;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson i += c - '0';
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson if (c != ',') {
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson j += c - '0';
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return (i << 8) | j;
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilsonint ippr_ftp_epsv(fin, ip, nat, f, dlen, ifsftp)
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * Check for EPSV reply message.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Skip the EPSV command + space
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && !ISDIGIT(*s))
fa9e4066f08beec538e775443c5be79dd423fcabahrens * As per RFC 2428, there are no addres components in the EPSV
fa9e4066f08beec538e775443c5be79dd423fcabahrens * response. So we'll go straight to getting the port.
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (*s && ISDIGIT(*s)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '|')
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == ')')
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*s == '\n')
990b4856d0eaada6f8140335733a1b1771ed2746lling * check for CR-LF at the end.
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n",
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s,