Exemplo n.º 1
0
static struct ftp_connection_info *add_file_cmd_to_str(struct connection *c)
{
    unsigned char *d = get_url_data(c->url);
    unsigned char *de;
    int del;
    unsigned char port_string[50];
    struct ftp_connection_info *inf, *inf2;
    unsigned char *s;
    int l;
    if (!d) {
        internal("get_url_data failed");
        setcstate(c, S_INTERNAL);
        abort_connection(c);
        return NULL;
    }

    de = init_str(), del = 0;
    add_conv_str(&de, &del, d, strlen(cast_const_char d), -2);
    d = de;
    inf = mem_alloc(sizeof(struct ftp_connection_info));
    memset(inf, 0, sizeof(struct ftp_connection_info));
    l = 0;
    s = init_str();
    inf->pasv = ftp_options.passive_ftp;
#ifdef LINKS_2
    if (*c->socks_proxy) inf->pasv = 1;
    if (ftp_options.eprt_epsv || is_ipv6(c->sock1)) inf->eprt_epsv = 1;
#endif
    c->info = inf;

    if (!inf->pasv) {
        int ps;
#ifdef SUPPORT_IPV6
        if (is_ipv6(c->sock1)) {
            ps = get_pasv_socket_ipv6(c, c->sock1, &c->sock2, port_string);
            if (ps) {
                mem_free(d);
                mem_free(s);
                return NULL;
            }
        } else
#endif
        {
            unsigned char pc[6];
            ps = get_pasv_socket(c, c->sock1, &c->sock2, pc);
            if (ps) {
                mem_free(d);
                mem_free(s);
                return NULL;
            }
            if (inf->eprt_epsv)
                sprintf(cast_char port_string, "|1|%d.%d.%d.%d|%d|", pc[0], pc[1], pc[2], pc[3], (pc[4] << 8) | pc[5]);
            else
                sprintf(cast_char port_string, "%d,%d,%d,%d,%d,%d", pc[0], pc[1], pc[2], pc[3], pc[4], pc[5]);
        }
        if (strlen(cast_const_char port_string) >= sizeof(port_string))
            internal("buffer overflow in get_pasv_socket_ipv6: %d > %d", (int)strlen(cast_const_char port_string), (int)sizeof(port_string));
    }
#ifdef HAVE_IPTOS
    if (ftp_options.set_tos) {
        int rx;
        int on = IPTOS_THROUGHPUT;
        EINTRLOOP(rx, setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)));
    }
#endif
    if (!(de = cast_uchar strchr(cast_const_char d, POST_CHAR))) de = d + strlen(cast_const_char d);
    if (d == de || de[-1] == '/') {
        inf->dir = 1;
        inf->pending_commands = 4;
        add_to_str(&s, &l, cast_uchar "TYPE A\r\n");
        add_port_pasv(&s, &l, inf, port_string);
        add_to_str(&s, &l, cast_uchar "CWD /");
        add_bytes_to_str(&s, &l, d, de - d);
        add_to_str(&s, &l, cast_uchar "\r\nLIST\r\n");
        c->from = 0;
    } else {
        inf->dir = 0;
        inf->pending_commands = 3;
        add_to_str(&s, &l, cast_uchar "TYPE I\r\n");
        add_port_pasv(&s, &l, inf, port_string);
        if (c->from && c->no_cache < NC_IF_MOD) {
            add_to_str(&s, &l, cast_uchar "REST ");
            add_num_to_str(&s, &l, c->from);
            add_to_str(&s, &l, cast_uchar "\r\n");
            inf->rest_sent = 1;
            inf->pending_commands++;
        } else c->from = 0;
        add_to_str(&s, &l, cast_uchar "RETR /");
        add_bytes_to_str(&s, &l, d, de - d);
        add_to_str(&s, &l, cast_uchar "\r\n");
    }
    inf->opc = inf->pending_commands;
    if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc();
    inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1);
    strcpy(cast_char (inf = inf2)->cmdbuf, cast_const_char s);
    mem_free(s);
    c->info = inf;
    mem_free(d);
    return inf;
}
Exemplo n.º 2
0
struct ftp_connection_info *add_file_cmd_to_str(struct connection *c)
{
	unsigned char *d = get_url_data(c->url);
	unsigned char *de;
	int del;
	unsigned char pc[6];
	int ps;
	struct ftp_connection_info *inf, *inf2;
	unsigned char *s;
	int l;
	if (!d) {
		internal("get_url_data failed");
		setcstate(c, S_INTERNAL);
		abort_connection(c);
		return NULL;
	}
	de = init_str(), del = 0;
	add_conv_str(&de, &del, d, strlen(d), -2);
	d = de;
	inf = mem_alloc(sizeof(struct ftp_connection_info));
	memset(inf, 0, sizeof(struct ftp_connection_info));
	l = 0;
	s = init_str();
	inf->pasv = ftp_options.passive_ftp;
	if (*c->socks_proxy) inf->pasv = 1;
	c->info = inf;
	if (!inf->pasv) if ((ps = get_pasv_socket(c, c->sock1, &c->sock2, pc))) {
		mem_free(d);
		return NULL;
	}
#ifdef HAVE_IPTOS
	if (ftp_options.set_tos) {
		int on = IPTOS_THROUGHPUT;
		setsockopt(c->sock2, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int));
	}
#endif
	if (!(de = strchr(d, POST_CHAR))) de = d + strlen(d);
	if (d == de || de[-1] == '/') {
		inf->dir = 1;
		inf->pending_commands = 4;
		add_to_str(&s, &l, "TYPE A\r\n");
		if (!inf->pasv) {
			add_to_str(&s, &l, "PORT ");
			add_num_to_str(&s, &l, pc[0]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[1]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[2]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[3]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[4]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[5]);
			add_to_str(&s, &l, "\r\n");
		} else {
			add_to_str(&s, &l, "PASV\r\n");
		}
		add_to_str(&s, &l, "CWD /");
		add_bytes_to_str(&s, &l, d, de - d);
		add_to_str(&s, &l, "\r\nLIST\r\n");
		c->from = 0;
	} else {
		inf->dir = 0;
		inf->pending_commands = 3;
		add_to_str(&s, &l, "TYPE I\r\n");
		if (!inf->pasv) {
			add_to_str(&s, &l, "PORT ");
			add_num_to_str(&s, &l, pc[0]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[1]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[2]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[3]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[4]);
			add_chr_to_str(&s, &l, ',');
			add_num_to_str(&s, &l, pc[5]);
			add_to_str(&s, &l, "\r\n");
		} else {
			add_to_str(&s, &l, "PASV\r\n");
		}
		if (c->from && c->no_cache < NC_IF_MOD) {
			add_to_str(&s, &l, "REST ");
			add_num_to_str(&s, &l, c->from);
			add_to_str(&s, &l, "\r\n");
			inf->rest_sent = 1;
			inf->pending_commands++;
		} else c->from = 0;
		add_to_str(&s, &l, "RETR /");
		add_bytes_to_str(&s, &l, d, de - d);
		add_to_str(&s, &l, "\r\n");
	}
	inf->opc = inf->pending_commands;
	if ((unsigned)l > MAXINT - sizeof(struct ftp_connection_info) - 1) overalloc();
	inf2 = mem_realloc(inf, sizeof(struct ftp_connection_info) + l + 1);
	strcpy((inf = inf2)->cmdbuf, s);
	mem_free(s);
	c->info = inf;
	mem_free(d);
	return inf;
}