diff --git a/include/columnlynx/common/utils.hpp b/include/columnlynx/common/utils.hpp index 7fd6467..39a5ee5 100644 --- a/include/columnlynx/common/utils.hpp +++ b/include/columnlynx/common/utils.hpp @@ -29,6 +29,9 @@ namespace ColumnLynx { } namespace ColumnLynx::Utils { + // Converts unix milliseconds to a local ISO 8601 formatted string; Defaults to local time; Will use UTC if local is false. + std::string unixMillisToISO8601(uint64_t unixMillis, bool local = true); + // General log function. Use for logging important information. void log(const std::string &msg); // General warning function. Use for logging important warnings. diff --git a/src/client/main.cpp b/src/client/main.cpp index 5146872..01a7ab8 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -110,6 +110,10 @@ int main(int argc, char** argv) { aesKey->fill(0); // Defualt zeroed state until modified by handshake std::shared_ptr sessionID = std::make_shared(0); + if (insecureMode) { + warn("You have started the client with the --ignore-whitelist. This means that the client will NOT attempt to verify the server's public key. This is INSECURE and SHOULDN'T be used!"); + } + asio::io_context io; auto client = std::make_shared(io, host, port, sodiumWrapper, aesKey, sessionID, insecureMode, configPath, tun); auto udpClient = std::make_shared(io, host, port, aesKey, sessionID, tun); diff --git a/src/common/utils.cpp b/src/common/utils.cpp index fbe2dcf..a4e5ce6 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -5,25 +5,61 @@ #include namespace ColumnLynx::Utils { + std::string unixMillisToISO8601(uint64_t unixMillis, bool local) { + using namespace std::chrono; + + // Convert milliseconds since epoch to system_clock::time_point + system_clock::time_point tp = system_clock::time_point(milliseconds(unixMillis)); + + // Convert to time_t for localtime conversion + std::time_t tt = system_clock::to_time_t(tp); + std::tm localTm; + + if (local) { +#ifdef _WIN32 + localtime_s(&localTm, &tt); +#else + localtime_r(&tt, &localTm); +#endif + } else { +#ifdef _WIN32 + gmtime_s(&localTm, &tt); +#else + gmtime_r(&tt, &localTm); +#endif + } + + // Format the time to ISO 8601 + char buffer[30]; + std::strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", &localTm); + + // Append milliseconds + auto ms = duration_cast(tp.time_since_epoch()) % 1000; + char iso8601[34]; + std::snprintf(iso8601, sizeof(iso8601), "%s.%03lld", buffer, static_cast(ms.count())); + + return std::string(iso8601); + } + void log(const std::string &msg) { uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::cout << "\033[0m[" << std::to_string(now) << " LOG] " << msg << std::endl; + std::cout << "\033[0m[" << unixMillisToISO8601(now) << " LOG] " << msg << std::endl; } void warn(const std::string &msg) { uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::cerr << "\033[33m[" << std::to_string(now) << " WARN] " << msg << "\033[0m" << std::endl; + std::cerr << "\033[33m[" << unixMillisToISO8601(now) << " WARN] " << msg << "\033[0m" << std::endl; } void error(const std::string &msg) { uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::cerr << "\033[31m[" << std::to_string(now) << " ERROR] " << msg << "\033[0m" << std::endl; + std::cerr << "\033[31m[" << unixMillisToISO8601(now) << " ERROR] " << msg << "\033[0m" << std::endl; } void debug(const std::string &msg) { #if DEBUG || _DEBUG uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - std::cerr << "\033[95m[" << std::to_string(now) << " DEBUG] " << msg << "\033[0m" << std::endl; + std::cerr << "\033[95m[" << unixMillisToISO8601(now) << " DEBUG] " << msg << "\033[0m" << std::endl; #else return; #endif