diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-05-18 23:38:46 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-05-18 23:38:46 +0200 |
commit | f48123bfaa46f5c93fe4b56423c6b52153e5c9b1 (patch) | |
tree | 4e3683e92251d4f3d8fc8cc3fde473a017e20436 | |
parent | ac5acb542df4b9e449dc2413388890ca1e30984e (diff) |
POTD skeleton #61.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | src/jail.c | 56 | ||||
-rw-r--r-- | src/log.h | 3 | ||||
-rw-r--r-- | src/log_colored.c | 7 | ||||
-rw-r--r-- | src/log_colored.h | 1 | ||||
-rw-r--r-- | src/pevent.c | 14 | ||||
-rw-r--r-- | src/pevent.h | 5 | ||||
-rw-r--r-- | src/redirector.c | 2 | ||||
-rw-r--r-- | src/utils.c | 51 | ||||
-rw-r--r-- | src/utils.h | 7 |
9 files changed, 136 insertions, 10 deletions
@@ -26,8 +26,12 @@ typedef struct server_event { } server_event; typedef struct client_event { - const psocket *client_sock; - const int tty_fd; + psocket *client_sock; + int tty_fd; + char tty_logbuf[BUFSIZ]; + size_t off_logbuf; + char *tty_logbuf_escaped; + size_t tty_logbuf_size; } client_event; static int jail_mainloop(event_ctx **ev_ctx, const jail_ctx *ctx[], size_t siz) @@ -37,6 +41,8 @@ static int jail_childfn(prisoner_process *ctx) __attribute__((noreturn)); static int jail_socket_tty(prisoner_process *ctx, int tty_fd); static int jail_socket_tty_io(event_ctx *ev_ctx, int src_fd, void *user_data); +static int jail_log_input(event_ctx *ev_ctx, int src_fd, int dst_fd, + char *buf, size_t siz, void *user_data); void jail_init_ctx(jail_ctx **ctx, size_t stacksize) @@ -251,6 +257,7 @@ static int jail_childfn(prisoner_process *ctx) FATAL("Clearing ENV for pid %d", self_pid); caps_drop_dac_override(0); + caps_drop_all(); D2("Unshare prisoner %d", self_pid); if (unshare(unshare_flags)) @@ -321,6 +328,7 @@ static int jail_childfn(prisoner_process *ctx) */ if (close_fds_except(0, 1, 2, -1)) exit(EXIT_FAILURE); + printf("%s", " _______ ________ __\n" " | |.-----.-----.-----.| | | |.----.| |_\n" @@ -339,6 +347,7 @@ static int jail_childfn(prisoner_process *ctx) " * 1 splash Cranberry juice\n" " -----------------------------------------------------\n" ); + if (execl(path_shell, path_shell, (char *) NULL)) exit(EXIT_FAILURE); default: @@ -359,11 +368,12 @@ static int jail_childfn(prisoner_process *ctx) static int jail_socket_tty(prisoner_process *ctx, int tty_fd) { - client_event ev_cli = {NULL, tty_fd}; + static client_event ev_cli = {NULL, 0, {0}, 0, 0, 0}; int s, rc = 1; event_ctx *ev_ctx = NULL; assert(ctx); + ev_cli.tty_fd = tty_fd; event_init(&ev_ctx); if (event_setup(ev_ctx)) { @@ -412,7 +422,8 @@ jail_socket_tty_io(event_ctx *ev_ctx, int src_fd, void *user_data) dest_fd = ev_cli->client_sock->fd; } else return 0; - fwd_state = event_forward_connection(ev_ctx, dest_fd); + fwd_state = event_forward_connection(ev_ctx, dest_fd, jail_log_input, + user_data); switch (fwd_state) { case CON_IN_TERMINATED: @@ -428,3 +439,40 @@ jail_socket_tty_io(event_ctx *ev_ctx, int src_fd, void *user_data) return 1; } + +static int jail_log_input(event_ctx *ev_ctx, int src_fd, int dst_fd, + char *buf, size_t siz, void *user_data) +{ + size_t idx = 0, slen, ssiz = siz; + client_event *ev_cli = (client_event *) user_data; + + (void) ev_ctx; + (void) src_fd; + + if (ev_cli->tty_fd == dst_fd) { + while (ssiz > 0) { + slen = MIN(sizeof(ev_cli->tty_logbuf) - ev_cli->off_logbuf, ssiz); + if (slen == 0) { + escape_ascii_string(ev_cli->tty_logbuf, ev_cli->off_logbuf, + &ev_cli->tty_logbuf_escaped, &ev_cli->tty_logbuf_size); + C("%s", ev_cli->tty_logbuf_escaped); + ev_cli->off_logbuf = 0; + ev_cli->tty_logbuf[0] = 0; + continue; + } + strncat(ev_cli->tty_logbuf, buf+idx, slen); + ssiz -= slen; + idx += slen; + ev_cli->off_logbuf += slen; + } + if (buf[siz-1] == '\r' || buf[siz-1] == '\n') { + escape_ascii_string(ev_cli->tty_logbuf, ev_cli->off_logbuf, + &ev_cli->tty_logbuf_escaped, &ev_cli->tty_logbuf_size); + C("%s", ev_cli->tty_logbuf_escaped); + ev_cli->off_logbuf = 0; + ev_cli->tty_logbuf[0] = 0; + } + } + + return 0; +} @@ -38,9 +38,10 @@ { int rv = expr; \ if (rv) { E2("`%s` returned: %d", #expr, rv); \ E_GAIERR(rv, msg); abort(); } } +#define C(fmt, ...) log_fmt(CMD, fmt, __VA_ARGS__) typedef enum log_priority { - DEBUG = 0, NOTICE, WARNING, ERROR + DEBUG = 0, NOTICE, WARNING, ERROR, CMD } log_priority; typedef int (*log_open_cb) (void); diff --git a/src/log_colored.c b/src/log_colored.c index 5434562..71f6d42 100644 --- a/src/log_colored.c +++ b/src/log_colored.c @@ -54,6 +54,9 @@ void log_fmt_colored(log_priority prio, const char *fmt, ...) case ERROR: printf("[" RED "ERROR" RESET "] [%d] %s\n", my_pid, out); break; + case CMD: + printf("[" BLUE "CMD" RESET "] [%d] %s\n", my_pid, out); + break; } } @@ -86,6 +89,8 @@ void log_fmtex_colored(log_priority prio, const char *srcfile, printf("[" RED "ERROR" RESET "] [%d] %s.%lu: %s\n", my_pid, srcfile, line, out); break; + case CMD: + break; } } @@ -143,5 +148,7 @@ void log_fmtexerr_colored(log_priority prio, const char *srcfile, my_pid, srcfile, line, out); break; + case CMD: + break; } } diff --git a/src/log_colored.h b/src/log_colored.h index 9f75557..b06a2f5 100644 --- a/src/log_colored.h +++ b/src/log_colored.h @@ -8,6 +8,7 @@ #define GRN "\x1B[32;1m" #define YEL "\x1B[33;1m" #define RED "\x1B[31;1;5m" +#define BLUE "\x1B[34;1;1m" /* LOG_SET_FUNCS comfort */ #define LOG_COLORED_FUNCS log_open_colored, log_close_colored, \ log_fmt_colored, log_fmtex_colored, log_fmtexerr_colored diff --git a/src/pevent.c b/src/pevent.c index 70fb311..3007472 100644 --- a/src/pevent.c +++ b/src/pevent.c @@ -113,14 +113,15 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) } forward_state -event_forward_connection(event_ctx *ctx, int dest_fd) +event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, + void *user_data) { int data_avail = 1; int has_input; int saved_errno; forward_state rc = CON_OK; ssize_t siz; - char buf[BUFSIZ+sizeof(long)]; + char buf[BUFSIZ]; struct epoll_event *ev; assert(ctx->current_event >= 0 && @@ -151,7 +152,6 @@ event_forward_connection(event_ctx *ctx, int dest_fd) rc = CON_IN_TERMINATED; break; default: - buf[siz] = 0; D2("Read %lu bytes from fd %d", siz, ev->data.fd); break; } @@ -159,6 +159,14 @@ event_forward_connection(event_ctx *ctx, int dest_fd) if (rc != CON_OK) break; + if (on_data && + on_data(ctx, ev->data.fd, dest_fd, buf, siz, user_data)) + { + W2("On data callback failed, not forwarding from %d to %d", + ev->data.fd, dest_fd); + continue; + } + if (has_input) { siz = write(dest_fd, &buf[0], siz); diff --git a/src/pevent.h b/src/pevent.h index c7b61e1..d6927f6 100644 --- a/src/pevent.h +++ b/src/pevent.h @@ -21,6 +21,8 @@ typedef struct event_ctx { } event_ctx; typedef int (*on_event_cb) (event_ctx *ev_ctx, int fd, void *user_data); +typedef int (*on_data_cb) (event_ctx *ev_ctx, int src_fd, int dst_fd, + char *buf, size_t siz, void *user_data); void event_init(event_ctx **ctx); @@ -36,6 +38,7 @@ int event_add_fd(event_ctx *ctx, int fd); int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data); forward_state -event_forward_connection(event_ctx *ctx, int dest_fd); +event_forward_connection(event_ctx *ctx, int dest_fd, on_data_cb on_data, + void *user_data); #endif diff --git a/src/redirector.c b/src/redirector.c index c21fa61..4a577ca 100644 --- a/src/redirector.c +++ b/src/redirector.c @@ -353,7 +353,7 @@ client_io(event_ctx *ev_ctx, int src_fd, void *user_data) dest_fd = ev_cli->fwd_sock->fd; } else return 0; - fwd_state = event_forward_connection(ev_ctx, dest_fd); + fwd_state = event_forward_connection(ev_ctx, dest_fd, NULL, NULL); switch (fwd_state_string(fwd_state, ev_cli->client_args, ev_cli->fwd_sock)) diff --git a/src/utils.c b/src/utils.c index d63edcc..4c6224d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <ctype.h> #include <stdarg.h> #include <fcntl.h> #include <signal.h> @@ -25,6 +26,7 @@ char *arg0 = NULL; static int null_fd = -1; static void sighandler_child(int signo); +static inline void bin2hex_char(unsigned char c, char hexc[5]); int set_fd_nonblock(int fd) @@ -445,3 +447,52 @@ int update_setgroups_self(int allow) return 0; } #endif + +static inline void bin2hex_char(unsigned char c, char hexc[5]) +{ + static const char hexalnum[] = "0123456789ABCDEF"; + + hexc[0] = '\\'; + hexc[1] = 'x'; + hexc[2] = hexalnum[ (c >> 4)%16 ]; + hexc[3] = hexalnum[ (c & 0x0F)%16 ]; + hexc[4] = 0; +} + +void escape_ascii_string(const char ascii[], size_t siz, char **dest, size_t *newsiz) +{ + char hexbyte[5]; + const size_t binsiz = 4; + size_t i, j, ns; + + assert(ascii && dest && newsiz); + + ns = 0; + for (i = 0; i < siz; ++i) { + if (isprint(ascii[i])) + ns++; + else + ns += binsiz; + } + + if (ns > *newsiz) { + if (*dest) + free(*dest); + *dest = (char *) malloc(sizeof(char) * (ns+1)); + assert(*dest); + (*newsiz) = ns; + } + + for (i = 0, j = 0; i < siz && j < ns; ++i) { + if (isprint(ascii[i])) { + (*dest)[j] = ascii[i]; + j++; + } else { + bin2hex_char(ascii[i], hexbyte); + snprintf((*dest)+j, binsiz+1, "%s", hexbyte); + j += binsiz; + } + } + + (*dest)[ns] = 0; +} diff --git a/src/utils.h b/src/utils.h index 8b3b230..3cd82e7 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,10 +1,14 @@ #ifndef POTD_UTILS_H #define POTD_UTILS_H 1 +#include <stdlib.h> + #ifndef SIZEOF #define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0])) #endif +#define MIN(x, y) (x > y ? y : x) + extern char *arg0; @@ -47,4 +51,7 @@ int update_guid_map(pid_t pid, unsigned int uid_map[3], int update_uidmap); int update_setgroups_self(int allow); #endif +void escape_ascii_string(const char ascii[], size_t siz, + char **dest, size_t *newsiz); + #endif |