Add Upload support
This commit is contained in:
parent
c3c682cad1
commit
5a932dd17c
@ -128,6 +128,10 @@ static int handler(void* user, const char* section, const char* name, const char
|
|||||||
if (cfg->fileroot[strlen(cfg->fileroot) -1] == '/') {
|
if (cfg->fileroot[strlen(cfg->fileroot) -1] == '/') {
|
||||||
cfg->fileroot[strlen(cfg->fileroot) -1] = '\0';
|
cfg->fileroot[strlen(cfg->fileroot) -1] = '\0';
|
||||||
}
|
}
|
||||||
|
} else if (strcasecmp(name, "upload folder") == 0) {
|
||||||
|
cfg->upload_folder = strdup(value);
|
||||||
|
} else if (strcasecmp(name, "upload sec level") == 0) {
|
||||||
|
cfg->upload_seclevel = atoi(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -221,6 +225,80 @@ int open_tcp_connection(struct ftpserver *cfg, struct ftpclient *client) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_STOR(struct ftpserver *cfg, struct ftpclient *client, char *path) {
|
||||||
|
char newpath[PATH_MAX];
|
||||||
|
struct stat s;
|
||||||
|
pid_t pid;
|
||||||
|
char buffer[1024];
|
||||||
|
int j;
|
||||||
|
int i;
|
||||||
|
FILE *fptr;
|
||||||
|
if (path[0] == '/') {
|
||||||
|
snprintf(newpath, PATH_MAX, "%s", path);
|
||||||
|
} else {
|
||||||
|
snprintf(newpath, PATH_MAX, "%s/%s", client->current_path, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=strlen(newpath);i > 0; i--) {
|
||||||
|
if (newpath[i] == '/') {
|
||||||
|
newpath[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(&newpath[1], cfg->upload_folder) == 0) {
|
||||||
|
if (path[0] == '/') {
|
||||||
|
snprintf(newpath, PATH_MAX, "%s%s", cfg->fileroot, path);
|
||||||
|
} else {
|
||||||
|
snprintf(newpath, PATH_MAX, "%s%s/%s",cfg->fileroot, client->current_path, path);
|
||||||
|
}
|
||||||
|
if (client->seclevel >= cfg->upload_seclevel) {
|
||||||
|
|
||||||
|
if (stat(newpath, &s) != 0) {
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
fptr = fopen(newpath, "wb");
|
||||||
|
if (fptr) {
|
||||||
|
if (open_tcp_connection(cfg, client)) {
|
||||||
|
send_msg(client, "150 Data connection accepted; transfer starting.\r\n");
|
||||||
|
while (1) {
|
||||||
|
j = recv(client->data_socket, buffer, 1024, 0);
|
||||||
|
if (j == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j < 0) {
|
||||||
|
send_msg(client, "426 TCP connection was established but then broken\r\n");
|
||||||
|
fclose(fptr);
|
||||||
|
unlink(newpath);
|
||||||
|
close_tcp_connection(client);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
fwrite(buffer, 1, j, fptr);
|
||||||
|
}
|
||||||
|
fclose(fptr);
|
||||||
|
close_tcp_connection(client);
|
||||||
|
send_msg(client, "226 Transfer OK.\r\n");
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
send_msg(client, "425 TCP connection cannot be established.\r\n");
|
||||||
|
fclose(fptr);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pid < 0) {
|
||||||
|
send_msg(client, "451 STOR Failed.\r\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
send_msg(client, "553 File Exists.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
send_msg(client, "532 Access Denied.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
send_msg(client, "532 Access Denied.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle_PASV(struct ftpserver *cfg, struct ftpclient *client) {
|
void handle_PASV(struct ftpserver *cfg, struct ftpclient *client) {
|
||||||
char buffer[200];
|
char buffer[200];
|
||||||
char *ipcpy;
|
char *ipcpy;
|
||||||
@ -436,7 +514,7 @@ void handle_PASS(struct ftpserver *cfg, struct ftpclient *client, char *password
|
|||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
sqlite3_stmt *res;
|
sqlite3_stmt *res;
|
||||||
int rc;
|
int rc;
|
||||||
char *sql = "SELECT password, salt FROM users WHERE loginname = ?";
|
char *sql = "SELECT password, salt, sec_level FROM users WHERE loginname = ?";
|
||||||
char *pass_hash;
|
char *pass_hash;
|
||||||
|
|
||||||
if (strlen(client->name) == 0) {
|
if (strlen(client->name) == 0) {
|
||||||
@ -469,6 +547,7 @@ void handle_PASS(struct ftpserver *cfg, struct ftpclient *client, char *password
|
|||||||
if (step == SQLITE_ROW) {
|
if (step == SQLITE_ROW) {
|
||||||
pass_hash = hash_sha256(password, (char *)sqlite3_column_text(res, 1));
|
pass_hash = hash_sha256(password, (char *)sqlite3_column_text(res, 1));
|
||||||
if (strcmp(pass_hash, (char *)sqlite3_column_text(res, 0)) == 0) {
|
if (strcmp(pass_hash, (char *)sqlite3_column_text(res, 0)) == 0) {
|
||||||
|
client->seclevel = sqlite3_column_int(res, 2);
|
||||||
send_msg(client, "230 User Logged in, Proceed.\r\n");
|
send_msg(client, "230 User Logged in, Proceed.\r\n");
|
||||||
strncpy(client->password, password, 32);
|
strncpy(client->password, password, 32);
|
||||||
} else {
|
} else {
|
||||||
@ -566,6 +645,9 @@ int handle_client(struct ftpserver *cfg, struct ftpclient *client, char *buf, in
|
|||||||
} else
|
} else
|
||||||
if (strcmp(cmd, "RETR") == 0) {
|
if (strcmp(cmd, "RETR") == 0) {
|
||||||
handle_RETR(cfg, client, argument);
|
handle_RETR(cfg, client, argument);
|
||||||
|
} else
|
||||||
|
if (strcmp(cmd, "STOR") == 0) {
|
||||||
|
handle_STOR(cfg, client, argument);
|
||||||
} else {
|
} else {
|
||||||
send_msg(client, "500 Command not recognized.\r\n");
|
send_msg(client, "500 Command not recognized.\r\n");
|
||||||
}
|
}
|
||||||
@ -654,6 +736,7 @@ void init(struct ftpserver *cfg) {
|
|||||||
clients[client_count]->type = 1;
|
clients[client_count]->type = 1;
|
||||||
clients[client_count]->status = 0;
|
clients[client_count]->status = 0;
|
||||||
clients[client_count]->data_port = 0;
|
clients[client_count]->data_port = 0;
|
||||||
|
clients[client_count]->seclevel = 0;
|
||||||
memset(clients[client_count]->name, 0, 16);
|
memset(clients[client_count]->name, 0, 16);
|
||||||
memset(clients[client_count]->password, 0, 32);
|
memset(clients[client_count]->password, 0, 32);
|
||||||
|
|
||||||
|
@ -13,12 +13,15 @@ struct ftpclient {
|
|||||||
char password[32];
|
char password[32];
|
||||||
int data_srv_socket;
|
int data_srv_socket;
|
||||||
int status;
|
int status;
|
||||||
|
int seclevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ftpserver {
|
struct ftpserver {
|
||||||
int port;
|
int port;
|
||||||
char *fileroot;
|
char *fileroot;
|
||||||
char *userdb;
|
char *userdb;
|
||||||
|
char *upload_folder;
|
||||||
|
int upload_seclevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
[Main]
|
[Main]
|
||||||
|
; Port to listen on
|
||||||
Port = 2121
|
Port = 2121
|
||||||
|
; Path and Filename of Magicka Users DB
|
||||||
Users DB = /home/andrew/MagickaBBS/users.sq3
|
Users DB = /home/andrew/MagickaBBS/users.sq3
|
||||||
|
; Root of files to serve
|
||||||
File Root = /home/andrew/MagickaBBS/ftproot/
|
File Root = /home/andrew/MagickaBBS/ftproot/
|
||||||
|
; Upload Folder is relative to file root. Make sure it exists
|
||||||
|
; Or remove this line to disable uploads.
|
||||||
|
Upload Folder = incoming
|
||||||
|
; Minimum Security Level to Upload - 0 to allow anonymous uploads
|
||||||
|
Upload Sec Level = 10
|
||||||
|
Reference in New Issue
Block a user