Add proper logging

This commit is contained in:
2024-10-17 20:02:54 -05:00
parent 66897bca0c
commit d2e062d03d
6 changed files with 92 additions and 31 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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
View 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

View File

@@ -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;
}

View File

@@ -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