19#define APR_WANT_BYTEFUNC
34module AP_MODULE_DECLARE_DATA proxy_ftp_module;
51 new->ftp_escape_wildcards = 1;
65 base->ftp_list_on_wildcard;
68 base->ftp_list_on_wildcard_set;
71 base->ftp_escape_wildcards;
74 base->ftp_escape_wildcards_set;
77 base->ftp_directory_charset;
119 for (
i = 0, j = 0; x[
i] !=
'\0';
i++, j++) {
140#define FTP_GLOBBING_CHARS "*?[{~"
184#if APR_CHARSET_EBCDIC
188 for (
i = 0; x[
i] !=
'\0';
i++) {
194#if !APR_CHARSET_EBCDIC
195 if (
ch ==
'\015' ||
ch ==
'\012' || (
ch & 0x80))
197 if (
ch ==
'\r' ||
ch ==
'\n')
251 (
const char **)&response,
375#define MAX_LINE_LEN 80
406 !
apr_isdigit(response[2]) || (response[3] !=
' ' && response[3] !=
'-'))
409 status = 100 * response[0] + 10 * response[1] + response[2] - 111 *
'0';
413 if (response[3] ==
'-') {
445#define LS_REG_PATTERN "^ *([0-9]+) +([^ ]+)$"
446#define LS_REG_MATCH 3
476 if (HEADER ==
ctx->state) {
515 while (
path[1] ==
'/')
531 str = (
basedir[0] !=
'\0') ?
"<a href=\"/%2f/\">%2f</a>/" :
"";
536 "<html>\n <head>\n <title>%s%s%s</title>\n"
537 "<base href=\"%s%s%s\">\n"
539 " <body>\n <h2>Directory of "
540 "<a href=\"/\">%s</a>/%s",
546 p,
c->bucket_alloc));
584 p,
c->bucket_alloc));
607 while (BODY ==
ctx->state) {
616 char *pos, *response;
630 if ((response +
len) != (pos + 1)) {
631 len = pos - response + 1;
636 max =
sizeof(
ctx->buffer) - strlen(
ctx->buffer) - 1;
661 ctx->buffer[--
n] =
'\0';
663 ctx->buffer[--
n] =
'\0';
684 else if (
ctx->buffer[0] ==
'd' ||
ctx->buffer[0] ==
'-' ||
ctx->buffer[0] ==
'l' ||
apr_isdigit(
ctx->buffer[0])) {
701 "proxy_ftp: could not parse line %s",
764 if (FOOTER ==
ctx->state) {
790 if (
p ==
NULL || !
p[1] ||
p[1] !=
p[2] ||
p[1] !=
p[3]
837 if (
rc == -1 ||
rc == 421)
870 if (
rc == -1 ||
rc == 421) {
872 "Error reading from remote server");
874 else if (
rc != 200 &&
rc != 504) {
876 "Unable to set transfer type");
879 else if (
rc == 504) {
905 "Failed to read PWD on ftp server");
933 "missing or failed auth to %s",
994#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF))
1009 "declining URL %s - proxyhost %s specified:",
url,
1015 "declining URL %s - not ftp:",
url);
1035 "URI cannot be parsed: %s",
url);
1067 "ftp proxy supports only types 'a', 'i', or 'e': \"",
1090 "user credentials contained invalid character");
1140 "Error resolving backend address");
1146 "Connect to remote machine blocked");
1172 "control connection complete");
1189 if (
rc == -1 ||
rc == 421) {
1234 if (
rc == -1 ||
rc == 421) {
1242 if (
rc != 230 &&
rc != 331) {
1262 if (
rc == -1 ||
rc == 421) {
1264 "Error reading from remote server");
1276 if (
rc != 230 &&
rc != 202) {
1288 while (*
path ==
'/')
1292 if (
rc == -1 ||
rc == 421)
1294 "Error reading from remote server");
1311 "Use of /%2f is only allowed at the base directory");
1331 if (
rc == -1 ||
rc == 421) {
1333 "Error reading from remote server");
1372 if (
rc == -1 ||
rc == 421) {
1374 "Error reading from remote server");
1376 if (
rc != 229 &&
rc != 500 &&
rc != 501 &&
rc != 502) {
1379 else if (
rc == 229) {
1387 "EPSV contacting remote host on port %d",
data_port);
1413 "could not establish socket for client data connection");
1422 "apr_socket_opt_set(SO_RCVBUF): Failed to "
1423 "set ProxyReceiveBufferSize, using default");
1429 "apr_socket_opt_set(APR_TCP_NODELAY): "
1436 "EPSV attempt to connect to %pI failed - "
1439 "EPSV attempt to connect to %pI failed - firewall/NAT?", &
epsv_addr));
1443 "connected data socket to %pI", &
epsv_addr);
1461 if (
rc == -1 ||
rc == 421) {
1463 "Error reading from remote server");
1465 if (
rc != 227 &&
rc != 502) {
1468 else if (
rc == 227) {
1478 if (*(
pstr + strlen(
pstr) + 1) ==
'=') {
1492 "%d,%d,%d,%d,%d,%d", &
h3, &
h2, &
h1, &
h0, &
p1, &
p0) == 6)) {
1497 "PASV contacting host %d.%d.%d.%d:%d",
1503 "error creating PASV socket");
1512 "apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
1518 "apr_socket_opt_set(APR_TCP_NODELAY): "
1534 "PASV attempt to connect to %pI failed - Firewall/NAT?",
pasv_addr);
1536 "PASV attempt to connect to %pI failed - firewall/NAT?",
pasv_addr));
1556 "error creating local socket");
1568 "error setting reuseaddr option");
1583 "error binding to ftp data socket %pI", local_addr);
1591 "error listening to ftp data socket %pI", local_addr);
1598 if (local_ip && (
sscanf(local_ip,
1599 "%d.%d.%d.%d", &
h3, &
h2, &
h1, &
h0) == 4)) {
1603 rc =
proxy_ftp_command(
apr_psprintf(
p,
"PORT %d,%d,%d,%d,%d,%d" CRLF,
h3,
h2,
h1,
h0,
p1,
p0),
1612 if (
rc == -1 ||
rc == 421) {
1614 "Error reading from remote server");
1631 "Connect to IPV6 ftp server using EPRT not supported. Enable EPSV.");
1647 "Use of /%2f is only allowed at the base directory");
1677 if (
rc == -1 ||
rc == 421) {
1679 "Error reading from remote server");
1681 else if (
rc == 213) {
1689 else if (
rc == 550) {
1691 "SIZE shows this is a directory");
1704 if (
rc == -1 ||
rc == 421) {
1706 "Error reading from remote server");
1744#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF))
1818 if (
rc == -1 ||
rc == 421) {
1820 "Error reading from remote server");
1824 "RETR failed, trying LIST instead");
1841 if (
rc == -1 ||
rc == 421) {
1843 "Error reading from remote server");
1864 if (
rc == -1 ||
rc == 421)
1866 "Error reading from remote server");
1868 if (
rc != 125 &&
rc != 150 &&
rc != 226 &&
rc != 250) {
1882 fdconf->ftp_directory_charset ?
1883 fdconf->ftp_directory_charset :
1884 "ISO-8859-1",
NULL));
1891 "Content-Length set to %s",
size);
1900#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF))
1906 "Last-Modified set to %s",
datestr);
1936 "failed to accept data connection");
1952 "an error occurred creating the transfer connection");
1966 "pre_connection setup failed (%d)",
rc);
2025 "data connection closed");
2031 if (
FALSE == finish) {
2047 if (
TRUE == finish) {
2099 RSRC_CONF|
ACCESS_CONF,
"Whether wildcard characters in a path cause mod_proxy_ftp to list the files instead of trying to get them. Defaults to on."),
2101 RSRC_CONF|
ACCESS_CONF,
"Whether the proxy should escape wildcards in paths before sending them to the FTP server. Defaults to on, but most FTP servers will need it turned off if you need to manage paths that contain wildcard characters."),
const char apr_size_t len
char * strstr(char *s1, char *s2)
apr_size_t const unsigned char unsigned int unsigned int d
APR Versioning Interface.
int ap_run_pre_connection(conn_rec *c, void *csd)
conn_rec * ap_run_create_connection(apr_pool_t *p, server_rec *server, apr_socket_t *csd, long conn_id, void *sbh, apr_bucket_alloc_t *alloc)
void ap_flush_conn(conn_rec *c)
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
#define ap_set_module_config(v, m, val)
request_rec int int apr_table_t const char * path
const char * ap_get_server_description(void)
#define ap_xlate_proto_to_ascii(x, y)
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
ap_filter_rec_t * ap_register_output_filter(const char *name, ap_out_filter_func filter_func, ap_init_filter_func filter_init, ap_filter_type ftype)
ap_filter_t * ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
#define ap_get_core_module_config(v)
char * ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r)
const unsigned char * buf
void ap_set_content_type(request_rec *r, const char *ct)
const char apr_port_t port
#define APR_STATUS_IS_EINTR(s)
#define APR_BRIGADE_LAST(b)
#define APR_BRIGADE_INSERT_TAIL(b, e)
#define apr_bucket_split(e, point)
#define APR_BRIGADE_CONCAT(a, b)
#define APR_BRIGADE_EMPTY(b)
#define apr_bucket_delete(e)
#define APR_BUCKET_IS_EOS(e)
apr_brigade_flush void * ctx
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
const char apr_ssize_t int flags
#define APR_URI_UNP_OMITQUERY
#define APR_URI_UNP_OMITPATHINFO
#define APR_URI_UNP_OMITPASSWORD
#define APR_URI_UNP_OMITSITEPART
#define HTTP_SERVICE_UNAVAILABLE
#define HTTP_INTERNAL_SERVER_ERROR
#define HTTP_UNAUTHORIZED
#define HTTP_NOT_IMPLEMENTED
int ap_proxy_ssl_engine(conn_rec *c, ap_conf_vector_t *per_dir_config, int enable)
int ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, server_rec *s)
char * ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, char **passwordp, char **hostp, apr_port_t *port)
int ap_proxy_release_connection(const char *proxy_function, proxy_conn_rec *conn, server_rec *s)
int ap_proxy_acquire_connection(const char *proxy_function, proxy_conn_rec **conn, proxy_worker *worker, server_rec *s)
apr_status_t ap_proxy_determine_address(const char *proxy_function, proxy_conn_rec *conn, const char *hostname, apr_port_t hostport, unsigned int flags, request_rec *r, server_rec *s)
int ap_proxy_hex2c(const char *x)
char * ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len, enum enctype t, int flags, int proxyreq)
int ap_proxy_checkproxyblock2(request_rec *r, proxy_server_conf *conf, const char *hostname, apr_sockaddr_t *addr)
#define PROXY_CANONENC_NOENCODEDSLASHENCODING
void proxy_hook_canon_handler(proxy_HOOK_canon_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
int ap_proxy_connection_create_ex(const char *proxy_function, proxy_conn_rec *conn, request_rec *r)
int ap_proxyerror(request_rec *r, int statuscode, const char *message)
void proxy_hook_scheme_handler(proxy_HOOK_scheme_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
char * ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, int forcedec, int proxyreq)
#define STANDARD20_MODULE_STUFF
int ap_cstr_casecmp(const char *s1, const char *s2)
const char * ap_psignature(const char *prefix, request_rec *r)
char * ap_getword(apr_pool_t *p, const char **line, char stop)
#define ap_escape_uri(ppool, path)
#define ap_strchr_c(s, c)
char * ap_pbase64decode(apr_pool_t *p, const char *bufcoded)
char * ap_getword_nulls(apr_pool_t *p, const char **line, char stop)
int ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n)
#define ap_escape_html(p, s)
ap_regex_t * ap_pregcomp(apr_pool_t *p, const char *pattern, int cflags)
char * ap_getword_conf(apr_pool_t *p, const char **line)
const char apr_int32_t flag
void * memchr(const void *s, int c, size_t n)
const apr_hash_t const apr_hash_t * h2
apr_vformatter_buff_t * c
#define apr_pcalloc(p, size)
apr_size_t const char * filename
const char const char * password
apr_int32_t apr_int32_t apr_int32_t err
#define APR_RFC822_DATE_LEN
apr_size_t apr_size_t const char apr_time_exp_t * tm
apr_size_t apr_size_t max
Proxy Extension Module for Apache.
static apr_status_t proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *in)
static const char * set_ftp_list_on_wildcard(cmd_parms *cmd, void *dconf, int flag)
static int decodeenc(char *x)
static const char * set_ftp_directory_charset(cmd_parms *cmd, void *dconf, const char *arg)
static const char * ftp_escape_globbingchars(apr_pool_t *p, const char *path, proxy_ftp_dir_conf *dconf)
static int ftp_check_string(const char *x)
static apr_status_t proxy_ftp_cleanup(request_rec *r, proxy_conn_rec *backend)
static char * ftp_get_PWD(request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb)
static int ftp_set_TYPE(char xfer_type, request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char **pmessage)
static int ftp_unauthorized(request_rec *r, int log_it)
static void ap_proxy_ftp_register_hook(apr_pool_t *p)
static void * create_proxy_ftp_dir_config(apr_pool_t *p, char *dummy)
static int proxy_ftp_canon(request_rec *r, char *url)
static const char * set_ftp_escape_wildcards(cmd_parms *cmd, void *dconf, int flag)
static int ftp_check_globbingchars(const char *path)
static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyhost, apr_port_t proxyport)
static ap_regex_t * ls_regex
#define FTP_GLOBBING_CHARS
static int proxy_ftp_command(const char *cmd, request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char **pmessage)
static apr_port_t parse_epsv_reply(const char *reply)
static int ftp_getrc_msg(conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char *msgbuf, int msglen)
static const command_rec proxy_ftp_cmds[]
static int ftp_proxyerror(request_rec *r, proxy_conn_rec *conn, int statuscode, const char *message)
static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, apr_size_t bufflen, int *eos, apr_size_t *outlen)
static void * merge_proxy_ftp_dir_config(apr_pool_t *p, void *basev, void *addv)
The representation of a filter chain.
Structure to store things which are per connection.
struct ap_conf_vector_t * conn_config
Per-directory configuration.
int ftp_escape_wildcards_set
int ftp_list_on_wildcard_set
const char * ftp_directory_charset
apr_size_t recv_buffer_size
apr_size_t io_buffer_size
A structure that represents the current request.
const char * content_type
struct ap_filter_t * output_filters
apr_table_t * err_headers_out
struct ap_conf_vector_t * per_dir_config
const char * content_encoding
apr_table_t * headers_out
apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock, apr_pool_t *connection_context)
apr_status_t apr_socket_listen(apr_socket_t *sock, apr_int32_t backlog)
apr_status_t apr_socket_bind(apr_socket_t *sock, apr_sockaddr_t *sa)
apr_status_t apr_socket_close(apr_socket_t *thesocket)
apr_status_t apr_socket_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont)
apr_status_t apr_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
apr_status_t apr_rfc822_date(char *date_str, apr_time_t t)