Lines 37-42
Link Here
|
37 |
|
37 |
|
38 |
module AP_MODULE_DECLARE_DATA proxy_ftp_module; |
38 |
module AP_MODULE_DECLARE_DATA proxy_ftp_module; |
39 |
|
39 |
|
|
|
40 |
typedef struct { |
41 |
int ftp_list_on_wildcard; |
42 |
int ftp_list_on_wildcard_set; |
43 |
int ftp_escape_wildcards; |
44 |
int ftp_escape_wildcards_set; |
45 |
} proxy_ftp_dir_conf; |
46 |
|
47 |
static void *create_proxy_ftp_dir_config(apr_pool_t *p, char *dummy) |
48 |
{ |
49 |
proxy_ftp_dir_conf *new = |
50 |
(proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf)); |
51 |
|
52 |
/* Put these in the dir config so they work inside <Location> */ |
53 |
new->ftp_list_on_wildcard = 1; |
54 |
new->ftp_escape_wildcards = 1; |
55 |
|
56 |
return (void *) new; |
57 |
} |
58 |
|
59 |
static void *merge_proxy_ftp_dir_config(apr_pool_t *p, void *basev, void *addv) |
60 |
{ |
61 |
proxy_ftp_dir_conf *new = (proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf)); |
62 |
proxy_ftp_dir_conf *add = (proxy_ftp_dir_conf *) addv; |
63 |
proxy_ftp_dir_conf *base = (proxy_ftp_dir_conf *) basev; |
64 |
|
65 |
/* Put these in the dir config so they work inside <Location> */ |
66 |
new->ftp_list_on_wildcard = add->ftp_list_on_wildcard_set ? |
67 |
add->ftp_list_on_wildcard : |
68 |
base->ftp_list_on_wildcard; |
69 |
new->ftp_list_on_wildcard_set = add->ftp_list_on_wildcard_set ? |
70 |
1 : |
71 |
base->ftp_list_on_wildcard_set; |
72 |
new->ftp_escape_wildcards = add->ftp_escape_wildcards_set ? |
73 |
add->ftp_escape_wildcards : |
74 |
base->ftp_escape_wildcards; |
75 |
new->ftp_escape_wildcards_set = add->ftp_escape_wildcards_set ? |
76 |
1 : |
77 |
base->ftp_escape_wildcards_set; |
78 |
|
79 |
return new; |
80 |
} |
81 |
|
82 |
static const char *set_ftp_list_on_wildcard(cmd_parms *cmd, void *dconf, |
83 |
int flag) |
84 |
{ |
85 |
proxy_ftp_dir_conf *conf = dconf; |
86 |
|
87 |
conf->ftp_list_on_wildcard = flag; |
88 |
conf->ftp_list_on_wildcard_set = 1; |
89 |
return NULL; |
90 |
} |
91 |
|
92 |
static const char *set_ftp_escape_wildcards(cmd_parms *cmd, void *dconf, |
93 |
int flag) |
94 |
{ |
95 |
proxy_ftp_dir_conf *conf = dconf; |
96 |
|
97 |
conf->ftp_escape_wildcards = flag; |
98 |
conf->ftp_escape_wildcards_set = 1; |
99 |
return NULL; |
100 |
} |
101 |
|
40 |
/* |
102 |
/* |
41 |
* Decodes a '%' escaped string, and returns the number of characters |
103 |
* Decodes a '%' escaped string, and returns the number of characters |
42 |
*/ |
104 |
*/ |
Lines 63-75
Link Here
|
63 |
* Escape the globbing characters in a path used as argument to |
125 |
* Escape the globbing characters in a path used as argument to |
64 |
* the FTP commands (SIZE, CWD, RETR, MDTM, ...). |
126 |
* the FTP commands (SIZE, CWD, RETR, MDTM, ...). |
65 |
* ftpd assumes '\\' as a quoting character to escape special characters. |
127 |
* ftpd assumes '\\' as a quoting character to escape special characters. |
|
|
128 |
* Just returns the original string if ProxyFtpEscapeWildcards has been |
129 |
* configured "off". |
66 |
* Returns: escaped string |
130 |
* Returns: escaped string |
67 |
*/ |
131 |
*/ |
68 |
#define FTP_GLOBBING_CHARS "*?[{~" |
132 |
#define FTP_GLOBBING_CHARS "*?[{~" |
69 |
static char *ftp_escape_globbingchars(apr_pool_t *p, const char *path) |
133 |
static const char *ftp_escape_globbingchars(apr_pool_t *p, const char *path, proxy_ftp_dir_conf *dconf) |
70 |
{ |
134 |
{ |
71 |
char *ret = apr_palloc(p, 2*strlen(path)+sizeof("")); |
135 |
char *ret; |
72 |
char *d; |
136 |
char *d; |
|
|
137 |
|
138 |
if (!dconf->ftp_escape_wildcards) { |
139 |
return path; |
140 |
} |
141 |
|
142 |
ret = apr_palloc(p, 2*strlen(path)+sizeof("")); |
73 |
for (d = ret; *path; ++path) { |
143 |
for (d = ret; *path; ++path) { |
74 |
if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) |
144 |
if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) |
75 |
*d++ = '\\'; |
145 |
*d++ = '\\'; |
Lines 809-814
Link Here
|
809 |
#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) |
879 |
#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) |
810 |
apr_time_t mtime = 0L; |
880 |
apr_time_t mtime = 0L; |
811 |
#endif |
881 |
#endif |
|
|
882 |
proxy_ftp_dir_conf *fdconf = ap_get_module_config(r->per_dir_config, |
883 |
&proxy_ftp_module); |
812 |
|
884 |
|
813 |
/* stuff for PASV mode */ |
885 |
/* stuff for PASV mode */ |
814 |
int connect = 0, use_port = 0; |
886 |
int connect = 0, use_port = 0; |
Lines 1157-1163
Link Here
|
1157 |
* We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH |
1229 |
* We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH |
1158 |
*/ |
1230 |
*/ |
1159 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1231 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1160 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1232 |
ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL), |
1161 |
r, origin, bb, &ftpmessage); |
1233 |
r, origin, bb, &ftpmessage); |
1162 |
*strp = '/'; |
1234 |
*strp = '/'; |
1163 |
/* responses: 250, 421, 500, 501, 502, 530, 550 */ |
1235 |
/* responses: 250, 421, 500, 501, 502, 530, 550 */ |
Lines 1480-1488
Link Here
|
1480 |
} |
1552 |
} |
1481 |
|
1553 |
|
1482 |
/* If len == 0 then it must be a directory (you can't RETR nothing) |
1554 |
/* If len == 0 then it must be a directory (you can't RETR nothing) |
1483 |
* Also, don't allow to RETR by wildcard. Instead, create a dirlisting |
1555 |
* Also, don't allow to RETR by wildcard. Instead, create a dirlisting, |
|
|
1556 |
* unless ProxyFtpListOnWildcard is off. |
1484 |
*/ |
1557 |
*/ |
1485 |
if (len == 0 || ftp_check_globbingchars(path)) { |
1558 |
if (len == 0 || (ftp_check_globbingchars(path) && fdconf->ftp_list_on_wildcard)) { |
1486 |
dirlisting = 1; |
1559 |
dirlisting = 1; |
1487 |
} |
1560 |
} |
1488 |
else { |
1561 |
else { |
Lines 1503-1509
Link Here
|
1503 |
/* Therefore: switch to binary if the user did not specify ";type=a" */ |
1576 |
/* Therefore: switch to binary if the user did not specify ";type=a" */ |
1504 |
ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); |
1577 |
ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); |
1505 |
rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", |
1578 |
rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", |
1506 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1579 |
ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL), |
1507 |
r, origin, bb, &ftpmessage); |
1580 |
r, origin, bb, &ftpmessage); |
1508 |
if (rc == -1 || rc == 421) { |
1581 |
if (rc == -1 || rc == 421) { |
1509 |
return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, |
1582 |
return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, |
Lines 1522-1528
Link Here
|
1522 |
"proxy: FTP: SIZE shows this is a directory"); |
1595 |
"proxy: FTP: SIZE shows this is a directory"); |
1523 |
dirlisting = 1; |
1596 |
dirlisting = 1; |
1524 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1597 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1525 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1598 |
ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL), |
1526 |
r, origin, bb, &ftpmessage); |
1599 |
r, origin, bb, &ftpmessage); |
1527 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1600 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1528 |
/* 250 Requested file action okay, completed. */ |
1601 |
/* 250 Requested file action okay, completed. */ |
Lines 1583-1589
Link Here
|
1583 |
* The "." and subsequent digits ("sss") are optional. <..> |
1656 |
* The "." and subsequent digits ("sss") are optional. <..> |
1584 |
* Time values are always represented in UTC (GMT) |
1657 |
* Time values are always represented in UTC (GMT) |
1585 |
*/ |
1658 |
*/ |
1586 |
rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path), CRLF, NULL), |
1659 |
rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL), |
1587 |
r, origin, bb, &ftpmessage); |
1660 |
r, origin, bb, &ftpmessage); |
1588 |
/* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ |
1661 |
/* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ |
1589 |
if (rc == 213) { |
1662 |
if (rc == 213) { |
Lines 1622-1628
Link Here
|
1622 |
} |
1695 |
} |
1623 |
#endif /* USE_MDTM */ |
1696 |
#endif /* USE_MDTM */ |
1624 |
/* FIXME: Handle range requests - send REST */ |
1697 |
/* FIXME: Handle range requests - send REST */ |
1625 |
buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path), CRLF, NULL); |
1698 |
buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL); |
1626 |
} |
1699 |
} |
1627 |
rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); |
1700 |
rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); |
1628 |
/* rc is an intermediate response for the LIST or RETR commands */ |
1701 |
/* rc is an intermediate response for the LIST or RETR commands */ |
Lines 1659-1665
Link Here
|
1659 |
ftp_set_TYPE('A', r, origin, bb, NULL); |
1732 |
ftp_set_TYPE('A', r, origin, bb, NULL); |
1660 |
|
1733 |
|
1661 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1734 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1662 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1735 |
ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL), |
1663 |
r, origin, bb, &ftpmessage); |
1736 |
r, origin, bb, &ftpmessage); |
1664 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1737 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1665 |
/* 250 Requested file action okay, completed. */ |
1738 |
/* 250 Requested file action okay, completed. */ |
Lines 1929-1940
Link Here
|
1929 |
NULL, AP_FTYPE_RESOURCE); |
2002 |
NULL, AP_FTYPE_RESOURCE); |
1930 |
} |
2003 |
} |
1931 |
|
2004 |
|
|
|
2005 |
static const command_rec proxy_ftp_cmds[] = |
2006 |
{ |
2007 |
AP_INIT_FLAG("ProxyFtpListOnWildcard", set_ftp_list_on_wildcard, NULL, |
2008 |
RSRC_CONF|ACCESS_CONF, "Whether wildcard characters in a path cause mod_proxy_ftp to list the files instead of trying to get them."), |
2009 |
AP_INIT_FLAG("ProxyFtpEscapeWildcards", set_ftp_escape_wildcards, NULL, |
2010 |
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."), |
2011 |
{NULL} |
2012 |
}; |
2013 |
|
2014 |
|
1932 |
module AP_MODULE_DECLARE_DATA proxy_ftp_module = { |
2015 |
module AP_MODULE_DECLARE_DATA proxy_ftp_module = { |
1933 |
STANDARD20_MODULE_STUFF, |
2016 |
STANDARD20_MODULE_STUFF, |
1934 |
NULL, /* create per-directory config structure */ |
2017 |
create_proxy_ftp_dir_config,/* create per-directory config structure */ |
1935 |
NULL, /* merge per-directory config structures */ |
2018 |
merge_proxy_ftp_dir_config, /* merge per-directory config structures */ |
1936 |
NULL, /* create per-server config structure */ |
2019 |
NULL, /* create per-server config structure */ |
1937 |
NULL, /* merge per-server config structures */ |
2020 |
NULL, /* merge per-server config structures */ |
1938 |
NULL, /* command apr_table_t */ |
2021 |
proxy_ftp_cmds, /* command apr_table_t */ |
1939 |
ap_proxy_ftp_register_hook /* register hooks */ |
2022 |
ap_proxy_ftp_register_hook /* register hooks */ |
1940 |
}; |
2023 |
}; |