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

📄 ftp.c

📁 proxy源代码,linux下的ftp 代理的源代码,大家多多支持啊
💻 C
📖 第 1 页 / 共 4 页
字号:
		copy_string(x->username, p, sizeof(x->username));		}	if ((p = strchr(x->password, ':')) != NULL) {		*p++ = 0;		copy_string(x->local.password, x->password, sizeof(x->local.password));		copy_string(x->password, p, sizeof(x->password));		}        /*         * Call the dynamic configuration program.         */        if (*x->config->ctp != 0) {		x->server.port = get_port(x->server.name, 21);                if (run_ctp(x) != 0)                        exit (0);       /* Never happens, we exit in run_ctp() */		if (debug != 0) {	                fprintf (stderr, "trp debug: server= %s:%u, login= %s, passwd= %s",					x->server.name, x->server.port,					x->username, x->password);			}                }	/*	 * Get port an IP number of server.  Moved code here -- 030404asg	 */	x->server.port = get_port(x->server.name, 21);	if ((hostp = gethostbyname(x->server.name)) == NULL) {		cfputs(x, "500 service unavailable");		syslog(LOG_NOTICE, "-ERR: can't resolve hostname: %s", x->server.name);		exit (1);		}	memcpy(&saddr.sin_addr, hostp->h_addr, hostp->h_length);	copy_string(x->server.ipnum, inet_ntoa(saddr.sin_addr), sizeof(x->server.ipnum));	/*	 * Call the access control program to check if the proxy	 * request is allowed.  Moved code here -- 030404asg	 */	if (*x->config->acp != 0) {		if (run_acp(x) != 0)			exit (0);		}	/*	 * Verification if the destination server is on the given list	 * is done now here.	 *	 * Notice: Prior to this change you could give a fixed desination	 * server as command line argument and a list of allowed server	 * too.  Meaningless because the proxy didn't care when the `server	 * selection' option wasn't turned on.  Now also the fixed server	 * is checked against the list.	 *	 * I don't expect that this breaks an already running configuration	 * because as said above this configuration was senseless in earlier	 * proxy versions -- 030404asg	 */	if ((p = x->config->serverlist) != NULL  &&  *p != 0) {		int	permitted;		char	pattern[80];		permitted = 0;		while ((p = skip_ws(p)), *get_quoted(&p, ',', pattern, sizeof(pattern)) != 0) {			noctrl(pattern);			if (strpcmp(x->server.name, pattern) == 0) {				permitted = 1;				break;				}			}		if (permitted == 0) {			cfputs(x, "500 service unavailable");			syslog(LOG_NOTICE, "-ERR: hostname not permitted: %s", x->server.name);			exit (1);			}		}	/*	 * Establish connection to the server	 */	if ((x->fd.server = openip(x->server.name, x->server.port, x->config->sourceip, 0)) < 0) {		cfputs(x, "500 service unavailable");		syslog(LOG_NOTICE, "-ERR: can't connect to server: %s", x->server.name);		exit (1);		}	syslog(LOG_NOTICE, "connected to server: %s", x->server.name);	if (sfputc(x, NULL, NULL, line, sizeof(line), NULL) != 220) {		cfputs(x, "500 service unavailable");		syslog(LOG_NOTICE, "-ERR: unexpected server greeting: %s", line);		exit (1);		}	/*	 * Login auf FTP-Server.	 *	 * Complete rewrite because of servers wanting no password after	 * login of anonymous user.	 */	rc = sfputc(x, "USER", x->username, line, sizeof(line), NULL);	if (rc == 230) {		cfputs(x, "230 login accepted");		syslog(LOG_NOTICE, "login accepted: %s@%s, no password needed.", x->username, x->server.name);		return (0);		}	else if (rc != 331) {		cfputs(x, "500 service unavailable");		syslog(LOG_NOTICE, "-ERR: unexpected reply to USER: %s", line);		exit (1);		}	else if (sfputc(x, "PASS", x->password, line, sizeof(line), NULL) != 230) {		cfputs(x, "530 bad login");		syslog(LOG_NOTICE, "-ERR: reply to PASS: %s", line);		exit (1);		}	cfputs(x, "230 login accepted");	syslog(LOG_NOTICE, "login accepted: %s@%s", x->username, x->server.name);	return (0);/*	if (sfputc(x, "USER", x->username, line, sizeof(line), NULL) != 331) {		cfputs(x, "500 service unavailable");		syslog(LOG_NOTICE, "-ERR: unexpected reply to USER: %s", line);		exit (1);		}	else if (sfputc(x, "PASS", x->password, line, sizeof(line), NULL) != 230) {		cfputs(x, "530 bad login");		syslog(LOG_NOTICE, "-ERR: reply to PASS: %s", line);		exit (1);		}	cfputs(x, "230 login accepted");	syslog(LOG_NOTICE, "login accepted: %s@%s", x->username, x->server.name);	return (0);*/}void signal_handler(int sig){	/*	 * Changed the way we handle broken pipes (broken control or	 * data connection).  We ignore it here but write() returns -1	 * and errno is set to EPIPE which is checked.	 */	if (sig == SIGPIPE) {		signal(SIGPIPE, signal_handler);		return;		}	syslog(LOG_NOTICE, "-ERR: received signal #%d", sig);	exit (1);}int set_signals(void){	signal(SIGHUP, signal_handler);	signal(SIGINT, signal_handler);	signal(SIGQUIT, signal_handler);	signal(SIGSEGV, signal_handler);	signal(SIGPIPE, signal_handler);	signal(SIGALRM, signal_handler);	signal(SIGTERM, signal_handler);	signal(SIGUSR1, signal_handler);	signal(SIGUSR2, signal_handler);	return (0);}ftpcmd_t *getcmd(char *name){	int	i;	for (i=0; cmdtab[i].name[0] != 0; i++) {		if (strcmp(cmdtab[i].name, name) == 0)			return (&cmdtab[i]);		}	return (NULL);}int proxy_request(config_t *config){	int	rc;	char	*p, command[200], parameter[200], line[300];	ftpcmd_t *cmd;	ftp_t	*x;	set_signals();	/*	 * Set socket options to prevent us from the rare case that	 * we transfer data to/from the client before the client has	 * seen our "150 ..." message.	 * Seems so that is doesn't work on all systems.	 * So temporary only enable it on linux. 	 */#if defined(__linux__)	rc = 1;	if (setsockopt(1, SOL_TCP, TCP_NODELAY, &rc, sizeof(rc)) != 0)		syslog(LOG_NOTICE, "can't set TCP_NODELAY, error= %s", strerror(errno));#endif	if (config->bsize <= 0)		config->bsize = 1024;	else if (config->bsize > FTPMAXBSIZE)		config->bsize = FTPMAXBSIZE;	x = allocate(sizeof(ftp_t));	x->config = config;	snprintf (x->session, sizeof(x->session) - 2, "%lu-%u", time(NULL), getpid());	/*	 * Fix potential problems after immediate initial unseccsesful	 * up/downloads.  Wasn't a problem since we all do a LIST	 * at first.	 */	x->ch.isock = -1;	x->ch.osock = -1;	if (get_client_info(x, 0) < 0) {		syslog(LOG_NOTICE, "-ERR: can't get client info: %s", strerror(errno));		exit (1);		}	x->port = get_interface_info(0, x->interface, sizeof(x->interface));	syslog(LOG_NOTICE, "connected to client: %s, interface= %s:%u", x->client,				x->interface, x->port);	if (*x->config->configfile != 0) {		if (readconfig(x->config, x->config->configfile, x->interface) == 0) {			cfputs(x, "421 not available");			syslog(LOG_NOTICE, "-ERR: unconfigured interface: %s", x->interface);			exit (1);			}		}	syslog(LOG_NOTICE, "info: monitor mode: %s, ccp: %s",			x->config->monitor == 0? "off": "on",			*x->config->ccp == 0? "<unset>": x->config->ccp);	cfputs(x, "220 server ready - login please");	if ((rc = dologin(x)) < 0)		return (1);	else if (rc == 2)		return (0);	/*	 * Open the xferlog if we have one.	 */	if (*x->config->xferlog != 0) {		if (*x->server.name == 0)			copy_string(x->logusername, x->username, sizeof(x->logusername));		else if (x->server.port != 21)			snprintf (x->logusername, sizeof(x->logusername), "%s@%s:%u", x->username, x->server.name, x->server.port);		else			snprintf (x->logusername, sizeof(x->logusername), "%s@%s", x->username, x->server.name);		x->xlfp = fopen(x->config->xferlog, "a");		if (x->xlfp == NULL) {			syslog(LOG_NOTICE, "-WARN: can't open xferlog: %s, error= %s",					x->config->xferlog, strerror(errno));			}		}	if (x->config->monitor) {		get_ftpdir(x);		copy_string(x->home, x->cwd, sizeof(x->home));		}	while ((p = cfgets(x, line, sizeof(line))) != NULL) {		if (*p == '\001') {			if (*x->ch.command != 0) {				syslog(LOG_NOTICE, "%s %s: %ld bytes", x->ch.command, x->ch.filename, x->ch.bytes);				if (x->xlfp != NULL) {					unsigned long now;					char	date[80];					/*					 * Write xferlog entry but notice that (1) session are never					 * flagged as anonymous and (2) the transfer type is always					 * binary (type flag was added to data channel but is					 * actually not used. 10MAY04wzk					 */					now = time(NULL);					copy_string(date, ctime(&now), sizeof(date));					fprintf (x->xlfp, "%s %lu %s %lu %s %c %c %c %c %s %s %d %s %c\n",							date,							now - x->ch.started,							x->client_ip,							x->ch.bytes,							x->ch.filename,							'b',		/* x->ch.type == TYPE_ASC? 'a': 'b', */							'-',							strcmp(x->ch.command, "RETR")? 'i': 'o',							'u',		/* x->isanonymous == 1? 'a': 'u', */							x->logusername,							"ftp", 1, x->logusername, 'c');					fflush(x->xlfp);					}				}			/*			 * Handle multiline server responses after the			 * data transfer.			 */			sfputc(x, NULL, NULL, line, sizeof(line), NULL);			cfputs(x, line);			continue;			}		p = noctrl(line);		get_word(&p, command, sizeof(command));		strupr(command);		if ((cmd = getcmd(command)) == NULL  ||  cmd->resp == -1) {			cfputs(x, "502 command not implemented");			syslog(LOG_NOTICE, "command not implemented: %s", command);			continue;			}		*x->filepath = 0;		if (cmd->par == 0)			*parameter = 0;		else {			if (strcmp(command, "CDUP") == 0)				strcpy(parameter, "..");			else if (strcmp(command, "SITE") == 0)				copy_string(parameter, p, sizeof(parameter));			else {				if (x->config->allow_blanks != 0)					copy_string(parameter, p, sizeof(parameter));				else					get_word(&p, parameter, sizeof(parameter));									if (*parameter == 0) {					if (strcmp(command, "LIST") == 0  ||  strcmp(command, "NLST") == 0)						/* nichts, ist ok */ ;					else {						syslog(LOG_NOTICE, "parameter required: %s", command);						exit (1);						}					}				}			if (cmd->ispath != 0) {				if (x->config->monitor) {					if ((strcmp(command, "LIST") == 0  ||  strcmp(command, "NLST") == 0)					    &&  *parameter == 0) {						/*						 * Sonderfall: wir simulieren `*' als Parameter.						 */						get_ftppath(x, "*");						}					else						get_ftppath(x, parameter);					}				}			}		if (cmd->useccp != 0) {			if (run_ccp(x, command, parameter) != CCP_OK)				continue;			}		if (strcmp(command, "QUIT") == 0) {/*		        run_ccp(x, "QUIT", ""); */			doquit(x);			break;			}		else if (strcmp(command, "PORT") == 0)			doport(x, command, parameter);		else if (strcmp(command, "FEAT") == 0)			dofeat(x);		else if (strcmp(command, "PASV") == 0)			dopasv(x, command, parameter);		else if (strcmp(command, "LIST") == 0  ||  strcmp(command, "NLST") == 0) {			x->ch.operation = OP_GET;	/* fuer PASV mode */			rc = sfputc(x, command, parameter, line, sizeof(line), NULL);			if (rc == 125  ||  rc == 150) {				x->ch.operation = OP_GET;				x->ch.seen150   = 1;				if (debug >= 2)					fprintf (stderr, "received 150 response\n");				}			else				close_ch(x, &x->ch);			cfputs(x, line);			*x->ch.command = 0;			}		else if (strcmp(command, "RETR") == 0) {			x->ch.operation = OP_GET;	/* fuer PASV mode */			rc = sfputc(x, "RETR", parameter, line, sizeof(line), NULL);			if (rc == 125  ||  rc == 150) {				x->ch.operation = OP_GET;				x->ch.seen150   = 1;				if (debug >= 2)					fprintf (stderr, "received 150 response\n");				}			else				close_ch(x, &x->ch);			cfputs(x, line);			copy_string(x->ch.command, "RETR", sizeof(x->ch.command));			copy_string(x->ch.filename, x->config->monitor != 0? x->filepath: parameter, sizeof(x->ch.filename));			if (extralog != 0)				syslog(LOG_NOTICE, "%d RETR %s", rc, (x->config->monitor != 0)? parameter: x->filepath);			}		else if (strcmp(command, "STOR") == 0  ||  strcmp(command, "APPE") == 0  ||  strcmp(command, "STOU") == 0) {			x->ch.operation = OP_PUT;	/* fuer PASV mode */			rc = sfputc(x, command, parameter, line, sizeof(line), NULL);			if (rc == 125  ||  rc == 150) {				x->ch.operation = OP_PUT;				x->ch.seen150   = 1;				if (debug >= 2)					fprintf (stderr, "received 150 response\n");				copy_string(x->ch.command, command, sizeof(x->ch.command));				}			else				close_ch(x, &x->ch);			cfputs(x, line);			copy_string(x->ch.filename, x->config->monitor != 0? x->filepath: parameter, sizeof(x->ch.filename));			if (extralog != 0) {				if (strcmp(command, "STOU") == 0)					syslog(LOG_NOTICE, "%d %s %s", rc, command, "-");				else					syslog(LOG_NOTICE, "%d %s %s", rc, command, x->ch.filename);				}			}		else {			if (strcmp(command, "CDUP") == 0)				*parameter = 0;			rc = sfputc(x, command, parameter, line, sizeof(line), NULL);			cfputs(x, line);			if (extralog != 0  &&  cmd->log != 0) {				if (x->config->monitor != 0  &&  cmd->ispath != 0)					syslog(LOG_NOTICE, "%d %s %s", rc, command, x->filepath);				else					syslog(LOG_NOTICE, "%d %s%s%s", rc, command, *parameter != 0? " ": "", parameter);				}			if (strcmp(command, "CWD") == 0  ||  strcmp(command, "CDUP") == 0) {				if (x->config->monitor)					get_ftpdir(x);				}			}		}	if (*x->config->ccp != 0)		run_ccp(x, "+EXIT", x->session);	syslog(LOG_NOTICE, "+OK: proxy terminating");	return (0);}

⌨️ 快捷键说明

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