-#include "log.h"
-
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <stdarg.h>
#include <syslog.h>
-#include <assert.h>
-#include <errno.h>
+#include <time.h>
+#include <unistd.h>
#include <string>
#include <vector>
+#include "tlse.h"
+
+#include "log.h"
+
using namespace std;
// Yes, it's a bit ugly.
-#define SYSLOG_FAKE_FILE (static_cast<FILE *>(NULL))
+#define SYSLOG_FAKE_FILE (static_cast<FILE *>(nullptr))
bool logging_started = false;
-std::vector<FILE *> log_destinations;
+vector<FILE *> log_destinations;
-void add_log_destination_file(const std::string &filename)
+void add_log_destination_file(const string &filename)
{
- FILE *fp = fopen(filename.c_str(), "a");
- if (fp == NULL) {
+ FILE *fp = fopen(filename.c_str(), "ae");
+ if (fp == nullptr) {
perror(filename.c_str());
return;
}
vsnprintf(formatted_msg, sizeof(formatted_msg), fmt, ap);
va_end(ap);
+ time_t now = time(nullptr);
+ struct tm lt;
+ struct tm *ltime = localtime_r(&now, <);
+ char timestamp[1024];
+ if (ltime == nullptr) {
+ strcpy(timestamp, "???");
+ } else {
+ strftime(timestamp, sizeof(timestamp), "%a, %d %b %Y %T %z", ltime);
+ }
+
const char *log_level_str;
int syslog_level;
switch (log_level) {
- case NO_LEVEL:
- log_level_str = "";
- syslog_level = LOG_INFO;
- break;
case INFO:
- log_level_str = "INFO: ";
+ log_level_str = "INFO: ";
syslog_level = LOG_INFO;
break;
case WARNING:
syslog_level = LOG_WARNING;
break;
case ERROR:
- log_level_str = "ERROR: ";
+ log_level_str = "ERROR: ";
syslog_level = LOG_ERR;
break;
default:
// Log to stderr if logging hasn't been set up yet. Note that this means
// that such messages will come even if there are no “error_log” lines.
if (!logging_started) {
- fprintf(stderr, "%s%s\n", log_level_str, formatted_msg);
+ fprintf(stderr, "[%s] %s%s\n", timestamp, log_level_str, formatted_msg);
return;
}
if (log_destinations[i] == SYSLOG_FAKE_FILE) {
syslog(syslog_level, "%s", formatted_msg);
} else {
- int err = fprintf(log_destinations[i], "%s%s\n", log_level_str, formatted_msg);
+ int err = fprintf(log_destinations[i], "[%s] %s%s\n", timestamp, log_level_str, formatted_msg);
if (err < 0) {
perror("fprintf");
}
void log_perror(const char *msg)
{
char errbuf[4096];
- strerror_r(errno, errbuf, sizeof(errbuf));
- log(ERROR, "%s: %s", msg, errbuf);
+ log(ERROR, "%s: %s", msg, strerror_r(errno, errbuf, sizeof(errbuf)));
+}
+
+void log_tls_error(const char *msg, int tls_err)
+{
+ switch (tls_err) {
+ case TLS_NEED_MORE_DATA:
+ log(ERROR, "%s: Need more data (TLS)", msg);
+ break;
+ case TLS_GENERIC_ERROR:
+ log(ERROR, "%s: Generic TLS error", msg);
+ break;
+ case TLS_BROKEN_PACKET:
+ log(ERROR, "%s: Broken TLS packet", msg);
+ break;
+ case TLS_NOT_UNDERSTOOD:
+ log(ERROR, "%s: Not understood (TLS)", msg);
+ break;
+ case TLS_NOT_SAFE:
+ log(ERROR, "%s: Not safe (TLS)", msg);
+ break;
+ case TLS_NO_COMMON_CIPHER:
+ log(ERROR, "%s: No common TLS cipher", msg);
+ break;
+ case TLS_UNEXPECTED_MESSAGE:
+ log(ERROR, "%s: Unexpected TLS message", msg);
+ break;
+ case TLS_CLOSE_CONNECTION:
+ log(ERROR, "%s: Close TLS connection", msg);
+ break;
+ case TLS_COMPRESSION_NOT_SUPPORTED:
+ log(ERROR, "%s: TLS compression not supported", msg);
+ break;
+ case TLS_NO_MEMORY:
+ log(ERROR, "%s: No TLS memory", msg);
+ break;
+ case TLS_NOT_VERIFIED:
+ log(ERROR, "%s: Not verified (TLS)", msg);
+ break;
+ case TLS_INTEGRITY_FAILED:
+ log(ERROR, "%s: TLS integrity failed", msg);
+ break;
+ case TLS_ERROR_ALERT:
+ log(ERROR, "%s: TLS alert", msg);
+ break;
+ case TLS_BROKEN_CONNECTION:
+ log(ERROR, "%s: Broken TLS connection", msg);
+ break;
+ case TLS_BAD_CERTIFICATE:
+ log(ERROR, "%s: Bad TLS certificate", msg);
+ break;
+ case TLS_UNSUPPORTED_CERTIFICATE:
+ log(ERROR, "%s: Unsupported TLS certificate", msg);
+ break;
+ case TLS_NO_RENEGOTIATION:
+ log(ERROR, "%s: No TLS renegotiation", msg);
+ break;
+ case TLS_FEATURE_NOT_SUPPORTED:
+ log(ERROR, "%s: TLS feature not supported", msg);
+ break;
+ default:
+ log(ERROR, "%s: Unknown TLS error %d", msg, tls_err);
+ break;
+ }
}