Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 157005 | Differences between
and this patch

Collapse All | Expand All

(-)oftpd-0.3.7/src/daemon_assert.c (+1 lines)
Lines 3-8 Link Here
3
#include <pthread.h>
3
#include <pthread.h>
4
#include <syslog.h>
4
#include <syslog.h>
5
#include <stdio.h>
5
#include <stdio.h>
6
#include <stdlib.h>
6
7
7
#ifndef NDEBUG
8
#ifndef NDEBUG
8
void daemon_assert_fail(const char *assertion,
9
void daemon_assert_fail(const char *assertion,
(-)oftpd-0.3.7/src/ftp_command.c (-6 / +13 lines)
Lines 137-143 int ftp_command_parse(const char *input, Link Here
137
	    input++;
137
	    input++;
138
138
139
            /* parse the host & port information (if any) */
139
            /* parse the host & port information (if any) */
140
	    input = parse_host_port(&tmp.arg[0].host_port, input);
140
	    SAFAM(&tmp.arg[0].host_port) = AF_INET; /* force type to AF_INET */
141
	    input = parse_host_port((struct sockaddr_in *)&tmp.arg[0].host_port, input);
141
	    if (input == NULL) {
142
	    if (input == NULL) {
142
	        return 0;
143
	        return 0;
143
	    }
144
	    }
Lines 325-330 static const char *parse_host_port(struc Link Here
325
    struct in_addr in_addr;
326
    struct in_addr in_addr;
326
327
327
    daemon_assert(addr != NULL);
328
    daemon_assert(addr != NULL);
329
    daemon_assert(SAFAM(addr) == AF_INET);
328
    daemon_assert(s != NULL);
330
    daemon_assert(s != NULL);
329
331
330
    /* scan in 5 pairs of "#," */
332
    /* scan in 5 pairs of "#," */
Lines 448-455 static const char *parse_host_port_long( Link Here
448
	if (port_len != 2) {
450
	if (port_len != 2) {
449
	    return NULL;
451
	    return NULL;
450
	}
452
	}
451
	memcpy(&SINADDR(sa), addr, addr_len);
453
	memcpy(&SIN4ADDR(sa), addr, addr_len);
452
	SINPORT(sa) = htons((port[0] << 8) + port[1]);
454
	SIN4PORT(sa) = htons((port[0] << 8) + port[1]);
453
    }
455
    }
454
#ifdef INET6
456
#ifdef INET6
455
    else if (family == 6) {
457
    else if (family == 6) {
Lines 461-467 static const char *parse_host_port_long( Link Here
461
	    return NULL;
463
	    return NULL;
462
	}
464
	}
463
	memcpy(&SIN6ADDR(sa), addr, addr_len);
465
	memcpy(&SIN6ADDR(sa), addr, addr_len);
464
	SINPORT(sa) = htons((port[0] << 8) + port[1]);
466
	SIN6PORT(sa) = htons((port[0] << 8) + port[1]);
465
    }
467
    }
466
#endif
468
#endif
467
    else {
469
    else {
Lines 550-556 static const char *parse_host_port_ext(s Link Here
550
#else
552
#else
551
    {
553
    {
552
        struct addrinfo hints;
554
        struct addrinfo hints;
553
	struct *res;
555
	struct addrinfo*res;
554
556
555
	memset(&hints, 0, sizeof(hints));
557
	memset(&hints, 0, sizeof(hints));
556
	hints.ai_flags = AI_NUMERICHOST;
558
	hints.ai_flags = AI_NUMERICHOST;
Lines 567-573 static const char *parse_host_port_ext(s Link Here
567
#endif /* INET6 */
569
#endif /* INET6 */
568
570
569
    SAFAM(sa) = family;
571
    SAFAM(sa) = family;
570
    SINPORT(sa) = htons(port);
572
#ifdef INET6
573
    if (family == AF_INET6)
574
	SIN6PORT(sa) = htons(port);
575
    else
576
#endif
577
	SIN4PORT(sa) = htons(port);
571
578
572
    /* return new pointer */
579
    /* return new pointer */
573
    return s;
580
    return s;
(-)oftpd-0.3.7/src/ftp_listener.c (-17 / +38 lines)
Lines 135-151 int ftp_listener_init(ftp_listener_t *f, Link Here
135
 * -- Matthew Danish [3/20/2001]
135
 * -- Matthew Danish [3/20/2001]
136
 */
136
 */
137
137
138
        hints.ai_flags  = AI_PASSIVE;
138
#ifdef INET6
139
#ifdef INET6
140
	/* For IPv6, try provided host/address as IPv6 address, but fall
141
	 * back to IPv4 if we fail
142
	 */
139
        hints.ai_family = AF_INET6;
143
        hints.ai_family = AF_INET6;
144
	gai_err = getaddrinfo(address, NULL, &hints, &res);
145
#ifdef EAI_ADDRFAMILY
146
	if (gai_err == EAI_ADDRFAMILY) {
147
	    hints.ai_family = AF_INET;
148
	    gai_err = getaddrinfo(address, NULL, &hints, &res);
149
	}
150
#else
151
	if (gai_err != 0) {
152
	    hints.ai_family = AF_INET;
153
	    gai_err = getaddrinfo(address, NULL, &hints, &res);
154
	}
155
#endif
140
#else
156
#else
141
        hints.ai_family = AF_INET;
157
        hints.ai_family = AF_INET;
142
#endif
143
144
        hints.ai_flags  = AI_PASSIVE;
145
146
        gai_err = getaddrinfo(address, NULL, &hints, &res);
158
        gai_err = getaddrinfo(address, NULL, &hints, &res);
159
#endif
147
        if (gai_err != 0) {
160
        if (gai_err != 0) {
148
            error_init(err, gai_err, "error parsing server socket address; %s", 
161
            error_init(err, -gai_err, "error parsing server socket address; %s", 
149
                       gai_strerror(gai_err));
162
                       gai_strerror(gai_err));
150
            return 0;
163
            return 0;
151
        }
164
        }
Lines 154-170 int ftp_listener_init(ftp_listener_t *f, Link Here
154
        freeaddrinfo(res);
167
        freeaddrinfo(res);
155
    } 
168
    } 
156
169
157
    if (port == 0) {
170
#ifdef INET6
158
        SINPORT(&sock_addr) = htons(DEFAULT_FTP_PORT);
171
    if (SAFAM(&sock_addr) == AF_INET6)
159
    } else {
172
	SIN6PORT(&sock_addr) = htons(port == 0 ? DEFAULT_FTP_PORT : port);
160
        SINPORT(&sock_addr) = htons(port);
173
    else
161
    }
174
#endif
162
175
	SIN4PORT(&sock_addr) = htons(port == 0 ? DEFAULT_FTP_PORT : port);
163
176
#ifdef INET6
164
    inet_ntop_ret = inet_ntop(SAFAM(&sock_addr), 
177
    if (SAFAM(&sock_addr) == AF_INET6)
165
                              (void *)&SINADDR(&sock_addr), 
178
	inet_ntop_ret = inet_ntop(AF_INET6,
179
                              (void *)&SIN6ADDR(&sock_addr),
166
                              buf, 
180
                              buf, 
167
                              sizeof(buf));
181
                              sizeof(buf));
182
    else
183
#endif
184
	inet_ntop_ret = inet_ntop(SAFAM(&sock_addr),
185
                              (void *)&SIN4ADDR(&sock_addr),
186
                              buf, 
187
                              sizeof(buf));
188
168
    if (inet_ntop_ret == NULL) {
189
    if (inet_ntop_ret == NULL) {
169
        error_init(err, errno, "error converting server address to ASCII; %s", 
190
        error_init(err, errno, "error converting server address to ASCII; %s", 
170
                   strerror(errno));
191
                   strerror(errno));
Lines 177-183 int ftp_listener_init(ftp_listener_t *f, Link Here
177
    
198
    
178
199
179
    /* okay, finally do some socket manipulation */
200
    /* okay, finally do some socket manipulation */
180
    fd = socket(AF_INET, SOCK_STREAM, 0);
201
    fd = socket(SAFAM(&sock_addr), SOCK_STREAM, 0);
181
    if (fd == -1) {
202
    if (fd == -1) {
182
        error_init(err, errno, "error creating socket; %s", strerror(errno));
203
        error_init(err, errno, "error creating socket; %s", strerror(errno));
183
        return 0;
204
        return 0;
Lines 194-200 int ftp_listener_init(ftp_listener_t *f, Link Here
194
    }
215
    }
195
216
196
    if (bind(fd, (struct sockaddr *)&sock_addr, 
217
    if (bind(fd, (struct sockaddr *)&sock_addr, 
197
             sizeof(struct sockaddr_in)) != 0) 
218
             SAFAM(&sock_addr) == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) 
198
    {
219
    {
199
        close(fd);
220
        close(fd);
200
        error_init(err, errno, "error binding address; %s", strerror(errno));
221
        error_init(err, errno, "error binding address; %s", strerror(errno));
Lines 461-467 static char *addr2string(const sockaddr_ Link Here
461
                         0, 
482
                         0, 
462
                         NI_NUMERICHOST);
483
                         NI_NUMERICHOST);
463
    if (error != 0) {
484
    if (error != 0) {
464
        syslog(LOG_WARN, "getnameinfo error; %s", gai_strerror(error));
485
        syslog(LOG_WARNING, "getnameinfo error; %s", gai_strerror(error));
465
        ret_val = "Unknown IP";
486
        ret_val = "Unknown IP";
466
    } else {
487
    } else {
467
        ret_val = addr;
488
        ret_val = addr;
(-)oftpd-0.3.7/src/ftp_session.c (-79 / +144 lines)
Lines 44-49 Link Here
44
#define ADDRPORT_STRLEN 58
44
#define ADDRPORT_STRLEN 58
45
45
46
/* prototypes */
46
/* prototypes */
47
static int alloc_ipv4(ftp_session_t *f);
47
static int invariant(const ftp_session_t *f);
48
static int invariant(const ftp_session_t *f);
48
static void reply(ftp_session_t *f, int code, const char *fmt, ...);
49
static void reply(ftp_session_t *f, int code, const char *fmt, ...);
49
static void change_dir(ftp_session_t *f, const char *new_dir);
50
static void change_dir(ftp_session_t *f, const char *new_dir);
Lines 137-175 int ftp_session_init(ftp_session_t *f, Link Here
137
    daemon_assert(strlen(dir) <= PATH_MAX);
138
    daemon_assert(strlen(dir) <= PATH_MAX);
138
    daemon_assert(err != NULL);
139
    daemon_assert(err != NULL);
139
140
140
#ifdef INET6
141
    memset(&f->server_ipv4_addr, 0, sizeof(f->server_ipv4_addr));
141
    /* if the control connection is on IPv6, we need to get an IPv4 address */
142
    /* to bind the socket to */
143
    if (SSFAM(server_addr) == AF_INET6) {
144
	struct addrinfo hints;
145
	struct addrinfo *res;
146
	int errcode;
147
148
        /* getaddrinfo() does the job nicely */
149
        memset(&hints, 0, sizeof(struct addrinfo));
150
        hints.ai_family = AF_INET;
151
	hints.ai_flags = AI_PASSIVE;
152
	if (getaddrinfo(NULL, "ftp", &hints, &res) != 0) {
153
	    error_init(err, 0, "unable to determing IPv4 address; %s",
154
	        gai_strerror(errcode));
155
	    return 0;
156
	}
157
158
        /* let's sanity check */
159
	daemon_assert(res != NULL);
160
	daemon_assert(sizeof(f->server_ipv4_addr) >= res->ai_addrlen);
161
        daemon_assert(SSFAM(host_port) == AF_INET);
162
163
        /* copy the result and free memory as necessary */
164
	memcpy(&f->server_ipv4_addr, res->ai_addr, res->ai_addrlen);
165
        freeaddrinfo(res);
166
    } else {
167
        daemon_assert(SSFAM(host_port) == AF_INET);
168
        f->server_ipv4_addr = *server_addr;
169
    }
170
#else
171
    f->server_ipv4_addr = *server_addr;
172
#endif
173
142
174
    f->session_active = 1;
143
    f->session_active = 1;
175
    f->command_number = 0;
144
    f->command_number = 0;
Lines 291-296 void ftp_session_destroy(ftp_session_t * Link Here
291
    }
260
    }
292
}
261
}
293
262
263
#ifdef INET6
264
static int alloc_ipv4(ftp_session_t *f)
265
{
266
    /* if the control connection is on IPv6, we need to get an IPv4 address */
267
    /* to bind the socket to */
268
    if (SSFAM(&f->server_addr) == AF_INET6) {
269
	struct addrinfo hints;
270
	struct addrinfo *res;
271
	int errcode;
272
273
	/* getaddrinfo() does the job nicely */
274
	memset(&hints, 0, sizeof(struct addrinfo));
275
	hints.ai_family = AF_INET;
276
	hints.ai_flags = AI_PASSIVE;
277
	if ((errcode = getaddrinfo(NULL, "ftp", &hints, &res)) != 0) {
278
	    syslog(LOG_ERR, "Unable to determing IPv4 address: %s", gai_strerror(errcode));
279
	    return 0;
280
	}
281
282
	/* let's sanity check */
283
	daemon_assert(res != NULL);
284
	daemon_assert(sizeof(f->server_ipv4_addr) >= res->ai_addrlen);
285
	daemon_assert(SSFAM(&f->server_ipv4_addr) == AF_INET);
286
287
	/* copy the result and free memory as necessary */
288
	memcpy(&f->server_ipv4_addr, res->ai_addr, res->ai_addrlen);
289
	freeaddrinfo(res);
290
    } else {
291
	daemon_assert(SSFAM(&f->server_addr) == AF_INET);
292
	memcpy(&f->server_ipv4_addr, &f->server_addr, sizeof(f->server_ipv4_addr));
293
    }
294
    return 1;
295
}
296
#else
297
inline static int alloc_ipv4(ftp_session_t *f)
298
{
299
    return 0;
300
}
301
#endif
302
294
#ifndef NDEBUG
303
#ifndef NDEBUG
295
static int invariant(const ftp_session_t *f)
304
static int invariant(const ftp_session_t *f)
296
{
305
{
Lines 333-339 static int invariant(const ftp_session_t Link Here
333
	        return 0;
342
	        return 0;
334
	    }
343
	    }
335
	    break;
344
	    break;
336
	case DATA_PASSIVE:
345
	case DATA_PASSIVE_4:
346
	case DATA_PASSIVE_6:
337
	    if (f->server_fd < 0) {
347
	    if (f->server_fd < 0) {
338
	        return 0;
348
	        return 0;
339
	    }
349
	    }
Lines 424-439 static void get_addr_str(const sockaddr_ Link Here
424
    /* buf must be able to contain (at least) a string representing an
434
    /* buf must be able to contain (at least) a string representing an
425
     * ipv4 addr, followed by the string " port " (6 chars) and the port
435
     * ipv4 addr, followed by the string " port " (6 chars) and the port
426
     * number (which is 5 chars max), plus the '\0' character. */ 
436
     * number (which is 5 chars max), plus the '\0' character. */ 
427
    daemon_assert(bufsiz >= (INET_ADDRSTRLEN + 12));
437
    daemon_assert(bufsiz >= (INET6_ADDRSTRLEN + 12));
428
438
429
    error = getnameinfo(client_addr, sizeof(sockaddr_storage_t), buf, 
439
    error = getnameinfo((struct sockaddr *)s, sizeof(sockaddr_storage_t), buf, 
430
                bufsiz, NULL, 0, NI_NUMERICHOST);
440
                bufsiz, NULL, 0, NI_NUMERICHOST);
431
    /* getnameinfo() should never fail when called with NI_NUMERICHOST */
441
    /* getnameinfo() should never fail when called with NI_NUMERICHOST */
432
    daemon_assert(error == 0);
442
    daemon_assert(error == 0);
433
443
434
    len = strlen(buf);
444
    len = strlen(buf);
435
    daemon_assert(bufsiz >= len+12);
445
    daemon_assert(bufsiz >= len+12);
436
    snprintf(buf+len, bufsiz-len, " port %d", ntohs(SINPORT(&f->client_addr)));
446
    snprintf(buf+len, bufsiz-len, " port %d", ntohs(SINPORT(s)));
437
}
447
}
438
#else
448
#else
439
static void get_addr_str(const sockaddr_storage_t *s, char *buf, int bufsiz)
449
static void get_addr_str(const sockaddr_storage_t *s, char *buf, int bufsiz)
Lines 639-645 static void set_port(ftp_session_t *f, c Link Here
639
        reply(f, 500, "Port may not be less than 1024, which is reserved.");
649
        reply(f, 500, "Port may not be less than 1024, which is reserved.");
640
    } else {
650
    } else {
641
        /* close any outstanding PASSIVE port */
651
        /* close any outstanding PASSIVE port */
642
        if (f->data_channel == DATA_PASSIVE) {
652
        if (f->data_channel == DATA_PASSIVE_4 || f->data_channel == DATA_PASSIVE_6) {
643
            close(f->server_fd);
653
            close(f->server_fd);
644
	    f->server_fd = -1;
654
	    f->server_fd = -1;
645
        }
655
        }
Lines 689-696 static void do_lprt(ftp_session_t *f, co Link Here
689
        reply(f, 521, "Only IPv4 supported, address family (4)");
699
        reply(f, 521, "Only IPv4 supported, address family (4)");
690
    }
700
    }
691
#endif
701
#endif
692
702
    else
693
    set_port(f, host_port);
703
        set_port(f, host_port);
694
704
695
    daemon_assert(invariant(f));
705
    daemon_assert(invariant(f));
696
}
706
}
Lines 733-744 static int set_pasv(ftp_session_t *f, so Link Here
733
743
734
    for (;;) {
744
    for (;;) {
735
        port = get_passive_port();
745
        port = get_passive_port();
736
        SINPORT(bind_addr) = htons(port);
746
#ifdef INET6
747
	if (SAFAM(bind_addr) == AF_INET6)
748
	    SIN6PORT(bind_addr) = htons(port);
749
	else
750
	    SIN4PORT(bind_addr) = htons(port);
737
	if (bind(socket_fd, (struct sockaddr *)bind_addr, 
751
	if (bind(socket_fd, (struct sockaddr *)bind_addr, 
738
	    sizeof(struct sockaddr)) == 0) 
752
	    SAFAM(bind_addr) == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) == 0)
739
	{
740
	    break;
753
	    break;
741
	}
754
#else
755
	SIN4PORT(bind_addr) = htons(port);
756
	if (bind(socket_fd, (struct sockaddr *)bind_addr, sizeof(struct sockaddr_in)) == 0)
757
	    break;
758
#endif
742
	if (errno != EADDRINUSE) {
759
	if (errno != EADDRINUSE) {
743
            reply(f, 500, "Error binding server port; %s.", strerror(errno));
760
            reply(f, 500, "Error binding server port; %s.", strerror(errno));
744
            close(socket_fd);
761
            close(socket_fd);
Lines 771-784 static void do_pasv(ftp_session_t *f, co Link Here
771
        goto exit_pasv;
788
        goto exit_pasv;
772
    }
789
    }
773
790
774
    socket_fd = set_pasv(f, &f->server_ipv4_addr);
791
    if (SAFAM(&f->server_addr) == AF_INET)
792
	socket_fd = set_pasv(f, (sockaddr_storage_t *)&f->server_addr);
793
    else if (SAFAM(&f->server_ipv4_addr) == AF_UNSPEC) {
794
	if (!alloc_ipv4(f)) {
795
	    reply(f, 522, "PASV not possible, use EPSV");
796
	    goto exit_pasv;
797
	}
798
	socket_fd = set_pasv(f, (sockaddr_storage_t *)&f->server_ipv4_addr);
799
    } else
800
	socket_fd = set_pasv(f, (sockaddr_storage_t *)&f->server_ipv4_addr);
775
    if (socket_fd == -1) {
801
    if (socket_fd == -1) {
776
        goto exit_pasv;
802
        goto exit_pasv;
777
    }
803
    }
778
804
779
    /* report port to client */
805
    /* report port to client */
780
    addr = ntohl(f->server_ipv4_addr.sin_addr.s_addr);
806
    if (SAFAM(&f->server_addr) == AF_INET) {
781
    port = ntohs(f->server_ipv4_addr.sin_port);
807
	addr = ntohl(SIN4ADDR(&f->server_addr).s_addr);
808
	port = ntohs(SIN4PORT(&f->server_addr));
809
    } else {
810
	addr = ntohl(SIN4ADDR(&f->server_ipv4_addr).s_addr);
811
	port = ntohs(SIN4PORT(&f->server_ipv4_addr));
812
    }
782
    reply(f, 227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d).",
813
    reply(f, 227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d).",
783
        addr >> 24, 
814
        addr >> 24, 
784
	(addr >> 16) & 0xff,
815
	(addr >> 16) & 0xff,
Lines 788-797 static void do_pasv(ftp_session_t *f, co Link Here
788
	port & 0xff);
819
	port & 0xff);
789
820
790
   /* close any outstanding PASSIVE port */
821
   /* close any outstanding PASSIVE port */
791
   if (f->data_channel == DATA_PASSIVE) {
822
   if (f->data_channel == DATA_PASSIVE_4 || f->data_channel == DATA_PASSIVE_6) {
792
       close(f->server_fd);
823
       close(f->server_fd);
793
   }
824
   }
794
   f->data_channel = DATA_PASSIVE;
825
   f->data_channel = DATA_PASSIVE_4;
795
   f->server_fd = socket_fd;
826
   f->server_fd = socket_fd;
796
827
797
exit_pasv:
828
exit_pasv:
Lines 841-850 static void do_lpsv(ftp_session_t *f, co Link Here
841
    reply(f, 228, "Entering Long Passive Mode %s", addr);
872
    reply(f, 228, "Entering Long Passive Mode %s", addr);
842
873
843
   /* close any outstanding PASSIVE port */
874
   /* close any outstanding PASSIVE port */
844
   if (f->data_channel == DATA_PASSIVE) {
875
   if (f->data_channel == DATA_PASSIVE_4 || f->data_channel == DATA_PASSIVE_6) {
845
       close(f->server_fd);
876
       close(f->server_fd);
846
   }
877
   }
847
   f->data_channel = DATA_PASSIVE;
878
#ifdef INET6
879
   f->data_channel = SSFAM(&f->server_addr) == AF_INET6 ? DATA_PASSIVE_6 : DATA_PASSIVE_4;
880
#else
881
   f->data_channel = DATA_PASSIVE_4;
882
#endif
848
   f->server_fd = socket_fd;
883
   f->server_fd = socket_fd;
849
884
850
exit_lpsv:
885
exit_lpsv:
Lines 875-885 static void do_epsv(ftp_session_t *f, co Link Here
875
		reply(f, 200, "EPSV ALL command successful.");
910
		reply(f, 200, "EPSV ALL command successful.");
876
		goto exit_epsv;
911
		goto exit_epsv;
877
	    case 1:
912
	    case 1:
878
	        addr = (sockaddr_storage_t *)&f->server_ipv4_addr;
913
		if (SAFAM(&f->server_addr) == AF_INET)
914
		    addr = &f->server_addr;
915
		else if (SAFAM(&f->server_ipv4_addr) == AF_UNSPEC) {
916
		    if (!alloc_ipv4(f)) {
917
			reply(f, 522, "Only IPv6 supported, use (2)");
918
			goto exit_epsv;
919
		    }
920
		    addr = &f->server_ipv4_addr;
921
		} else
922
		    addr = &f->server_ipv4_addr;
879
		break;
923
		break;
880
#ifdef INET6
924
#ifdef INET6
881
	    case 2:
925
	    case 2:
882
	        addr = &f->server_addr;
926
		if (SAFAM(&f->server_addr) == AF_INET) {
927
		    reply(f, 522, "Only IPv4 supported, use (1)");
928
		    goto exit_epsv;
929
		}
930
		addr = &f->server_addr;
883
		break;
931
		break;
884
	    default:
932
	    default:
885
	        reply(f, 522, "Only IPv4 and IPv6 supported, use (1,2)");
933
	        reply(f, 522, "Only IPv4 and IPv6 supported, use (1,2)");
Lines 903-912 static void do_epsv(ftp_session_t *f, co Link Here
903
        ntohs(SINPORT(&f->server_addr)));
951
        ntohs(SINPORT(&f->server_addr)));
904
952
905
    /* close any outstanding PASSIVE port */
953
    /* close any outstanding PASSIVE port */
906
    if (f->data_channel == DATA_PASSIVE) {
954
    if (f->data_channel == DATA_PASSIVE_4 || f->data_channel == DATA_PASSIVE_6) {
907
        close(f->server_fd);
955
        close(f->server_fd);
908
    }
956
    }
909
    f->data_channel = DATA_PASSIVE;
957
    f->data_port = *addr;
958
#ifdef INET6
959
    if (cmd->num_arg == 0)
960
	f->data_channel = SAFAM(&f->server_addr) == AF_INET6 ? DATA_PASSIVE_6 : DATA_PASSIVE_4;
961
    else
962
#endif
963
	f->data_channel = cmd->arg[0].num == 2 ? DATA_PASSIVE_6 : DATA_PASSIVE_4;
910
    f->server_fd = socket_fd;  
964
    f->server_fd = socket_fd;  
911
965
912
exit_epsv:
966
exit_epsv:
Lines 1278-1288 static void do_stor(ftp_session_t *f, co Link Here
1278
static int open_connection(ftp_session_t *f)
1332
static int open_connection(ftp_session_t *f)
1279
{
1333
{
1280
    int socket_fd;
1334
    int socket_fd;
1281
    struct sockaddr_in addr;
1335
    sockaddr_storage_t addr;
1282
    unsigned addr_len;
1336
    unsigned addr_len;
1283
1337
1284
    daemon_assert((f->data_channel == DATA_PORT) || 
1338
    daemon_assert((f->data_channel == DATA_PORT) || 
1285
                  (f->data_channel == DATA_PASSIVE));
1339
                  (f->data_channel == DATA_PASSIVE_4) ||
1340
		  (f->data_channel == DATA_PASSIVE_6));
1286
1341
1287
    if (f->data_channel == DATA_PORT) {
1342
    if (f->data_channel == DATA_PORT) {
1288
        socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
1343
        socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
Lines 1298-1306 static int open_connection(ftp_session_t Link Here
1298
	    return -1;
1353
	    return -1;
1299
	}
1354
	}
1300
    } else {
1355
    } else {
1301
        daemon_assert(f->data_channel == DATA_PASSIVE);
1356
        daemon_assert(f->data_channel == DATA_PASSIVE_4 || f->data_channel == DATA_PASSIVE_6);
1302
1357
1303
        addr_len = sizeof(struct sockaddr_in);
1358
	addr_len = sizeof(addr);
1304
        socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
1359
        socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
1305
	if (socket_fd == -1) {
1360
	if (socket_fd == -1) {
1306
	    reply(f, 425, "Error accepting connection; %s.", strerror(errno));
1361
	    reply(f, 425, "Error accepting connection; %s.", strerror(errno));
Lines 1310-1333 static int open_connection(ftp_session_t Link Here
1310
        /* in IPv6, the client can connect to a channel using a different */
1365
        /* in IPv6, the client can connect to a channel using a different */
1311
	/* protocol - in that case, we'll just blindly let the connection */
1366
	/* protocol - in that case, we'll just blindly let the connection */
1312
	/* through, otherwise verify addresses match */
1367
	/* through, otherwise verify addresses match */
1313
        if (SAFAM(addr) == SSFAM(&f->client_addr)) {
1368
        if (SAFAM(&addr) == SSFAM(&f->client_addr)) {
1314
	    if (memcmp(&SINADDR(&f->client_addr), &SINADDR(&addr), 
1369
	    if (SAFAM(&addr) == AF_INET6) {
1315
	               sizeof(SINADDR(&addr))))
1370
		if (memcmp(&SIN6ADDR(&f->client_addr), &SIN6ADDR(&addr),
1316
	    {
1371
		           sizeof(struct in6_addr))) {
1317
	        reply(f, 425, 
1372
		    reply(f, 425, "Error accepting connection; "
1318
	          "Error accepting connection; connection from invalid IP.");
1373
		                  "connection from invalid IP.");
1319
	        close(socket_fd);
1374
		    close(socket_fd);
1320
	        return -1;
1375
		    return -1;
1321
            }
1376
        	}
1322
	}
1377
	    } else {
1323
#else
1378
#endif
1324
	if (memcmp(&f->client_addr.sin_addr, 
1379
		if (memcmp(&SIN4ADDR(&f->client_addr), &SIN4ADDR(&addr),
1325
	    &addr.sin_addr, sizeof(struct in_addr))) 
1380
		           sizeof(struct in_addr))) {
1326
	{
1381
		    reply(f, 425, "Error accepting connection; "
1327
	    reply(f, 425, 
1382
		                  "connection from invalid IP.");
1328
	      "Error accepting connection; connection from invalid IP.");
1383
		    close(socket_fd);
1329
	    close(socket_fd);
1384
		    return -1;
1330
	    return -1;
1385
        	}
1386
#ifdef INET6
1387
	    }
1331
	}
1388
	}
1332
#endif
1389
#endif
1333
    }
1390
    }
Lines 1822-1830 static int ip_equal(const sockaddr_stora Link Here
1822
    if (SSFAM(a) != SSFAM(b)) {
1879
    if (SSFAM(a) != SSFAM(b)) {
1823
        return 0;
1880
        return 0;
1824
    }
1881
    }
1825
    if (memcmp(&SINADDR(a), &SINADDR(b), sizeof(SINADDR(a))) != 0) {
1882
#ifdef INET6
1826
        return 0;
1883
    if (SSFAM(a) == AF_INET6) {
1884
	if (memcmp(&SIN6ADDR(a), &SIN6ADDR(b), sizeof(struct in6_addr)) != 0)
1885
	    return 0;
1886
    } else {
1887
#endif
1888
	if (memcmp(&SIN4ADDR(a), &SIN4ADDR(b), sizeof(struct in_addr)) != 0)
1889
	    return 0;
1890
#ifdef INET6
1827
    }
1891
    }
1892
#endif
1828
    return 1;
1893
    return 1;
1829
}
1894
}
1830
1895
(-)oftpd-0.3.7/src/ftp_session.h (-3 / +4 lines)
Lines 25-32 Link Here
25
#define STRU_RECORD 1
25
#define STRU_RECORD 1
26
26
27
/* data path chosen */
27
/* data path chosen */
28
#define DATA_PORT     0
28
#define DATA_PORT      0
29
#define DATA_PASSIVE  1
29
#define DATA_PASSIVE_4 1
30
#define DATA_PASSIVE_6 2
30
31
31
/* space required for text representation of address and port, 
32
/* space required for text representation of address and port, 
32
   e.g. "192.168.0.1 port 1024" or 
33
   e.g. "192.168.0.1 port 1024" or 
Lines 59-65 typedef struct { Link Here
59
60
60
    /* address of server (including IPv4 version) */
61
    /* address of server (including IPv4 version) */
61
    sockaddr_storage_t server_addr;
62
    sockaddr_storage_t server_addr;
62
    struct sockaddr_in server_ipv4_addr;
63
    sockaddr_storage_t server_ipv4_addr;
63
64
64
    /* telnet session to encapsulate control channel logic */
65
    /* telnet session to encapsulate control channel logic */
65
    telnet_session_t *telnet_session;
66
    telnet_session_t *telnet_session;

Return to bug 157005