You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2007/12/06 19:50:10 UTC
svn commit: r601812 - /httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
Author: wrowe
Date: Thu Dec 6 10:50:09 2007
New Revision: 601812
URL: http://svn.apache.org/viewvc?rev=601812&view=rev
Log:
Fix PORT/EPRT proxy error reporting, enhance EPRT parsing to compare
after the requested port is canonicalize, and increase strictness of
the PORT command to catch trailing invalid garbage.
Modified:
httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
Modified: httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c
URL: http://svn.apache.org/viewvc/httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c?rev=601812&r1=601811&r2=601812&view=diff
==============================================================================
--- httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c (original)
+++ httpd/mod_ftp/trunk/modules/ftp/ftp_commands.c Thu Dec 6 10:50:09 2007
@@ -1724,28 +1724,6 @@
return res;
}
- /* Open data connection only if the PORT connection is to the client's
- * IP address.
- * All other PORT connection requests are denied, unless disabled using:
- *
- * FTPOptions AllowProxyPORT
- */
- if (!(fsc->options & FTP_OPT_ALLOWPROXYPORT)) {
- /* XXX: Match IPv6 ip_addr strings where c->remote_ip is IPv4 mapped */
- if (strcasecmp(ip_addr, c->remote_ip) != 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server,
- "PORT data connection request to %s "
- "doesn't match the client IP %s",
- ip_addr, c->remote_ip);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
- "PORT data connection request denied, "
- "not configured to AllowProxyPORT");
- fc->response_notes = apr_pstrdup(r->pool,
- "Invalid PORT command, proxy PORT is not permitted");
- return FTP_REPLY_SYNTAX_ERROR;
- }
- }
-
#if 0
if ((fsc->active_min != -1) && (fsc->active_min < 1024)) {
/* Here's the case of low numbered port creation; the only way
@@ -1780,19 +1758,23 @@
sa->port = 0;
}
- /* XXX: Handle IPv6 ip_addr string where c->remote_ip is IPv4 mapped */
- if ((c->local_addr->family == APR_INET) && (family == APR_INET)) {
- apr_sockaddr_info_get(&sa, c->local_ip, family,
- sa->port, 0, c->pool);
- }
- else if ((c->local_addr->family == APR_INET6) && (family == APR_INET6)) {
+ /* XXX: Anything special to handle IPv6 ip_addr string where c->remote_ip
+ * is IPv4 mapped?
+ */
+ if (((c->local_addr->family == APR_INET) && (family == APR_INET)) ||
+#if APR_HAVE_IPV6
+ ((c->local_addr->family == APR_INET6) && (family == APR_INET6))
+#endif
+ ) {
apr_sockaddr_info_get(&sa, c->local_ip, family,
sa->port, 0, c->pool);
}
else {
+ /* If the family differs, it's difficult to map the EPRT origin IP */
apr_sockaddr_info_get(&sa, NULL, family,
sa->port, 0, c->pool);
}
+
apr_socket_opt_set(s, APR_SO_REUSEADDR, 1);
rv = apr_socket_bind(s, sa);
@@ -1807,9 +1789,45 @@
}
apr_socket_addr_get(&fc->clientsa, APR_LOCAL, s);
- apr_sockaddr_info_get(&fc->clientsa, ip_addr, family,
- port, 0, c->pool);
+ rv = apr_sockaddr_info_get(&fc->clientsa, ip_addr, family,
+ port, 0, c->pool);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
+ "Unable to decode EPRT request |%d|%s|%d|",
+#if APR_HAVE_IPV6
+ (family == APR_INET6) ? 2 : 1, ip_addr, port);
+#else
+ 1, ip_addr, port);
+#endif
+ fc->response_notes = apr_pstrdup(r->pool,
+ "Invalid EPRT command, unable to decode request");
+ return FTP_REPLY_SYNTAX_ERROR;
+ }
+ /* Open data connection only if the EPRT connection is to the client's
+ * IP address.
+ * All other EPRT connection requests are denied, unless disabled using:
+ *
+ * FTPOptions AllowProxyPORT
+ *
+ * We must canonicalize the IP address first to compare it to our own
+ * idea of the client's IP address.
+ */
+ if (!(fsc->options & FTP_OPT_ALLOWPROXYPORT)) {
+ char *test_ip = "(unknown)";
+ if (apr_sockaddr_ip_get(&test_ip, fc->clientsa) != APR_SUCCESS
+ || (strcasecmp(test_ip, c->remote_ip) != 0)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
+ "Rejected EPRT data connection request to %s "
+ "(doesn't match the client IP %s and "
+ "not configured to AllowProxyPORT)",
+ test_ip, c->remote_ip);
+ fc->response_notes = apr_pstrdup(r->pool,
+ "Invalid EPRT command, proxy EPRT is not permitted");
+ return FTP_REPLY_SYNTAX_ERROR;
+ }
+ }
+
fc->response_notes = apr_psprintf(r->pool, FTP_MSG_SUCCESS, r->method);
fc->passive_created = -1; /* Redundant but just for clarity */
fc->csock = s;
@@ -1824,7 +1842,7 @@
apr_sockaddr_t *sa;
apr_socket_t *s;
apr_status_t rv;
- char *ip_addr;
+ char *ip_addr, tc;
short port;
int res, val[6];
@@ -1839,8 +1857,8 @@
fc->passive_created = -1;
}
- if ((res = sscanf(arg, "%d,%d,%d,%d,%d,%d", &val[0], &val[1], &val[2],
- &val[3], &val[4], &val[5])) != 6) {
+ if ((res = sscanf(arg, "%d,%d,%d,%d,%d,%d%c", &val[0], &val[1], &val[2],
+ &val[3], &val[4], &val[5], &tc)) != 6) {
fc->response_notes = apr_pstrdup(r->pool, "Invalid PORT request");
return FTP_REPLY_SYNTAX_ERROR;
}
@@ -1857,14 +1875,13 @@
*/
if (!(fsc->options & FTP_OPT_ALLOWPROXYPORT)) {
if (strcasecmp(ip_addr, c->remote_ip) != 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server,
- "PORT data connection request to %s "
- "doesn't match the client IP %s",
- ip_addr, c->remote_ip);
ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
- "PORT data connection request denied, "
- "not configured to AllowProxyPORT");
- fc->response_notes = apr_pstrdup(r->pool, "Invalid PORT command, proxy PORT is not permitted");
+ "Rejected PORT data connection request to %s "
+ "(doesn't match the client IP %s and "
+ "not configured to AllowProxyPORT)",
+ ip_addr, c->remote_ip);
+ fc->response_notes = apr_pstrdup(r->pool,
+ "Invalid PORT command, proxy PORT is not permitted");
return FTP_REPLY_SYNTAX_ERROR;
}
}