proxy_ftp.c revision db3fa7db7c7910f2f23c3e3ffe0cf9f41a1899b9
6ae232055d4d8a97267517c5e50074c2c819941and/* ====================================================================
6ae232055d4d8a97267517c5e50074c2c819941and * The Apache Software License, Version 1.1
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * Copyright (c) 2000 The Apache Software Foundation. All rights
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * reserved.
6ae232055d4d8a97267517c5e50074c2c819941and * Redistribution and use in source and binary forms, with or without
6ae232055d4d8a97267517c5e50074c2c819941and * modification, are permitted provided that the following conditions
6ae232055d4d8a97267517c5e50074c2c819941and * are met:
6ae232055d4d8a97267517c5e50074c2c819941and * 1. Redistributions of source code must retain the above copyright
6ae232055d4d8a97267517c5e50074c2c819941and * notice, this list of conditions and the following disclaimer.
2e545ce2450a9953665f701bb05350f0d3f26275nd * 2. Redistributions in binary form must reproduce the above copyright
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * notice, this list of conditions and the following disclaimer in
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * the documentation and/or other materials provided with the
6ae232055d4d8a97267517c5e50074c2c819941and * distribution.
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * 3. The end-user documentation included with the redistribution,
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * if any, must include the following acknowledgment:
6ae232055d4d8a97267517c5e50074c2c819941and * "This product includes software developed by the
6ae232055d4d8a97267517c5e50074c2c819941and * Apache Software Foundation (http://www.apache.org/)."
6ae232055d4d8a97267517c5e50074c2c819941and * Alternately, this acknowledgment may appear in the software itself,
b43f840409794ed298e8634f6284741f193b6c4ftakashi * if and wherever such third-party acknowledgments normally appear.
b43f840409794ed298e8634f6284741f193b6c4ftakashi * 4. The names "Apache" and "Apache Software Foundation" must
befb6758d5618c60f29b19f9a7eb75ab993511dcjim * not be used to endorse or promote products derived from this
6ae232055d4d8a97267517c5e50074c2c819941and * software without prior written permission. For written
52ea316008e2581c8113441c9c341e5c65225f6anilgun * permission, please contact apache@apache.org.
6ae232055d4d8a97267517c5e50074c2c819941and * 5. Products derived from this software may not be called "Apache",
9995029b732e29b6957f746bbeed2c2547273150rjung * nor may "Apache" appear in their name, without prior written
9995029b732e29b6957f746bbeed2c2547273150rjung * permission of the Apache Software Foundation.
9995029b732e29b6957f746bbeed2c2547273150rjung * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
6ae232055d4d8a97267517c5e50074c2c819941and * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6ae232055d4d8a97267517c5e50074c2c819941and * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6ae232055d4d8a97267517c5e50074c2c819941and * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
6ae232055d4d8a97267517c5e50074c2c819941and * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
6ae232055d4d8a97267517c5e50074c2c819941and * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
6ae232055d4d8a97267517c5e50074c2c819941and * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * SUCH DAMAGE.
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * ====================================================================
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * This software consists of voluntary contributions made by many
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * individuals on behalf of the Apache Software Foundation. For more
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * information on the Apache Software Foundation, please see
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * Portions of this software are based upon public domain software
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * originally written at the National Center for Supercomputing Applications,
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * University of Illinois, Urbana-Champaign.
6ae232055d4d8a97267517c5e50074c2c819941and/* FTP routines for Apache proxy */
6ae232055d4d8a97267517c5e50074c2c819941and } while(c != '\n');
6ae232055d4d8a97267517c5e50074c2c819941and * Decodes a '%' escaped string, and returns the number of characters
6ae232055d4d8a97267517c5e50074c2c819941andstatic int decodeenc(char *x)
6ae232055d4d8a97267517c5e50074c2c819941and if (x[0] == '\0')
6ae232055d4d8a97267517c5e50074c2c819941and return 0; /* special case for no characters */
6ae232055d4d8a97267517c5e50074c2c819941and for (i = 0, j = 0; x[i] != '\0'; i++, j++) {
6ae232055d4d8a97267517c5e50074c2c819941and/* decode it if not already done */
6ae232055d4d8a97267517c5e50074c2c819941and if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) {
6ae232055d4d8a97267517c5e50074c2c819941and x[j] = '\0';
6ae232055d4d8a97267517c5e50074c2c819941and * checks an encoded ftp string for bad characters, namely, CR, LF or
6a3ab831a34f470b077294a173f24fcf1e5f0a3ctakashi * non-ascii character
6ae232055d4d8a97267517c5e50074c2c819941andstatic int ftp_check_string(const char *x)
6ae232055d4d8a97267517c5e50074c2c819941and int i, ch = 0;
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi for (i = 0; x[i] != '\0'; i++) {
6a3ab831a34f470b077294a173f24fcf1e5f0a3ctakashi if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) {
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi#else /*APR_CHARSET_EBCDIC*/
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi if (ch == '\r' || ch == '\n' || (os_toascii[ch] & 0x80))
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi#endif /*APR_CHARSET_EBCDIC*/
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi * Canonicalise ftp URLs.
6a3ab831a34f470b077294a173f24fcf1e5f0a3ctakashi char *user, *password, *host, *path, *parms, *strp, sport[7];
cd6c8de3bedcc401ee230159b0439fa20f44488etakashi const char *err;
6ae232055d4d8a97267517c5e50074c2c819941and err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port);
6ae232055d4d8a97267517c5e50074c2c819941and/* now parse path/parameters args, according to rfc1738 */
6ae232055d4d8a97267517c5e50074c2c819941and/* N.B. if this isn't a true proxy request, then the URL path
6ae232055d4d8a97267517c5e50074c2c819941and * (but not query args) has already been decoded.
6ae232055d4d8a97267517c5e50074c2c819941and * This gives rise to the problem of a ; being decoded into the
6a3ab831a34f470b077294a173f24fcf1e5f0a3ctakashi parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm,
6ae232055d4d8a97267517c5e50074c2c819941and path = ap_proxy_canonenc(p, url, strlen(url), enc_path, r->proxyreq);
6a3ab831a34f470b077294a173f24fcf1e5f0a3ctakashi strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, 1);
6ae232055d4d8a97267517c5e50074c2c819941and strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, 1);
6ae232055d4d8a97267517c5e50074c2c819941and/* now, rebuild URL */
6ae232055d4d8a97267517c5e50074c2c819941and r->filename = apr_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "",
befb6758d5618c60f29b19f9a7eb75ab993511dcjim * Returns the ftp status code;
6ae232055d4d8a97267517c5e50074c2c819941and * or -1 on I/O error, 0 on data error
0d0ba3a410038e179b695446bb149cce6264e0abnd/* check format */
0d0ba3a410038e179b695446bb149cce6264e0abnd if (len < 5 || !apr_isdigit(linebuff[0]) || !apr_isdigit(linebuff[1]) ||
0d0ba3a410038e179b695446bb149cce6264e0abnd !apr_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-'))
0d0ba3a410038e179b695446bb149cce6264e0abnd status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';
205f749042ed530040a4f0080dbcb47ceae8a374rjung/* skip continuation lines */
skiplf(f);
return status;
status = 0;
skiplf(f);
skiplf(f);
return status;
char *filename;
int searchidx = 0;
unsigned long total_bytes_sent = 0;
/* print "ftp://host/" */
++reldir;
if (c != NULL) {
ap_proxy_cache_error(&c);
filename--;
apr_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s\">%s %s</A>\n", buf, filename, filename, link_ptr);
*(filename++) = 0;
firstfile = 0;
total_bytes_sent += n;
cntr = n;
ap_proxy_cache_error(&c);
cntr = n;
return total_bytes_sent;
* ftp://user@host part of the reqest (sans password -if supplied but invalid-)
r->proxyreq = 0;
if (log_it)
return HTTP_UNAUTHORIZED;
BUFF *f;
const long int zero = 0L;
unsigned short pport;
int pasvmode = 0;
char *npaddr;
return HTTP_NOT_IMPLEMENTED;
return HTTP_INTERNAL_SERVER_ERROR;
return HTTP_INTERNAL_SERVER_ERROR;
i = ftp_getrc(f);
return HTTP_BAD_GATEWAY;
return ftp_unauthorized (r, 0);
ap_bflush(f);
i = ftp_getrc(f);
return HTTP_BAD_GATEWAY;
ap_bflush(f);
i = ftp_getrc(f);
return HTTP_NOT_FOUND;
return HTTP_BAD_GATEWAY;
ap_bflush(f);
i = ftp_getrc(f);
return HTTP_BAD_GATEWAY;
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
ap_bflush(f);
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
!= APR_SUCCESS) {
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
ap_bclose(f);
return HTTP_INTERNAL_SERVER_ERROR;
if (len == 0) {
ap_bflush(f);
ap_bflush(f);
i = ftp_getrc(f);
return HTTP_NOT_FOUND;
return HTTP_BAD_GATEWAY;
len = 0;
#ifdef AUTODETECT_PWD
ap_bflush(f);
return HTTP_NOT_FOUND;
if (len != 0)
ap_bflush(f);
ap_bflush(f);
return HTTP_NOT_FOUND;
return HTTP_BAD_GATEWAY;
#ifdef AUTODETECT_PWD
ap_bflush(f);
return HTTP_NOT_FOUND;
ap_bflush(f);
return HTTP_BAD_GATEWAY;
if (i != DECLINED) {
ap_bclose(f);
ap_proxy_cache_error(&c);
case APR_EINTR:
case APR_SUCCESS:
ap_bclose(f);
return HTTP_BAD_GATEWAY;
if (!r->assbackwards)
ap_proxy_cache_error(&c);
if (!r->assbackwards)
ap_proxy_cache_error(&c);
if (!r->header_only) {
ap_proxy_cache_error(&c);
ap_bflush(f);
if (!pasvmode)
i = ftp_getrc(f);
ap_bflush(f);
i = ftp_getrc(f);
if (pasvmode)
ap_bclose(f);
if(c) ap_proxy_cache_update(c);
return OK;