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

📄 ftp.c

📁 proxy源代码,linux下的ftp 代理的源代码,大家多多支持啊
💻 C
📖 第 1 页 / 共 4 页
字号:
	return (line);}int cfputs(ftp_t *x, char *line){	char	buffer[310];	if (debug)		fprintf (stderr, ">>> CLI: %s\n", line);	snprintf (buffer, sizeof(buffer) - 2, "%s\r\n", line);	write(1, buffer, strlen(buffer));	return (0);}char *sfgets(ftp_t *x, char *line, int size){	char *p;	*line = 0;	if ((p = readline_fd(x, x->fd.server, line, size)) == NULL)		return (NULL);	else if (debug != 0)		fprintf (stderr, "SVR >>>: %s\n", p);	return (line);}int sfputs(ftp_t *x, char *format, ...){	int	len;	char	buffer[310];	va_list	ap;	va_start(ap, format);	vsnprintf (buffer, sizeof(buffer) - 10, format, ap);	va_end(ap);	if (debug)		fprintf (stderr, ">>> SVR: %s\n", buffer);	/*	 * There are firewalls that don't like command to be split in	 * two packets.  Notice: the `- 10' above is really important	 * to protect the proxy against buffer overflows.	 */	strcat(buffer, "\r\n");	len = strlen(buffer);	/*	 * SIGPIPE is catched but then ignored, we have to handle it	 * one our own now -- 24APR02asg	 */	if (write(x->fd.server, buffer, len) != len) {		syslog(LOG_NOTICE, "-ERR: error writing control connect, error= %s", strerror(errno));		exit (1);		}/* *	write(x->fd.server, buffer, strlen(buffer)); *	write(x->fd.server, "\r\n", 2); */	return (0);}int sfputc(ftp_t *x, char *command, char *parameter, char *line, int size, char **here){	int	rc;	char	*p, buffer[300];	if (command != NULL  &&  *command != 0) {		if (parameter != NULL  &&  *parameter != 0)			snprintf (buffer, sizeof(buffer) - 2, "%s %s", command, skip_ws(parameter));		else			copy_string(buffer, command, sizeof(buffer));		sfputs(x, "%s", buffer);		}		if (sfgets(x, line, size) == NULL) {		if (debug != 0)			fprintf (stderr, "server disappered in sfputc(), pos #1\n");		return (-1);		}	else if (strlen(line) < 3) {		if (debug != 0)			fprintf (stderr, "short server reply in sfputc()\n");		return (-1);		}	rc = atoi(line);	if (line[3] != ' '  &&  line[3] != 0) {        	while (1) {                	if (sfgets(x, line, size) == NULL) {				syslog(LOG_NOTICE, "-ERR: lost server while reading client greeting: %s", x->server.name);				exit (1);				}			if (strlen(line) < 3)				/* line too short to be response's last line */ ;			else if (line[3] != ' '  &&  line[3] != 0)				/* neither white space nor EOL at position #4 */ ;			else if (line[0] >= '0'  &&  line[0] <= '9'  &&  atoi(line) == rc)                       		break;		/* status code followed by EOL or blank detected */			}        	}	if (here != NULL) {		p = skip_ws(&line[3]);		*here = p;		}	return (rc);}int doquit(ftp_t *x){	int	rc;	char	resp[200];	if ((rc = sfputc(x, "QUIT", "", resp, sizeof(resp), NULL)) != 221)		syslog(LOG_NOTICE, "unexpected resonse to QUIT: %s", resp);	cfputs(x, "221 goodbye");	syslog(LOG_NOTICE, "%d QUIT", rc);		return (0);}char *_getipnum(char *line, char **here, char *ip, int size){	int	c, i, k;	copy_string(ip, line, size);	k = 0;	for (i=0; (c = ip[i]) != 0; i++) {		if (c == ',') {			if (k < 3) {				ip[i] = '.';				k++;				}			else {				ip[i++] = 0;				break;				}			}		}	if (here != NULL)		*here = &line[i];	return (ip);}unsigned long _getport(char *line, char **here){	unsigned long port;	char	*p;	p = line;	port = strtoul(p, &p, 10);	if (*p != ',')		return (0);	p++;	port = (port << 8) + strtoul(p, &p, 10);	if (here != NULL)		*here = p;	return (port);}int doport(ftp_t *x, char *command, char *par){	int	c, rc;	char	*p, line[200];	dtc_t	*ch;	ch = &x->ch;	_getipnum(par, &p, ch->client.ipnum, sizeof(ch->client.ipnum));	ch->client.port = _getport(p, &p);	if (debug)		fprintf (stderr, "client listens on %s:%u\n", ch->client.ipnum, ch->client.port);	get_interface_info(x->fd.server, ch->outside.ipnum, sizeof(ch->outside.ipnum));	ch->osock = bind_to_port(ch->outside.ipnum, 0);	ch->outside.port = get_interface_info(ch->osock, line, sizeof(line));	if (debug)		fprintf (stderr, "listening on %s:%u\n", ch->outside.ipnum, ch->outside.port);	copy_string(line, ch->outside.ipnum, sizeof(line));	for (p=line; (c = *p) != 0; p++) {		if (c == '.')			*p = ',';		}	*p++ = ',';	snprintf (p, 20, "%u,%u", ch->outside.port >> 8, ch->outside.port & 0xFF);	/* Open port first */			ch->isock     = -1;	ch->mode      = MODE_PORT;	ch->state     = PORT_LISTEN;	/* then send PORT cmd */	rc = sfputc(x, "PORT", line, line, sizeof(line), &p);	/* check return code */	if (rc != 200){		cfputs(x, "500 not accepted");		close_ch(x, &x->ch);		}	else 		cfputs(x, "200 ok, port allocated");/*	if (rc != 200)		cfputs(x, "500 not accepted");	else {		cfputs(x, "200 ok, port allocated");		ch->isock  = -1;		ch->mode   = MODE_PORT;		ch->state  = PORT_LISTEN;		}*/	*ch->command = 0;	return (rc);}int dopasv(ftp_t *x, char *command, char *par){	int	c, k, rc;	char	*p, line[200];	dtc_t	*ch;	ch = &x->ch;	rc = sfputc(x, "PASV", "", line, sizeof(line), &p);	if (rc != 227) {		cfputs(x, "500 not accepted");		return (0);		}	/*	 * Ende der Port-Koordinaten im Server-Response suchen.	 */	k = strlen(line);	while (k > 0  &&  isdigit(line[k-1]) == 0)		k--;	if (isdigit(line[k-1])) {		line[k--] = 0;		while (k > 0  &&  (isdigit(line[k-1])  ||  line[k-1] == ','))			k--;		}	/*	 * line[k] sollte jetzt auf die erste Ziffer des PASV Response	 * zeigen.	 */	if (isdigit(line[k]) == 0) {		syslog(LOG_NOTICE, "can't locate passive response: %s", line);		cfputs(x, "500 not accepted");		return (0);		}	/*	 * Auslesen der PASV IP-Nummer und des Ports.	 */	p = &line[k];	_getipnum(p, &p, ch->server.ipnum, sizeof(ch->server.ipnum));	ch->server.port = _getport(p, &p);	if (debug)		fprintf (stderr, "server listens on %s:%u\n", ch->server.ipnum, ch->server.port);	get_interface_info(0, ch->inside.ipnum, sizeof(ch->inside.ipnum));	ch->isock = bind_to_port(ch->inside.ipnum, 0);	ch->inside.port = get_interface_info(ch->isock, line, sizeof(line));	if (debug)		fprintf (stderr, "listening on %s:%u\n", ch->inside.ipnum, ch->inside.port);	snprintf (line, sizeof(line) - 2, "227 Entering Passive Mode (%s,%u,%u)",			ch->inside.ipnum,			ch->inside.port >> 8, ch->inside.port & 0xFF);	for (p=line; (c = *p) != 0; p++) {		if (c == '.')			*p = ',';		}	cfputs(x, line);	ch->osock = -1;	ch->mode  = MODE_PASSIVE;	ch->state = PORT_LISTEN;	*ch->command = 0;	ch->operation = 0;	return (rc);}int dofeat(ftp_t *x){	/*	 * Not so easy because we have to align with the server response. 	 */	int	rc;	char	*p, word[80], serverfeature[80], line[300];	static char *proxyfeatlist = "SIZE:MDTM";	sfputs(x, "%s", "FEAT");	if (sfgets(x, line, sizeof(line)) == NULL) {		syslog(LOG_NOTICE, "monitor: server not responding");		exit (1);		}	rc = atoi(line);	if (rc != 211) {		/* kein FEAT Support */ ;		cfputs(x, "502 command not implemented");		return (1);		}	cfputs(x, "211-feature list follows");	while (1) {		if (sfgets(x, line, sizeof(line)) == NULL) {			syslog(LOG_NOTICE, "lost server in FEAT response");			exit (1);			}		else if (*line != ' ') { 			/*			 * RFC2389 specifies exactly one space in this			 * multi-line response.  Nothing else.			 */			break;			}		/* Get feature from server response ...		 */		copy_string(serverfeature, line, sizeof(serverfeature));		strupr(serverfeature);		/* ... and compare it against our feature list		 */		p = proxyfeatlist;		while (*get_quoted(&p, ':', word, sizeof(word)) != 0) {			if (strcmp(word, serverfeature) == 0) {				snprintf (line, sizeof(line) - 4, " %s", word);				cfputs(x, line);				break;				}			}		}	cfputs(x, "211 end");	return (0);}int setvar(ftp_t *x, char *var, char *value){	char	varname[200];	#if defined SOLARIS	snprintf (varname, sizeof(varname) - 2, "%s%s=%s", x->config->varname, var, value != NULL? value: "");	putenv(varname);	#else	snprintf (varname, sizeof(varname) - 2, "%s%s", x->config->varname, var);	setenv(varname, value != NULL? value: "", 1);	#endif	return (0);}int set_variables(ftp_t *x){	char	val[200];	setvar(x, "INTERFACE", x->interface);	snprintf (val, sizeof(val) - 2, "%u", x->port);	setvar(x, "PORT", val);	setvar(x, "CLIENT", x->client_ip);	setvar(x, "CLIENTNAME", x->client);	setvar(x, "SERVER", x->server.ipnum);	snprintf (val, sizeof(val) - 2, "%u", x->server.port);	setvar(x, "SERVERPORT", val);	setvar(x, "SERVERNAME", x->server.name);	setvar(x, "SERVERLOGIN", x->username);	setvar(x, "USERNAME", x->local.username);	setvar(x, "PASSWD", x->local.password);	return (0);}int run_acp(ftp_t *x){	int	rc, pid, pfd[2];	char	line[300];		if (*x->config->acp == 0)		return (0);	rc = 0;	if (pipe(pfd) != 0) {		syslog(LOG_NOTICE, "-ERR: can't pipe: %s", strerror(errno));		exit (1);		}	else if ((pid = fork()) < 0) {		syslog(LOG_NOTICE, "-ERR: can't fork acp: %s", strerror(errno));		exit (1);		}	else if (pid == 0) {		int	argc;		char	*argv[32];		close(0);		/* Das acp kann nicht vom client lesen. */		dup2(pfd[1], 2);	/* stderr wird vom parent gelesen. */		close(pfd[0]);		set_variables(x);				copy_string(line, x->config->acp, sizeof(line));		argc = split(line, argv, ' ', 30);		argv[argc] = NULL;		execvp(argv[0], argv);		syslog(LOG_NOTICE, "-ERR: can't exec acp %s: %s", argv[0], strerror(errno));		exit (1);		}	else {		int	len;		char	message[300];		close(pfd[1]);		*message = 0;		if ((len = read(pfd[0], message, sizeof(message) - 2)) < 0)			len = 0;		message[len] = 0;		noctrl(message);		close(pfd[0]);		if (waitpid(pid, &rc, 0) < 0) {			syslog(LOG_NOTICE, "-ERR: error while waiting for acp: %s", strerror(errno));			exit (1);			}		rc = WIFEXITED(rc) != 0? WEXITSTATUS(rc): 1;		if (*message == 0)			copy_string(message, rc == 0? "access granted": "access denied", sizeof(message));		if (*message != 0)			syslog(LOG_NOTICE, "%s (rc= %d)", message, rc);		}			return (rc);}static char *getvarname(char **here, char *var, int size){	int	c, k;	size = size - 2;	k = 0;	while ((c = **here) != 0) {		*here += 1;		if (c == ' '  ||  c == '\t'  ||  c == '=')			break;		if (k < size)			var[k++] = c;		}	var[k] = 0;	strupr(var);	*here = skip_ws(*here);	return (var);}

⌨️ 快捷键说明

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