Added some data channel safety checks.
[uftps.git] / enable_passive.c
blobe7392e5798de555cf56f62f709345db60a1e4dde
1 /*
2 * User FTP Server, Share folders over FTP without being root.
3 * Copyright (C) 2008 Isaac Jurado
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option) any later
8 * version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "uftps.h"
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
30 void enable_passive (void)
32 int bsk, l, e;
33 struct sockaddr_in sai;
34 socklen_t sai_len = sizeof(struct sockaddr_in);
35 unsigned char addr[6];
36 char pasv_reply[32];
38 /* Safety check in case there was some error before */
39 if (SS.passive_sk != -1)
41 e = close(SS.passive_sk);
42 if (e == -1)
43 error("Closing unused passive socket");
44 SS.passive_sk = -1;
45 SS.passive_mode = 0;
48 bsk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
49 if (bsk == -1)
51 error("Creating passive socket");
52 goto error;
54 e = 1;
55 setsockopt(bsk, SOL_SOCKET, SO_REUSEADDR, &e, sizeof(int));
57 sai_len = sizeof(struct sockaddr_in);
58 memcpy(&sai, &SS.local_address, sizeof(struct sockaddr_in));
59 sai.sin_port = 0;
60 e = bind(bsk, (struct sockaddr *) &sai, sai_len);
61 if (e == -1)
63 error("Binding to a random port");
64 goto error_close;
66 e = listen(bsk, 1);
67 if (e == -1)
69 error("Listening on passive socket");
70 goto error_close;
73 e = getsockname(bsk, (struct sockaddr *) &sai, &sai_len);
74 if (e == -1)
76 error("Retrieving passive socket information");
77 goto error_close;
79 memcpy(&addr[0], &sai.sin_addr, 4);
80 memcpy(&addr[4], &sai.sin_port, 2);
82 debug("Passive mode listening on port %d", ntohs(sai.sin_port));
84 SS.passive_mode = 1;
85 SS.passive_sk = bsk;
86 l = snprintf(pasv_reply, 32, "227 =%u,%u,%u,%u,%u,%u\r\n", addr[0],
87 addr[1], addr[2], addr[3], addr[4], addr[5]);
89 reply(pasv_reply, l);
90 return;
92 error_close:
93 e = close(bsk);
94 if (e == -1)
95 error("Closing passive socket");
96 error:
97 reply_c("425 No way to open a port for you.\r\n");