⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_proxy_ftp.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* ignore it silently */;    return ret;}/* Return the current directory which we have selected on the FTP server, or NULL */static char *ftp_get_PWD(request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb){    char *cwd = NULL;    char *ftpmessage = NULL;    /* responses: 257, 500, 501, 502, 421, 550 */    /* 257 "<directory-name>" <commentary> */    /* 421 Service not available, closing control connection. */    /* 500 Syntax error, command unrecognized. */    /* 501 Syntax error in parameters or arguments. */    /* 502 Command not implemented. */    /* 550 Requested action not taken. */    switch (proxy_ftp_command("PWD" CRLF, r, ftp_ctrl, bb, &ftpmessage)) {        case -1:        case 421:        case 550:            ap_proxyerror(r, HTTP_BAD_GATEWAY,                             "Failed to read PWD on ftp server");            break;        case 257: {            const char *dirp = ftpmessage;            cwd = ap_getword_conf(r->pool, &dirp);        }    }    return cwd;}/* Common routine for failed authorization (i.e., missing or wrong password) * to an ftp service. This causes most browsers to retry the request * with username and password (which was presumably queried from the user) * supplied in the Authorization: header. * Note that we "invent" a realm name which consists of the * ftp://user@host part of the reqest (sans password -if supplied but invalid-) */static int ftp_unauthorized(request_rec *r, int log_it){    r->proxyreq = PROXYREQ_NONE;    /*     * Log failed requests if they supplied a password (log username/password     * guessing attempts)     */    if (log_it)        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,                      "proxy: missing or failed auth to %s",                      apr_uri_unparse(r->pool,                                 &r->parsed_uri, APR_URI_UNP_OMITPATHINFO));    apr_table_setn(r->err_headers_out, "WWW-Authenticate",                   apr_pstrcat(r->pool, "Basic realm=\"",                               apr_uri_unparse(r->pool, &r->parsed_uri,                       APR_URI_UNP_OMITPASSWORD | APR_URI_UNP_OMITPATHINFO),                               "\"", NULL));    return HTTP_UNAUTHORIZED;}staticapr_status_t proxy_ftp_cleanup(request_rec *r, proxy_conn_rec *backend){    backend->close_on_recycle = 1;    ap_set_module_config(r->connection->conn_config, &proxy_ftp_module, NULL);    ap_proxy_release_connection("FTP", backend, r->server);    return OK;}staticint ftp_proxyerror(request_rec *r, proxy_conn_rec *conn, int statuscode, const char *message){    proxy_ftp_cleanup(r, conn);    return ap_proxyerror(r, statuscode, message);}/* * Handles direct access of ftp:// URLs * Original (Non-PASV) version from * Troy Morrison <spiffnet@zoom.com> * PASV added by Chuck * Filters by [Graham Leggett <minfrin@sharp.fm>] */static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,                             proxy_server_conf *conf, char *url,                             const char *proxyhost, apr_port_t proxyport){    apr_pool_t *p = r->pool;    conn_rec *c = r->connection;    proxy_conn_rec *backend;    apr_socket_t *sock, *local_sock, *data_sock = NULL;    apr_sockaddr_t *connect_addr = NULL;    apr_status_t rv;    conn_rec *origin, *data = NULL;    apr_status_t err = APR_SUCCESS;    apr_status_t uerr = APR_SUCCESS;    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);    char *buf, *connectname;    apr_port_t connectport;    char buffer[MAX_STRING_LEN];    char *ftpmessage = NULL;    char *path, *strp, *type_suffix, *cwd = NULL;    apr_uri_t uri;    char *user = NULL;/*    char *account = NULL; how to supply an account in a URL? */    const char *password = NULL;    int len, rc;    int one = 1;    char *size = NULL;    char xfer_type = 'A'; /* after ftp login, the default is ASCII */    int  dirlisting = 0;#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF))    apr_time_t mtime = 0L;#endif    /* stuff for PASV mode */    int connect = 0, use_port = 0;    char dates[APR_RFC822_DATE_LEN];    int status;    apr_pool_t *address_pool;    /* is this for us? */    if (proxyhost) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                     "proxy: FTP: declining URL %s - proxyhost %s specified:", url, proxyhost);        return DECLINED;        /* proxy connections are via HTTP */    }    if (strncasecmp(url, "ftp:", 4)) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                     "proxy: FTP: declining URL %s - not ftp:", url);        return DECLINED;        /* only interested in FTP */    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "proxy: FTP: serving URL %s", url);    /*     * I: Who Do I Connect To? -----------------------     *     * Break up the URL to determine the host to connect to     */    /* we only support GET and HEAD */    if (r->method_number != M_GET)        return HTTP_NOT_IMPLEMENTED;    /* We break the URL into host, port, path-search */    if (r->parsed_uri.hostname == NULL) {        if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) {            return ap_proxyerror(r, HTTP_BAD_REQUEST,                apr_psprintf(p, "URI cannot be parsed: %s", url));        }        connectname = uri.hostname;        connectport = uri.port;        path = apr_pstrdup(p, uri.path);    }    else {        connectname = r->parsed_uri.hostname;        connectport = r->parsed_uri.port;        path = apr_pstrdup(p, r->parsed_uri.path);    }    if (connectport == 0) {        connectport = apr_uri_port_of_scheme("ftp");    }    path = (path != NULL && path[0] != '\0') ? &path[1] : "";    type_suffix = strchr(path, ';');    if (type_suffix != NULL)        *(type_suffix++) = '\0';    if (type_suffix != NULL && strncmp(type_suffix, "type=", 5) == 0        && apr_isalpha(type_suffix[5])) {        /* "type=d" forces a dir listing.         * The other types (i|a|e) are directly used for the ftp TYPE command         */        if ( ! (dirlisting = (apr_tolower(type_suffix[5]) == 'd')))            xfer_type = apr_toupper(type_suffix[5]);        /* Check valid types, rather than ignoring invalid types silently: */        if (strchr("AEI", xfer_type) == NULL)            return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r->pool,                                    "ftp proxy supports only types 'a', 'i', or 'e': \"",                                    type_suffix, "\" is invalid.", NULL));    }    else {        /* make binary transfers the default */        xfer_type = 'I';    }    /*     * The "Authorization:" header must be checked first. We allow the user     * to "override" the URL-coded user [ & password ] in the Browsers'     * User&Password Dialog. NOTE that this is only marginally more secure     * than having the password travel in plain as part of the URL, because     * Basic Auth simply uuencodes the plain text password. But chances are     * still smaller that the URL is logged regularly.     */    if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL        && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0        && (password = ap_pbase64decode(r->pool, password))[0] != ':') {        /*         * Note that this allocation has to be made from r->connection->pool         * because it has the lifetime of the connection.  The other         * allocations are temporary and can be tossed away any time.         */        user = ap_getword_nulls(r->connection->pool, &password, ':');        r->ap_auth_type = "Basic";        r->user = r->parsed_uri.user = user;    }    else if ((user = r->parsed_uri.user) != NULL) {        user = apr_pstrdup(p, user);        decodeenc(user);        if ((password = r->parsed_uri.password) != NULL) {            char *tmp = apr_pstrdup(p, password);            decodeenc(tmp);            password = tmp;        }    }    else {        user = "anonymous";        password = "apache-proxy@";    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,       "proxy: FTP: connecting %s to %s:%d", url, connectname, connectport);    if (worker->is_address_reusable) {        if (!worker->cp->addr) {            if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) {                ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server,                             "proxy: FTP: lock");                return HTTP_INTERNAL_SERVER_ERROR;            }        }        connect_addr = worker->cp->addr;        address_pool = worker->cp->pool;    }    else        address_pool = r->pool;    /* do a DNS lookup for the destination host */    if (!connect_addr)        err = apr_sockaddr_info_get(&(connect_addr),                                    connectname, APR_UNSPEC,                                    connectport, 0,                                    address_pool);    if (worker->is_address_reusable && !worker->cp->addr) {        worker->cp->addr = connect_addr;        if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_ERR, uerr, r->server,                         "proxy: FTP: unlock");        }    }    /*     * get all the possible IP addresses for the destname and loop through     * them until we get a successful connection     */    if (APR_SUCCESS != err) {        return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p,                                                 "DNS lookup failure for: ",                                                        connectname, NULL));    }    /* check if ProxyBlock directive on this host */    if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) {        return ap_proxyerror(r, HTTP_FORBIDDEN,                             "Connect to remote machine blocked");    }    /* create space for state information */    backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, &proxy_ftp_module);    if (!backend) {        status = ap_proxy_acquire_connection("FTP", &backend, worker, r->server);        if (status != OK) {            if (backend) {                backend->close_on_recycle = 1;                ap_proxy_release_connection("FTP", backend, r->server);            }            return status;        }        /* TODO: see if ftp could use determine_connection */        backend->addr = connect_addr;        ap_set_module_config(c->conn_config, &proxy_ftp_module, backend);    }    /*     * II: Make the Connection -----------------------     *     * We have determined who to connect to. Now make the connection.     */    if (ap_proxy_connect_backend("FTP", backend, worker, r->server)) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                     "proxy: FTP: an error occurred creating a new connection to %pI (%s)",                     connect_addr, connectname);        proxy_ftp_cleanup(r, backend);        return HTTP_SERVICE_UNAVAILABLE;    }    if (!backend->connection) {        status = ap_proxy_connection_create("FTP", backend, c, r->server);        if (status != OK) {            proxy_ftp_cleanup(r, backend);            return status;        }    }    /* Use old naming */    origin = backend->connection;    sock = backend->sock;    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "proxy: FTP: control connection complete");    /*     * III: Send Control Request -------------------------     *     * Log into the ftp server, send the username & password, change to the     * correct directory...     */    /* possible results: */    /* 120 Service ready in nnn minutes. */    /* 220 Service ready for new user. */    /* 421 Service not available, closing control connection. */    rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage);    if (rc == -1 || rc == 421) {        return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, "Error reading from remote server");    }    if (rc == 120) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -