Lines 63-75
Link Here
|
63 |
* Escape the globbing characters in a path used as argument to |
63 |
* Escape the globbing characters in a path used as argument to |
64 |
* the FTP commands (SIZE, CWD, RETR, MDTM, ...). |
64 |
* the FTP commands (SIZE, CWD, RETR, MDTM, ...). |
65 |
* ftpd assumes '\\' as a quoting character to escape special characters. |
65 |
* ftpd assumes '\\' as a quoting character to escape special characters. |
|
|
66 |
* Just returns the original string if ProxyFtpEscapeWildcards has been |
67 |
* configured "off". |
66 |
* Returns: escaped string |
68 |
* Returns: escaped string |
67 |
*/ |
69 |
*/ |
68 |
#define FTP_GLOBBING_CHARS "*?[{~" |
70 |
#define FTP_GLOBBING_CHARS "*?[{~" |
69 |
static char *ftp_escape_globbingchars(apr_pool_t *p, const char *path) |
71 |
static const char *ftp_escape_globbingchars(apr_pool_t *p, const char *path, proxy_dir_conf *dconf) |
70 |
{ |
72 |
{ |
71 |
char *ret = apr_palloc(p, 2*strlen(path)+sizeof("")); |
73 |
char *ret; |
72 |
char *d; |
74 |
char *d; |
|
|
75 |
|
76 |
if (!dconf->ftp_escape_wildcards) { |
77 |
return path; |
78 |
} |
79 |
|
80 |
ret = apr_palloc(p, 2*strlen(path)+sizeof("")); |
73 |
for (d = ret; *path; ++path) { |
81 |
for (d = ret; *path; ++path) { |
74 |
if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) |
82 |
if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) |
75 |
*d++ = '\\'; |
83 |
*d++ = '\\'; |
Lines 809-814
Link Here
|
809 |
#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) |
817 |
#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) |
810 |
apr_time_t mtime = 0L; |
818 |
apr_time_t mtime = 0L; |
811 |
#endif |
819 |
#endif |
|
|
820 |
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, |
821 |
&proxy_module); |
812 |
|
822 |
|
813 |
/* stuff for PASV mode */ |
823 |
/* stuff for PASV mode */ |
814 |
int connect = 0, use_port = 0; |
824 |
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 |
1167 |
* We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH |
1158 |
*/ |
1168 |
*/ |
1159 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1169 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1160 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1170 |
ftp_escape_globbingchars(p, path, dconf), CRLF, NULL), |
1161 |
r, origin, bb, &ftpmessage); |
1171 |
r, origin, bb, &ftpmessage); |
1162 |
*strp = '/'; |
1172 |
*strp = '/'; |
1163 |
/* responses: 250, 421, 500, 501, 502, 530, 550 */ |
1173 |
/* responses: 250, 421, 500, 501, 502, 530, 550 */ |
Lines 1480-1488
Link Here
|
1480 |
} |
1490 |
} |
1481 |
|
1491 |
|
1482 |
/* If len == 0 then it must be a directory (you can't RETR nothing) |
1492 |
/* 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 |
1493 |
* Also, don't allow to RETR by wildcard. Instead, create a dirlisting, |
|
|
1494 |
* unless ProxyFtpListOnWildcard is off. |
1484 |
*/ |
1495 |
*/ |
1485 |
if (len == 0 || ftp_check_globbingchars(path)) { |
1496 |
if (len == 0 || (ftp_check_globbingchars(path) && dconf->ftp_list_on_wildcard)) { |
1486 |
dirlisting = 1; |
1497 |
dirlisting = 1; |
1487 |
} |
1498 |
} |
1488 |
else { |
1499 |
else { |
Lines 1503-1509
Link Here
|
1503 |
/* Therefore: switch to binary if the user did not specify ";type=a" */ |
1514 |
/* Therefore: switch to binary if the user did not specify ";type=a" */ |
1504 |
ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); |
1515 |
ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); |
1505 |
rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", |
1516 |
rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", |
1506 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1517 |
ftp_escape_globbingchars(p, path, dconf), CRLF, NULL), |
1507 |
r, origin, bb, &ftpmessage); |
1518 |
r, origin, bb, &ftpmessage); |
1508 |
if (rc == -1 || rc == 421) { |
1519 |
if (rc == -1 || rc == 421) { |
1509 |
return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, |
1520 |
return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, |
Lines 1522-1528
Link Here
|
1522 |
"proxy: FTP: SIZE shows this is a directory"); |
1533 |
"proxy: FTP: SIZE shows this is a directory"); |
1523 |
dirlisting = 1; |
1534 |
dirlisting = 1; |
1524 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1535 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1525 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1536 |
ftp_escape_globbingchars(p, path, dconf), CRLF, NULL), |
1526 |
r, origin, bb, &ftpmessage); |
1537 |
r, origin, bb, &ftpmessage); |
1527 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1538 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1528 |
/* 250 Requested file action okay, completed. */ |
1539 |
/* 250 Requested file action okay, completed. */ |
Lines 1583-1589
Link Here
|
1583 |
* The "." and subsequent digits ("sss") are optional. <..> |
1594 |
* The "." and subsequent digits ("sss") are optional. <..> |
1584 |
* Time values are always represented in UTC (GMT) |
1595 |
* Time values are always represented in UTC (GMT) |
1585 |
*/ |
1596 |
*/ |
1586 |
rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path), CRLF, NULL), |
1597 |
rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path, dconf), CRLF, NULL), |
1587 |
r, origin, bb, &ftpmessage); |
1598 |
r, origin, bb, &ftpmessage); |
1588 |
/* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ |
1599 |
/* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ |
1589 |
if (rc == 213) { |
1600 |
if (rc == 213) { |
Lines 1622-1628
Link Here
|
1622 |
} |
1633 |
} |
1623 |
#endif /* USE_MDTM */ |
1634 |
#endif /* USE_MDTM */ |
1624 |
/* FIXME: Handle range requests - send REST */ |
1635 |
/* FIXME: Handle range requests - send REST */ |
1625 |
buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path), CRLF, NULL); |
1636 |
buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path, dconf), CRLF, NULL); |
1626 |
} |
1637 |
} |
1627 |
rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); |
1638 |
rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); |
1628 |
/* rc is an intermediate response for the LIST or RETR commands */ |
1639 |
/* 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); |
1670 |
ftp_set_TYPE('A', r, origin, bb, NULL); |
1660 |
|
1671 |
|
1661 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1672 |
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", |
1662 |
ftp_escape_globbingchars(p, path), CRLF, NULL), |
1673 |
ftp_escape_globbingchars(p, path, dconf), CRLF, NULL), |
1663 |
r, origin, bb, &ftpmessage); |
1674 |
r, origin, bb, &ftpmessage); |
1664 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1675 |
/* possible results: 250, 421, 500, 501, 502, 530, 550 */ |
1665 |
/* 250 Requested file action okay, completed. */ |
1676 |
/* 250 Requested file action okay, completed. */ |
Lines 1709-1717
Link Here
|
1709 |
|
1720 |
|
1710 |
/* set content-type */ |
1721 |
/* set content-type */ |
1711 |
if (dirlisting) { |
1722 |
if (dirlisting) { |
1712 |
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, |
|
|
1713 |
&proxy_module); |
1714 |
|
1715 |
ap_set_content_type(r, apr_pstrcat(p, "text/html;charset=", |
1723 |
ap_set_content_type(r, apr_pstrcat(p, "text/html;charset=", |
1716 |
dconf->ftp_directory_charset ? |
1724 |
dconf->ftp_directory_charset ? |
1717 |
dconf->ftp_directory_charset : |
1725 |
dconf->ftp_directory_charset : |