Add proper logging
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
server_name=My FTP Server
|
||||
motd_file=motd
|
||||
auth_engine=noauth
|
||||
[logging]
|
||||
file=digftp.log
|
||||
level=0
|
||||
[net]
|
||||
listen_address=127.0.0.1
|
||||
control_port=21
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
sscanf(config->getValue("net", "listen_address", "127.0.0.1").c_str(), "%d.%d.%d.%d", &netaddr[0], &netaddr[1], &netaddr[2], &netaddr[3]);
|
||||
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);
|
||||
logger->print(LOGLEVEL_DEBUG, "D(%i) PASV initialized: %u.%u.%u.%u:%u", data_fd, netaddr[0], netaddr[1], netaddr[2], netaddr[3], dataport);
|
||||
} else {
|
||||
perror("pasv getpeername() failed");
|
||||
close(data_fd);
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
free(pasvok);
|
||||
|
||||
if ((data_sock = accept(data_fd, NULL, NULL)) >= 0) {
|
||||
printf("[i] D(%i) PASV accepted: %i\n", data_fd, data_sock);
|
||||
logger->print(LOGLEVEL_INFO, "D(%i) PASV accepted: %i", data_fd, data_sock);
|
||||
state = 2;
|
||||
} else {
|
||||
perror("accept() failed");
|
||||
@@ -135,7 +135,7 @@ 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) PORT initialized: %s:%d\n", control_sock, ip_decimal, port_dec);
|
||||
logger->print(LOGLEVEL_DEBUG, "D(%i) PORT initialized: %s:%d", control_sock, ip_decimal, port_dec);
|
||||
|
||||
data_address.sin_family = AF_INET;
|
||||
data_address.sin_addr.s_addr = inet_addr(ip_decimal);
|
||||
@@ -217,7 +217,7 @@ public:
|
||||
submit(331, "Password required");
|
||||
} else if (cmd == "PASS") {
|
||||
if (auth->check(name, argstr)) {
|
||||
printf("[d] (%i) logged in as '%s'\n", control_sock, name.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "(%i) logged in as '%s'", control_sock, name.c_str());
|
||||
// We can now set the root safely (I hope).
|
||||
filer->setRoot(auth->getUserDirectory(name));
|
||||
state = 1;
|
||||
@@ -240,26 +240,26 @@ public:
|
||||
std::string out = std::to_string(code)+" "+msg+"\r\n";
|
||||
int bytes = send(control_sock, out.c_str(), out.size(), 0);
|
||||
if (bytes < 0) {
|
||||
printf("[d] C(%i) !< %i %s\n", control_sock, code, msg.c_str());
|
||||
logger->print(LOGLEVEL_ERROR, "C(%i) !< %i %s", control_sock, code, msg.c_str());
|
||||
return 1;
|
||||
}
|
||||
printf("[d] C(%i) << %i %s\n", control_sock, code, msg.c_str());
|
||||
logger->print(LOGLEVEL_DEBUG, "C(%i) << %i %s", control_sock, code, msg.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int data_submit(char* out, int size) {
|
||||
int bytes = send(data_sock, out, size, 0);
|
||||
if (bytes < 0) {
|
||||
printf("[d] D(%i) !< %i\n", data_sock, size);
|
||||
logger->print(LOGLEVEL_DEBUG, "D(%i) !< %i", data_sock, size);
|
||||
return 1;
|
||||
}
|
||||
printf("[d] D(%i) << %i\n", data_sock, size);
|
||||
logger->print(LOGLEVEL_DEBUG, "D(%i) << %i", data_sock, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int data_close() {
|
||||
if (data_sock <= 0) return 0;
|
||||
printf("[d] D(%i) Closing...\n", data_sock);
|
||||
logger->print(LOGLEVEL_DEBUG, "D(%i) Closing...", data_sock);
|
||||
close(data_sock);
|
||||
data_sock = -1;
|
||||
close(data_fd);
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int traverse(std::string dir) {
|
||||
fs::path ndir = fs::weakly_canonical(cwd / dir);
|
||||
fs::path fdir = fullPath(dir);
|
||||
printf("[i] Traversing: %s\n", ndir.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Traversing: %s", ndir.c_str());
|
||||
if (fdir.string().rfind(root.string(), 0) != 0) return -2;
|
||||
else if (!fs::exists(fdir) || !fs::is_directory(fdir)) return -1;
|
||||
else {
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
int setRoot(std::string _root) {
|
||||
fs::path froot = fs::weakly_canonical(_root);
|
||||
printf("[i] Setting root: %s\n", froot.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Setting root: %s", froot.c_str());
|
||||
if (!fs::exists(froot)) fs::create_directory(froot);
|
||||
root = fs::absolute(froot);
|
||||
cwd = "/";
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
int fileSize(std::string name) {
|
||||
fs::path nfile = fs::weakly_canonical(cwd / name);
|
||||
fs::path ffile = fullPath(name);
|
||||
printf("[i] Retreiving filesize: %s\n", nfile.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Retreiving filesize: %s", nfile.c_str());
|
||||
if (ffile.string().rfind(root.string(), 0) != 0) return -2;
|
||||
else if (!fs::exists(ffile)) return -1;
|
||||
else if (type == 'A') return -3;
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
int deleteFile(std::string name) {
|
||||
fs::path nfile = fs::weakly_canonical(cwd / name);
|
||||
fs::path ffile = fullPath(name);
|
||||
printf("[i] Deleting file: %s\n", nfile.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Deleting file: %s", nfile.c_str());
|
||||
if (ffile.string().rfind(root.string(), 0) != 0) return -2;
|
||||
else if (!fs::exists(ffile)) return -1;
|
||||
else {
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
|
||||
fs::path nfile = fs::weakly_canonical(cwd / name);
|
||||
fs::path ffile = fullPath(name);
|
||||
printf("[i] Retreiving file: %s\n", nfile.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Retreiving file: %s", nfile.c_str());
|
||||
if (ffile.string().rfind(root.string(), 0) != 0) fd.ecode = -2;
|
||||
else if (!fs::exists(ffile)) fd.ecode = -1;
|
||||
else if (type != 'A') {
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
int writeFile(std::string name, unsigned char* data, int size) {
|
||||
fs::path nfile = fs::weakly_canonical(cwd / name);
|
||||
fs::path ffile = fullPath(name);
|
||||
printf("[i] Storing file: %s\n", nfile.c_str());
|
||||
logger->print(LOGLEVEL_INFO, "Storing file: %s", nfile.c_str());
|
||||
if (ffile.string().rfind(root.string(), 0) != 0) return -2;
|
||||
else {
|
||||
std::ofstream outfile(ffile, std::ios::out|std::ios::binary);
|
||||
|
||||
51
src/logger.h
Normal file
51
src/logger.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#include <fstream>
|
||||
|
||||
#define LOGLEVEL_ERROR 3
|
||||
#define LOGLEVEL_WARNING 2
|
||||
#define LOGLEVEL_INFO 1
|
||||
#define LOGLEVEL_DEBUG 0
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
Logger(const char* path) {
|
||||
logfile.open(path, std::ios::binary|std::ios::app);
|
||||
};
|
||||
|
||||
void setLevel(int level) { this->logLevel = level; }
|
||||
|
||||
template<class... Args>
|
||||
void print(int level, const char* message, Args... args) {
|
||||
if (level >= this->logLevel) {
|
||||
char* prepared;
|
||||
char* formatted;
|
||||
asprintf(&prepared, "[%c] %s\n", logTypeChar(level), message);
|
||||
asprintf(&formatted, prepared, args...);
|
||||
fprintf(stdout, formatted);
|
||||
if (logfile.is_open()) {
|
||||
logfile.write(formatted, strlen(formatted));
|
||||
logfile.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void close() {
|
||||
logfile.close();
|
||||
}
|
||||
private:
|
||||
std::ofstream logfile;
|
||||
int logLevel = 0;
|
||||
|
||||
static const char logTypeChar(int level) {
|
||||
switch(level) {
|
||||
default: return ' ';
|
||||
case LOGLEVEL_ERROR: return 'E';
|
||||
case LOGLEVEL_WARNING: return 'W';
|
||||
case LOGLEVEL_INFO: return 'I';
|
||||
case LOGLEVEL_DEBUG: return 'D';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
32
src/main.cpp
32
src/main.cpp
@@ -22,8 +22,8 @@
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
const int max_clients = config->getInt("net", "max_clients", 255);
|
||||
const int cport = config->getInt("net", "control_port", 21);
|
||||
const uint16_t max_clients = config->getInt("net", "max_clients", 255);
|
||||
const uint16_t cport = config->getInt("net", "control_port", 21);
|
||||
|
||||
struct pollfd fds[65535];
|
||||
struct clientfd {
|
||||
@@ -41,10 +41,9 @@ void runClient(struct clientfd* cfd) {
|
||||
//while (fcntl(cfd->client->control_sock, F_GETFD) != -1) {
|
||||
while (true) {
|
||||
if (cfd->client == nullptr) { break; }
|
||||
printf("[d] C(%i) Attempting read...\n", cfd->client->control_sock);
|
||||
int rc = recv(cfd->client->control_sock, inbuf, sizeof(inbuf), 0);
|
||||
if (rc < 0) {
|
||||
printf("[d] C(%i) Recieved empty packet\n", cfd->client->control_sock);
|
||||
logger->print(LOGLEVEL_WARNING, "C(%i) Recieved empty packet", cfd->client->control_sock);
|
||||
if (errno != EWOULDBLOCK) {
|
||||
perror("recv() failed");
|
||||
break;
|
||||
@@ -65,19 +64,20 @@ void runClient(struct clientfd* cfd) {
|
||||
std::string args = "";
|
||||
if (len > cmdend) args = lin.substr(cmdend+1, len-cmdend-1);
|
||||
|
||||
printf("[d] C(%i) >> '%s' '%s'\n", cfd->client->control_sock, cmd.c_str(), args.c_str());
|
||||
logger->print(LOGLEVEL_DEBUG, "C(%i) >> '%s' '%s'", cfd->client->control_sock, cmd.c_str(), args.c_str());
|
||||
|
||||
if (cfd->client->receive(cmd, args) < 0) break;
|
||||
inbuf[0] = '\0';
|
||||
}
|
||||
} catch (...) {
|
||||
printf("[!] C(%i) Caught error!\n", cfd->client->control_sock);
|
||||
logger->print(LOGLEVEL_ERROR, "C(%i) Caught error!", cfd->client->control_sock);
|
||||
}
|
||||
//printf("[d] C(%i) Marking for deletion...\n", cfd->client->control_sock);
|
||||
cfd->close = true;
|
||||
}
|
||||
|
||||
int main(int argc , char *argv[]) {
|
||||
logger = new Logger(config->getValue("logging", "file", "digftp.log").c_str());
|
||||
logger->setLevel(config->getInt("logging", "level", 0));
|
||||
std::string authType = config->getValue("main", "auth_engine", "plain");
|
||||
auth = getAuthByName(authType);
|
||||
auth->setOptions(config->get(authType));
|
||||
@@ -129,7 +129,7 @@ int main(int argc , char *argv[]) {
|
||||
fds[0].fd = master_socket;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
printf("[i] Server started.\n");
|
||||
logger->print(LOGLEVEL_INFO, "Server started.");
|
||||
while (run) {
|
||||
int pc = poll(fds, nfds, -1);
|
||||
|
||||
@@ -139,7 +139,7 @@ int main(int argc , char *argv[]) {
|
||||
}
|
||||
|
||||
if (pc == 0) {
|
||||
printf("poll() timed out\n");
|
||||
perror("poll() timed out\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ int main(int argc , char *argv[]) {
|
||||
continue;
|
||||
|
||||
if(fds[i].revents != POLLIN) {
|
||||
printf("[!] C(%i) Error! revents = %d\n", fds[i].fd, fds[i].revents);
|
||||
logger->print(LOGLEVEL_ERROR, "C(%i) Error! revents = %d", fds[i].fd, fds[i].revents);
|
||||
goto conn_close;
|
||||
}
|
||||
if (fds[i].fd == master_socket) {
|
||||
@@ -162,8 +162,7 @@ int main(int argc , char *argv[]) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
printf("[d] C(%i) Accepted client\n", newsock);
|
||||
logger->print(LOGLEVEL_DEBUG, "C(%i) Accepted client", newsock);
|
||||
fds[nfds].fd = newsock;
|
||||
fds[nfds].events = POLLIN;
|
||||
fdc[nfds].close = false;
|
||||
@@ -174,7 +173,7 @@ int main(int argc , char *argv[]) {
|
||||
} else {
|
||||
if (fdc[i].close) {
|
||||
conn_close:
|
||||
printf("[d] C(%i) Deleting client...\n", fds[i].fd);
|
||||
logger->print(LOGLEVEL_DEBUG, "C(%i) Deleting client...", fds[i].fd);
|
||||
close(fds[i].fd);
|
||||
fds[i].fd = -1;
|
||||
if (fdc[i].client->thread.joinable())
|
||||
@@ -193,15 +192,15 @@ int main(int argc , char *argv[]) {
|
||||
if (fds[i].fd == -1) {
|
||||
for(int j = i; j < nfds; j++) {
|
||||
if (fds[j].fd == -1) {
|
||||
printf("[d] Compressing: %i(fd:%i) <= %i(fd:%i)\n", j, fds[j].fd, j+1, fds[j+1].fd);
|
||||
logger->print(LOGLEVEL_DEBUG, "Compressing: %i(fd:%i) <= %i(fd:%i)", j, fds[j].fd, j+1, fds[j+1].fd);
|
||||
fds[j].fd = fds[j+1].fd;
|
||||
fds[j].revents = fds[j+1].revents;
|
||||
fds[j+1].fd = -1;
|
||||
printf("[d] Reinitialized fds of %i\n", j+1);
|
||||
logger->print(LOGLEVEL_DEBUG, "Reinitialized fds of %i", j+1);
|
||||
fdc[j].client = fdc[j+1].client;
|
||||
fdc[j].close = fdc[j+1].close;
|
||||
fdc[j+1] = {};
|
||||
printf("[d] Reinitialized fdc of %i\n", j+1);
|
||||
logger->print(LOGLEVEL_DEBUG, "[d] Reinitialized fdc of %i", j+1);
|
||||
}
|
||||
}
|
||||
i--;
|
||||
@@ -210,5 +209,6 @@ int main(int argc , char *argv[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
logger->close();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#define CONF_DIR "conf"
|
||||
#define LOG_DIR "log"
|
||||
|
||||
#include "conf.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include "auth.h"
|
||||
#include "auth/noauth.h"
|
||||
|
||||
ConfigFile* config = new ConfigFile("conf/ftp.conf");
|
||||
Auth* auth;
|
||||
Logger* logger;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user