~ubuntu-branches/ubuntu/natty/apache2/natty

« back to all changes in this revision

Viewing changes to modules/proxy/mod_proxy_ftp.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-11-06 00:29:03 UTC
  • mfrom: (14.3.5 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091106002903-a7zl7sh2z1z3uxqb
Tags: 2.2.14-1ubuntu1
* Merge from debian testing, remaining changes:
  - debian/{control, rules}: Enable PIE hardening.
  - debian/{control, rules, pache2.2-common.ufw.profile}: Add ufw profiles.
  - debian/conrol: Add bzr tag and point it to our tree.
  - Dropped debian/patches/203_fix_legacy_ap_rputs_segfaults.dpatch: 
    Already applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
604
604
    return APR_SUCCESS;
605
605
}
606
606
 
 
607
/* Parse EPSV reply and return port, or zero on error. */
 
608
static apr_port_t parse_epsv_reply(const char *reply)
 
609
{
 
610
    const char *p;
 
611
    char *ep;
 
612
    long port;
 
613
 
 
614
    /* Reply syntax per RFC 2428: "229 blah blah (|||port|)" where '|'
 
615
     * can be any character in ASCII from 33-126, obscurely.  Verify
 
616
     * the syntax. */
 
617
    p = ap_strchr_c(reply, '(');
 
618
    if (p == NULL || !p[1] || p[1] != p[2] || p[1] != p[3]
 
619
        || p[4] == p[1]) {
 
620
        return 0;
 
621
    }
 
622
 
 
623
    errno = 0;
 
624
    port = strtol(p + 4, &ep, 10);
 
625
    if (errno || port < 1 || port > 65535 || ep[0] != p[1] || ep[1] != ')') {
 
626
        return 0;
 
627
    }
 
628
 
 
629
    return (apr_port_t)port;
 
630
}
 
631
 
607
632
/*
608
633
 * Generic "send FTP command to server" routine, using the control socket.
609
634
 * Returns the FTP returncode (3 digit code)
887
912
    if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL
888
913
        && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0
889
914
        && (password = ap_pbase64decode(r->pool, password))[0] != ':') {
 
915
        /* Check the decoded string for special characters. */
 
916
        if (!ftp_check_string(password)) {
 
917
            return ap_proxyerror(r, HTTP_BAD_REQUEST, 
 
918
                                 "user credentials contained invalid character");
 
919
        } 
890
920
        /*
891
921
         * Note that this allocation has to be made from r->connection->pool
892
922
         * because it has the lifetime of the connection.  The other
1210
1240
            return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage);
1211
1241
        }
1212
1242
        else if (rc == 229) {
1213
 
            char *pstr;
1214
 
            char *tok_cntx;
1215
 
 
1216
 
            pstr = ftpmessage;
1217
 
            pstr = apr_strtok(pstr, " ", &tok_cntx);    /* separate result code */
1218
 
            if (pstr != NULL) {
1219
 
                if (*(pstr + strlen(pstr) + 1) == '=') {
1220
 
                    pstr += strlen(pstr) + 2;
1221
 
                }
1222
 
                else {
1223
 
                    pstr = apr_strtok(NULL, "(", &tok_cntx);    /* separate address &
1224
 
                                                                 * port params */
1225
 
                    if (pstr != NULL)
1226
 
                        pstr = apr_strtok(NULL, ")", &tok_cntx);
1227
 
                }
1228
 
            }
1229
 
 
1230
 
            if (pstr) {
 
1243
            /* Parse the port out of the EPSV reply. */
 
1244
            data_port = parse_epsv_reply(ftpmessage);
 
1245
 
 
1246
            if (data_port) {
1231
1247
                apr_sockaddr_t *epsv_addr;
1232
 
                data_port = atoi(pstr + 3);
1233
1248
 
1234
1249
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
1235
1250
                       "proxy: FTP: EPSV contacting remote host on port %d",
1272
1287
                    connect = 1;
1273
1288
                }
1274
1289
            }
1275
 
            else {
1276
 
                /* and try the regular way */
1277
 
                apr_socket_close(data_sock);
1278
 
            }
1279
1290
        }
1280
1291
    }
1281
1292
 
1364
1375
                    connect = 1;
1365
1376
                }
1366
1377
            }
1367
 
            else {
1368
 
                /* and try the regular way */
1369
 
                apr_socket_close(data_sock);
1370
 
            }
1371
1378
        }
1372
1379
    }
1373
1380
/*bypass:*/
1851
1858
                 * for a slow client to eat these bytes
1852
1859
                 */
1853
1860
                ap_flush_conn(data);
1854
 
                apr_socket_close(data_sock);
 
1861
                if (data_sock) {
 
1862
                    apr_socket_close(data_sock);
 
1863
                }
1855
1864
                data_sock = NULL;
1856
1865
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
1857
1866
                             "proxy: FTP: data connection closed");