You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2012/12/16 14:57:39 UTC

svn commit: r1422578 - in /httpd/httpd/branches/2.4.x: CHANGES STATUS modules/proxy/mod_proxy_ftp.c

Author: minfrin
Date: Sun Dec 16 13:57:38 2012
New Revision: 1422578

URL: http://svn.apache.org/viewvc?rev=1422578&view=rev
Log:
mod_proxy_ftp: Fix segfaults on IPv4 requests to hosts with DNS AAAA records.
PR 40841.

trunk patch: http://svn.apache.org/viewvc?rev=1404625&view=rev
             http://svn.apache.org/viewvc?rev=1420223&view=rev
2.4.x patch: http://people.apache.org/~jorton/proxyftpepsv-24.patch
Submitted by: jorton
Reviewed by: jim, minfrin

Modified:
    httpd/httpd/branches/2.4.x/CHANGES
    httpd/httpd/branches/2.4.x/STATUS
    httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c

Modified: httpd/httpd/branches/2.4.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CHANGES?rev=1422578&r1=1422577&r2=1422578&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x/CHANGES [utf-8] Sun Dec 16 13:57:38 2012
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.4.4
 
+  *) mod_proxy_ftp: Fix segfaults on IPv4 requests to hosts with DNS
+     AAAA records. PR  40841. [Andrew Rucker Jones <arjones simultan
+     dyndns org>, <ast domdv de>, Jim Jagielski]
+
   *) mod_auth_form: Make sure that get_notes_auth() sets the user as does
      get_form_auth() and get_session_auth(). Makes sure that REMOTE_USER
      does not vanish during mod_include driven subrequests. [Graham

Modified: httpd/httpd/branches/2.4.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/STATUS?rev=1422578&r1=1422577&r2=1422578&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/STATUS (original)
+++ httpd/httpd/branches/2.4.x/STATUS Sun Dec 16 13:57:38 2012
@@ -91,14 +91,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-   * mod_proxy_ftp: Fix segfaults on IPv4 requests to hosts with DNS AAAA records.
-     PR 40841.
-     trunk patch: http://svn.apache.org/viewvc?rev=1404625&view=rev
-                  http://svn.apache.org/viewvc?rev=1420223&view=rev
-     2.4.x patch: trunk patch works, or
-                  http://people.apache.org/~jorton/proxyftpepsv-24.patch
-     +1: jorton, jim, minfrin
-
    * mod_slotmem_*: Add in new fgrab() function which forces a grab and
      slot allocation on a specified slot. Allow for clearing of inuse
      array.

Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c?rev=1422578&r1=1422577&r2=1422578&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c (original)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c Sun Dec 16 13:57:38 2012
@@ -16,6 +16,7 @@
 
 /* FTP routines for Apache proxy */
 
+#define APR_WANT_BYTEFUNC
 #include "mod_proxy.h"
 #if APR_HAVE_TIME_H
 #include <time.h>
@@ -1377,8 +1378,6 @@ static int proxy_ftp_handler(request_rec
 
     /* set up data connection - EPSV */
     {
-        apr_sockaddr_t *data_addr;
-        char *data_ip;
         apr_port_t data_port;
 
         /*
@@ -1408,14 +1407,36 @@ static int proxy_ftp_handler(request_rec
             data_port = parse_epsv_reply(ftpmessage);
 
             if (data_port) {
-                apr_sockaddr_t *epsv_addr;
+                apr_sockaddr_t *remote_addr, epsv_addr;
 
                 ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                               "EPSV contacting remote host on port %d", data_port);
 
-                if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) {
-                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01040)
-                                  "error creating EPSV socket");
+                /* Retrieve the client's address. */
+                rv = apr_socket_addr_get(&remote_addr, APR_REMOTE, sock);
+                if (rv == APR_SUCCESS) {
+                    /* Take a shallow copy of the server address to
+                     * modify; the _addr_get function gives back a
+                     * pointer to the socket's internal structure.
+                     * This is awkward given current APR network
+                     * interfaces. */
+                    epsv_addr = *remote_addr;
+                    epsv_addr.port = data_port;
+#if APR_HAVE_IPV6
+                    if (epsv_addr.family == APR_INET6) {
+                        epsv_addr.sa.sin6.sin6_port = htons(data_port);
+                    }
+                    else
+#endif
+                    {
+                        epsv_addr.sa.sin.sin_port = htons(data_port);
+                    }
+                    rv = apr_socket_create(&data_sock, epsv_addr.family, SOCK_STREAM, 0, r->pool);
+                }
+
+                if (rv != APR_SUCCESS) {
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01040) 
+                                  "could not establish socket for client data connection");
                     proxy_ftp_cleanup(r, backend);
                     return HTTP_INTERNAL_SERVER_ERROR;
                 }
@@ -1435,19 +1456,17 @@ static int proxy_ftp_handler(request_rec
                                   "Failed to set");
                 }
 
-                /* make the connection */
-                apr_socket_addr_get(&data_addr, APR_REMOTE, sock);
-                apr_sockaddr_ip_get(&data_ip, data_addr);
-                apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p);
-                rv = apr_socket_connect(data_sock, epsv_addr);
+                rv = apr_socket_connect(data_sock, &epsv_addr);
                 if (rv != APR_SUCCESS) {
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01043)
                                   "EPSV attempt to connect to %pI failed - "
-                                  "Firewall/NAT?", epsv_addr);
+                                  "Firewall/NAT?", &epsv_addr);
                     return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
-                                                                           "EPSV attempt to connect to %pI failed - firewall/NAT?", epsv_addr));
+                                                                           "EPSV attempt to connect to %pI failed - firewall/NAT?", &epsv_addr));
                 }
                 else {
+                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO()
+                                  "connected data socket to %pI", &epsv_addr);
                     connect = 1;
                 }
             }