From b1ec5d0e0913e761084332bdde2945155ed24624 Mon Sep 17 00:00:00 2001 From: Daniel Roethlisberger Date: Sun, 16 Nov 2014 22:31:54 +0100 Subject: [PATCH] Improve log_content_open() error handling --- log.c | 51 ++++++++++++++++++++++++++++++++++++++------------- log.h | 4 ++-- pxyconn.c | 19 ++++++++++++------- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/log.c b/log.c index 416e332..88c9e88 100644 --- a/log.c +++ b/log.c @@ -388,18 +388,25 @@ log_content_format_pathspec(const char *logspec, char *srcaddr, char *dstaddr, } #undef PATH_BUF_INC -void +int log_content_open(log_content_ctx_t *ctx, char *srcaddr, char *dstaddr, char *exec_path, char *user, char *group) { if (ctx->open) - return; + return 0; if (content_fd != -1) { /* single-file content log (-L) */ ctx->fd = content_fd; - asprintf(&ctx->header_in, "%s -> %s", srcaddr, dstaddr); - asprintf(&ctx->header_out, "%s -> %s", dstaddr, srcaddr); + if (asprintf(&ctx->header_in, "%s -> %s", + srcaddr, dstaddr) == -1) { + return -1; + } + if (asprintf(&ctx->header_out, "%s -> %s", + dstaddr, srcaddr) == -1) { + free(ctx->header_in); + return -1; + } } else if (content_logspec) { /* per-connection-file content log with logspec (-F) */ char *filename, *filedir; @@ -408,8 +415,7 @@ log_content_open(log_content_ctx_t *ctx, char *srcaddr, char *dstaddr, srcaddr, dstaddr, exec_path, user, group); if (!filename) { - ctx->fd = -1; - return; + return -1; } filedir = dirname(filename); @@ -417,14 +423,15 @@ log_content_open(log_content_ctx_t *ctx, char *srcaddr, char *dstaddr, log_err_printf("Could not create directory '%s': %s\n", filedir, strerror(errno)); free(filename); - ctx->fd = -1; - return; + return -1; } ctx->fd = open(filename, O_WRONLY|O_APPEND|O_CREAT, 0660); if (ctx->fd == -1) { log_err_printf("Failed to open '%s': %s\n", filename, strerror(errno)); + free(filename); + return -1; } free(filename); } else { @@ -434,18 +441,36 @@ log_content_open(log_content_ctx_t *ctx, char *srcaddr, char *dstaddr, time_t epoch; struct tm *utc; - time(&epoch); - utc = gmtime(&epoch); - strftime(timebuf, sizeof(timebuf), "%Y%m%dT%H%M%SZ", utc); - snprintf(filename, sizeof(filename), "%s/%s-%s-%s.log", - content_basedir, timebuf, srcaddr, dstaddr); + if (time(&epoch) == -1) { + log_err_printf("Failed to get time\n"); + return -1; + } + if ((utc = gmtime(&epoch)) == NULL) { + log_err_printf("Failed to convert time: %s\n", + strerror(errno)); + return -1; + } + if (!strftime(timebuf, sizeof(timebuf), + "%Y%m%dT%H%M%SZ", utc)) { + log_err_printf("Failed to format time: %s\n", + strerror(errno)); + return -1; + } + if (snprintf(filename, sizeof(filename), "%s/%s-%s-%s.log", + content_basedir, timebuf, srcaddr, dstaddr) < 0) { + log_err_printf("Failed to format filename: %s\n", + strerror(errno)); + return -1; + } ctx->fd = open(filename, O_WRONLY|O_APPEND|O_CREAT, 0660); if (ctx->fd == -1) { log_err_printf("Failed to open '%s': %s\n", filename, strerror(errno)); + return -1; } } ctx->open = 1; + return 0; } void diff --git a/log.h b/log.h index 0579cf3..ac7ae40 100644 --- a/log.h +++ b/log.h @@ -64,8 +64,8 @@ typedef struct log_content_ctx { char *header_in; char *header_out; } log_content_ctx_t; -void log_content_open(log_content_ctx_t *, char *, char *, - char *, char *, char *) NONNULL(1,2,3); +int log_content_open(log_content_ctx_t *, char *, char *, + char *, char *, char *) NONNULL(1,2,3) WUNRES; void log_content_submit(log_content_ctx_t *, logbuf_t *, int) NONNULL(1,2); void log_content_close(log_content_ctx_t *) NONNULL(1); diff --git a/pxyconn.c b/pxyconn.c index f181bd5..c68ef9d 100644 --- a/pxyconn.c +++ b/pxyconn.c @@ -1706,16 +1706,21 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) #endif /* HAVE_LOCAL_PROCINFO */ } if (WANT_CONTENT_LOG(ctx)) { - log_content_open(&ctx->logctx, ctx->src_str, - ctx->dst_str, + if (log_content_open(&ctx->logctx, ctx->src_str, + ctx->dst_str, #ifdef HAVE_LOCAL_PROCINFO - ctx->lproc.exec_path, - ctx->lproc.user, - ctx->lproc.group + ctx->lproc.exec_path, + ctx->lproc.user, + ctx->lproc.group #else /* HAVE_LOCAL_PROCINFO */ - NULL, NULL, NULL + NULL, NULL, NULL #endif /* HAVE_LOCAL_PROCINFO */ - ); + ) == -1) { + if (errno == ENOMEM) + ctx->enomem = 1; + pxy_conn_terminate_free(ctx); + return; + } } /* log connection if we don't analyze any headers */