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

📄 proxy_ftp.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ==================================================================== * Copyright (c) 1996-1998 The Apache Group.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    apache@apache.org. * * 5. Products derived from this software may not be called "Apache" *    nor may "Apache" appear in their names without prior written *    permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * *//* FTP routines for Apache proxy */#include "mod_proxy.h"#include "http_main.h"#include "http_log.h"#define AUTODETECT_PWDDEF_Explain/* * Decodes a '%' escaped string, and returns the number of characters */static int decodeenc(char *x){    int i, j, ch;    if (x[0] == '\0')	return 0;		/* special case for no characters */    for (i = 0, j = 0; x[i] != '\0'; i++, j++) {/* decode it if not already done */	ch = x[i];	if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) {	    ch = ap_proxy_hex2c(&x[i + 1]);	    i += 2;	}	x[j] = ch;    }    x[j] = '\0';    return j;}/* * checks an encoded ftp string for bad characters, namely, CR, LF or * non-ascii character */static int ftp_check_string(const char *x){    int i, ch;    for (i = 0; x[i] != '\0'; i++) {	ch = x[i];	if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) {	    ch = ap_proxy_hex2c(&x[i + 1]);	    i += 2;	}#ifndef CHARSET_EBCDIC	if (ch == '\015' || ch == '\012' || (ch & 0x80))#else /*CHARSET_EBCDIC*/	if (ch == '\r' || ch == '\n' || (os_toascii[ch] & 0x80))#endif /*CHARSET_EBCDIC*/	    return 0;    }    return 1;}/* * Canonicalise ftp URLs. */int ap_proxy_ftp_canon(request_rec *r, char *url){    char *user, *password, *host, *path, *parms, *strp, sport[7];    pool *p = r->pool;    const char *err;    int port;    port = DEFAULT_FTP_PORT;    err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port);    if (err)	return HTTP_BAD_REQUEST;    if (user != NULL && !ftp_check_string(user))	return HTTP_BAD_REQUEST;    if (password != NULL && !ftp_check_string(password))	return HTTP_BAD_REQUEST;/* now parse path/parameters args, according to rfc1738 *//* N.B. if this isn't a true proxy request, then the URL path * (but not query args) has already been decoded. * This gives rise to the problem of a ; being decoded into the * path. */    strp = strchr(url, ';');    if (strp != NULL) {	*(strp++) = '\0';	parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm, r->proxyreq);	if (parms == NULL)	    return HTTP_BAD_REQUEST;    }    else	parms = "";    path = ap_proxy_canonenc(p, url, strlen(url), enc_path, r->proxyreq);    if (path == NULL)	return HTTP_BAD_REQUEST;    if (!ftp_check_string(path))	return HTTP_BAD_REQUEST;    if (!r->proxyreq && r->args != NULL) {	if (strp != NULL) {	    strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, 1);	    if (strp == NULL)		return HTTP_BAD_REQUEST;	    parms = ap_pstrcat(p, parms, "?", strp, NULL);	}	else {	    strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, 1);	    if (strp == NULL)		return HTTP_BAD_REQUEST;	    path = ap_pstrcat(p, path, "?", strp, NULL);	}	r->args = NULL;    }/* now, rebuild URL */    if (port != DEFAULT_FTP_PORT)	ap_snprintf(sport, sizeof(sport), ":%d", port);    else	sport[0] = '\0';    r->filename = ap_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "",			       (password != NULL) ? ":" : "",			       (password != NULL) ? password : "",		          (user != NULL) ? "@" : "", host, sport, "/", path,			       (parms[0] != '\0') ? ";" : "", parms, NULL);    return OK;}/* * Returns the ftp status code; *  or -1 on I/O error, 0 on data error */static int ftp_getrc(BUFF *f){    int len, status;    char linebuff[100], buff[5];    len = ap_bgets(linebuff, sizeof linebuff, f);    if (len == -1)	return -1;/* check format */    if (len < 5 || !ap_isdigit(linebuff[0]) || !ap_isdigit(linebuff[1]) ||	!ap_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-'))	status = 0;    else	status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';    if (linebuff[len - 1] != '\n') {	(void)ap_bskiplf(f);    }/* skip continuation lines */    if (linebuff[3] == '-') {	memcpy(buff, linebuff, 3);	buff[3] = ' ';	do {	    len = ap_bgets(linebuff, sizeof linebuff, f);	    if (len == -1)		return -1;	    if (linebuff[len - 1] != '\n') {		(void)ap_bskiplf(f);	    }	} while (memcmp(linebuff, buff, 4) != 0);    }    return status;}/* * Like ftp_getrc but returns both the ftp status code and  * remembers the response message in the supplied buffer */static int ftp_getrc_msg(BUFF *f, char *msgbuf, int msglen){    int len, status;    char linebuff[100], buff[5];    char *mb = msgbuf,	 *me = &msgbuf[msglen];    len = ap_bgets(linebuff, sizeof linebuff, f);    if (len == -1)	return -1;    if (len < 5 || !ap_isdigit(linebuff[0]) || !ap_isdigit(linebuff[1]) ||	!ap_isdigit(linebuff[2]) || (linebuff[3] != ' ' && linebuff[3] != '-'))	status = 0;    else	status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';    mb = ap_cpystrn(mb, linebuff+4, me - mb);    if (linebuff[len - 1] != '\n')	(void)ap_bskiplf(f);    if (linebuff[3] == '-') {	memcpy(buff, linebuff, 3);	buff[3] = ' ';	do {	    len = ap_bgets(linebuff, sizeof linebuff, f);	    if (len == -1)		return -1;	    if (linebuff[len - 1] != '\n') {		(void)ap_bskiplf(f);	    }	    mb = ap_cpystrn(mb, linebuff+4, me - mb);	} while (memcmp(linebuff, buff, 4) != 0);    }    return status;}static long int send_dir(BUFF *f, request_rec *r, cache_req *c, char *cwd){    char buf[IOBUFSIZE];    char buf2[IOBUFSIZE];    char *filename;    int searchidx = 0;    char *searchptr = NULL;    int firstfile = 1;    unsigned long total_bytes_sent = 0;    register int n, o, w;    conn_rec *con = r->connection;    char *dir, *path, *reldir, *site;    /* Save "scheme://site" prefix without password */    site = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD|UNP_OMITPATHINFO);    /* ... and path without query args */    path = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITSITEPART|UNP_OMITQUERY);    (void)decodeenc(path);    /* Copy path, strip (all except the last) trailing slashes */    path = dir = ap_pstrcat(r->pool, path, "/", NULL);    while ((n = strlen(path)) > 1 && path[n-1] == '/' && path[n-2] == '/')	path[n-1] = '\0';    /* print "ftp://host/" */    n = ap_snprintf(buf, sizeof(buf), "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"		"<HTML><HEAD><TITLE>%s%s</TITLE>\n"		"<BASE HREF=\"%s%s\"></HEAD>\n"		"<BODY><H2>Directory of "		"<A HREF=\"/\">%s</A>/",		site, path, site, path, site);    total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);    while ((dir = strchr(dir+1, '/')) != NULL)    {	*dir = '\0';	if ((reldir = strrchr(path+1, '/'))==NULL)	    reldir = path+1;	else	    ++reldir;	/* print "path/" component */	ap_snprintf(buf, sizeof(buf), "<A HREF=\"/%s/\">%s</A>/", path+1, reldir);	total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);	*dir = '/';    }    /* If the caller has determined the current directory, and it differs */    /* from what the client requested, then show the real name */    if (cwd == NULL || strncmp (cwd, path, strlen(cwd)) == 0) {	ap_snprintf(buf, sizeof(buf), "</H2>\n<HR><PRE>");    } else {	ap_snprintf(buf, sizeof(buf), "</H2>\n(%s)\n<HR><PRE>", cwd);    }    total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);    while (!con->aborted) {	n = ap_bgets(buf, sizeof buf, f);	if (n == -1) {		/* input error */	    if (c != NULL)		c = ap_proxy_cache_error(c);	    break;	}	if (n == 0)	    break;		/* EOF */	if (buf[0] == 'l' && (filename=strstr(buf, " -> ")) != NULL) {	    char *link_ptr = filename;	    do {		filename--;	    } while (filename[0] != ' ');	    *(filename++) = '\0';	    *(link_ptr++) = '\0';	    if ((n = strlen(link_ptr)) > 1 && link_ptr[n - 1] == '\n')	      link_ptr[n - 1] = '\0';	    ap_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s\">%s %s</A>\n", buf, filename, filename, link_ptr);	    ap_cpystrn(buf, buf2, sizeof(buf));	    n = strlen(buf);	}	else if (buf[0] == 'd' || buf[0] == '-' || buf[0] == 'l' || ap_isdigit(buf[0])) {	    if (ap_isdigit(buf[0])) {	/* handle DOS dir */		searchptr = strchr(buf, '<');		if (searchptr != NULL)		    *searchptr = '[';		searchptr = strchr(buf, '>');		if (searchptr != NULL)		    *searchptr = ']';	    }	    filename = strrchr(buf, ' ');	    *(filename++) = 0;	    filename[strlen(filename) - 1] = 0;	    /* handle filenames with spaces in 'em */	    if (!strcmp(filename, ".") || !strcmp(filename, "..") || firstfile) {		firstfile = 0;		searchidx = filename - buf;	    }	    else if (searchidx != 0 && buf[searchidx] != 0) {		*(--filename) = ' ';		buf[searchidx - 1] = 0;		filename = &buf[searchidx];	    }	    /* Special handling for '.' and '..' */	    if (!strcmp(filename, ".") || !strcmp(filename, "..") || buf[0] == 'd') {		ap_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s/\">%s</A>\n",		    buf, filename, filename);	    }	    else {		ap_snprintf(buf2, sizeof(buf2), "%s <A HREF=\"%s\">%s</A>\n", buf, filename, filename);	    }	    ap_cpystrn(buf, buf2, sizeof(buf));	    n = strlen(buf);	}	o = 0;	total_bytes_sent += n;	if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n)	    c = ap_proxy_cache_error(c);	while (n && !r->connection->aborted) {	    w = ap_bwrite(con->client, &buf[o], n);	    if (w <= 0)		break;	    ap_reset_timeout(r);	/* reset timeout after successfule write */	    n -= w;	    o += w;	}    }    total_bytes_sent += ap_proxy_bputs2("</PRE><HR>\n", con->client, c);    total_bytes_sent += ap_proxy_bputs2(ap_psignature("", r), con->client, c);    total_bytes_sent += ap_proxy_bputs2("</BODY></HTML>\n", con->client, c);    ap_bflush(con->client);    return total_bytes_sent;}/* 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 = 0;    /* Log failed requests if they supplied a password     * (log username/password guessing attempts)

⌨️ 快捷键说明

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