Add passive mode (only for localhost) and fix random thread crashes
This commit is contained in:
1 parent
d996ec9fb8
commit
184288ce24
2 files changed
+99
-59
No files matched your search
+83
-10
@@ -8,6 +8,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <thread>
|
||||
|
||||
#include "server.h"
|
||||
#include "filer.cpp"
|
||||
@@ -25,6 +26,7 @@ public:
|
||||
* 2 - Waiting for data
|
||||
*/
|
||||
int state = 0;
|
||||
std::thread thread;
|
||||
|
||||
Client(int &_sock) {
|
||||
control_sock = _sock;
|
||||
@@ -37,7 +39,7 @@ public:
|
||||
return -1;
|
||||
} else if (state > 0) {
|
||||
if (cmd == "SYST") {
|
||||
submit(215, "UNIX");
|
||||
submit(215, "UNIX Type: L8");
|
||||
} else if (cmd == "PWD") {
|
||||
submit(257, "'"+filer->cwd.string()+"'");
|
||||
} else if (cmd == "CWD") {
|
||||
@@ -69,7 +71,76 @@ public:
|
||||
sscanf(argstr.c_str(), "%c", &(filer->type));
|
||||
submit(226, "OK");
|
||||
} else if (cmd == "PASV") {
|
||||
submit(502, "Command not implemented");
|
||||
if ((data_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
perror("pasv socket() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, (char *)&opt, sizeof(opt)) < 0) {
|
||||
perror("pasv setsockopt() failed");
|
||||
close(data_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t dataport;
|
||||
uint8_t netaddr[4];
|
||||
uint8_t netport[2];
|
||||
socklen_t datalen = sizeof(data_address);
|
||||
|
||||
data_address.sin_family = AF_INET;
|
||||
data_address.sin_addr.s_addr = INADDR_ANY;
|
||||
data_address.sin_port = 0;
|
||||
|
||||
if (bind(data_fd, (struct sockaddr *)&data_address, sizeof(data_address)) < 0) {
|
||||
perror("pasv bind() failed");
|
||||
close(data_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(data_fd, 3) < 0) {
|
||||
perror("pasv listen() failed");
|
||||
close(data_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getsockname(data_fd, (struct sockaddr *)&data_address, &datalen) == 0) {
|
||||
//memcpy(&netaddr[0], &data_address.sin_addr, 4);
|
||||
netaddr[0] = 127;
|
||||
netaddr[1] = netaddr[2] = 0;
|
||||
netaddr[3] = 1;
|
||||
dataport = ntohs(data_address.sin_port);
|
||||
memcpy(&netport[0], &dataport, 2);
|
||||
printf("[i] D(%i) PASV initialized: %u.%u.%u.%u:%u\n", data_fd, netaddr[0], netaddr[1], netaddr[2], netaddr[3], dataport);
|
||||
} else {
|
||||
perror("pasv getpeername() failed");
|
||||
close(data_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* pasvok;
|
||||
asprintf(
|
||||
&pasvok,
|
||||
"Entering Passive Mode (%u,%u,%u,%u,%u,%u)",
|
||||
netaddr[0],
|
||||
netaddr[1],
|
||||
netaddr[2],
|
||||
netaddr[3],
|
||||
netport[1],
|
||||
netport[0]
|
||||
);
|
||||
|
||||
submit(227, std::string(pasvok));
|
||||
free(pasvok);
|
||||
|
||||
if ((data_sock = accept(data_fd, NULL, NULL)) >= 0) {
|
||||
printf("[i] D(%i) PASV accepted: %i\n", data_fd, data_sock);
|
||||
state = 2;
|
||||
//submit(200, "OK");
|
||||
} else {
|
||||
perror("accept() failed");
|
||||
submit(425, "Unknown Error");
|
||||
data_close();
|
||||
}
|
||||
} else if (cmd == "PORT") {
|
||||
data_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
@@ -79,16 +150,15 @@ public:
|
||||
sscanf(argstr.c_str(), "%d,%d,%d,%d,%d,%d", &act_ip[0], &act_ip[1], &act_ip[2], &act_ip[3], (int*)&act_port[0], (int*)&act_port[1]);
|
||||
sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2], act_ip[3]);
|
||||
port_dec = act_port[0]*256+act_port[1];
|
||||
printf("[d] D(%i) Initialized data transport: %s:%d\n", control_sock, ip_decimal, port_dec);
|
||||
printf("[d] D(%i) PORT initialized: %s:%d\n", control_sock, ip_decimal, port_dec);
|
||||
|
||||
data_address.sin_family = AF_INET;
|
||||
data_address.sin_addr.s_addr = inet_addr(ip_decimal);
|
||||
data_address.sin_port = htons(port_dec);
|
||||
|
||||
if (connect(data_sock, (struct sockaddr *)&data_address, sizeof(data_address)) != 0) {
|
||||
close(data_sock);
|
||||
data_sock = 0;
|
||||
submit(425, "Unknown Error");
|
||||
data_close();
|
||||
} else {
|
||||
state = 2;
|
||||
submit(200, "OK");
|
||||
@@ -152,9 +222,7 @@ public:
|
||||
}
|
||||
submit(226, "OK");
|
||||
}
|
||||
if (data_close() != 0) {
|
||||
printf("[!] Data Sock returned %i instead of 0! Not closed!!!\n", data_sock);
|
||||
}
|
||||
data_close();
|
||||
} else {
|
||||
submit(502, "Command not implemented");
|
||||
}
|
||||
@@ -205,17 +273,22 @@ public:
|
||||
}
|
||||
|
||||
int data_close() {
|
||||
if (data_sock <= 0) return 0;
|
||||
printf("[d] D(%i) Closing...\n", data_sock);
|
||||
close(data_sock);
|
||||
data_sock = 0;
|
||||
data_sock = -1;
|
||||
close(data_fd);
|
||||
data_fd = -1;
|
||||
state = 1;
|
||||
return data_sock; // Should be 0 if successful.
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
Filer* filer = new Filer();
|
||||
const int opt = 1;
|
||||
|
||||
int data_fd;
|
||||
int data_sock;
|
||||
struct sockaddr_in data_address;
|
||||
};
|
||||
Reference in new issue
Block a user