diff options
author | lns <matzeton@googlemail.com> | 2018-07-26 19:12:48 +0200 |
---|---|---|
committer | lns <matzeton@googlemail.com> | 2018-07-26 19:12:48 +0200 |
commit | 4c31056b7bc7c5fbcf81bff0fdeb2229b4f8f0ad (patch) | |
tree | e8f8e3e0c61475fb9eb9d0ed474d3add20a4d4b3 /src | |
parent | ae2a806b35b8ef01f9bb45b6e091370fc03afb07 (diff) |
pevent timeout support, jail protocol handshake read
Signed-off-by: lns <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/jail.c | 32 | ||||
-rw-r--r-- | src/jail_protocol.c | 36 | ||||
-rw-r--r-- | src/jail_protocol.h | 6 | ||||
-rw-r--r-- | src/pevent.c | 18 | ||||
-rw-r--r-- | src/pevent.h | 5 | ||||
-rw-r--r-- | src/redirector.c | 4 |
6 files changed, 64 insertions, 37 deletions
@@ -155,7 +155,7 @@ int jail_setup_event(jail_ctx *ctx[], size_t siz, event_ctx **ev_ctx) assert(siz > 0 && siz < POTD_MAXFD); event_init(ev_ctx); - if (event_setup(*ev_ctx, POTD_WAITINF)) + if (event_setup(*ev_ctx)) return 1; for (size_t i = 0; i < siz; ++i) { @@ -407,6 +407,15 @@ static int jail_childfn(prisoner_process *ctx) if (update_guid_map(getpid(), ug_map, 1)) exit(EXIT_FAILURE); */ + + if (read(init_pipefd[0], &ctx->client_data, sizeof ctx->client_data) == + sizeof ctx->client_data) + { + N("Got additional Jail data: [user: '%s', pass: '%s']", + ctx->client_data.user, ctx->client_data.pass); + } + close(init_pipefd[0]); + close(master_fd); if (login_tty(slave_fd)) exit(EXIT_FAILURE); @@ -436,14 +445,6 @@ static int jail_childfn(prisoner_process *ctx) " -----------------------------------------------------\n" ); - if (read(init_pipefd[0], &ctx->client_data, sizeof ctx->client_data) == - sizeof ctx->client_data) - { - N("Got additional Jail data: [user: '%s', pass: '%s']", - ctx->client_data.user, ctx->client_data.pass); - } - close(init_pipefd[0]); - #ifdef HAVE_SECCOMP pseccomp_set_immutable(); pseccomp_init(&psc, @@ -507,7 +508,7 @@ static int jail_socket_tty(prisoner_process *ctx, int tty_fd, int init_fd) ev_cli.tty_fd = tty_fd; event_init(&ev_ctx); - if (event_setup(ev_ctx, POTD_WAITINF)) { + if (event_setup(ev_ctx)) { E_STRERR("Jail event context creation for jail tty fd %d", tty_fd); goto finish; @@ -550,16 +551,18 @@ static int jail_socket_tty(prisoner_process *ctx, int tty_fd, int init_fd) ev_cli.host_buf = &ctx->host_buf[0]; ev_cli.service_buf = &ctx->service_buf[0]; + snprintf(ctx->client_data.user, sizeof ctx->client_data.user, + "%s", "root"); + snprintf(ctx->client_data.pass, sizeof ctx->client_data.pass, + "%s", "pass"); + + event_set_timeout(ev_ctx, PROTO_TIMEOUT); if (!jail_protocol_handshake_read(ev_ctx, ctx->client_psock.fd, tty_fd, &ctx->client_data)) { N("Using Jail protocol for fd %d", ctx->client_psock.fd); } else { N("Using raw Jail communication for fd %d", ctx->client_psock.fd); - snprintf(ctx->client_data.user, sizeof ctx->client_data.user, - "%s", "root"); - snprintf(ctx->client_data.pass, sizeof ctx->client_data.pass, - "%s", "pass"); } if (write(init_fd, &ctx->client_data, sizeof ctx->client_data) != @@ -570,6 +573,7 @@ static int jail_socket_tty(prisoner_process *ctx, int tty_fd, int init_fd) } close(init_fd); + event_set_timeout(ev_ctx, POTD_WAITINF); rc = event_loop(ev_ctx, jail_socket_tty_io, &ev_cli); finish: close(ev_cli.signal_fd); diff --git a/src/jail_protocol.c b/src/jail_protocol.c index 4b6ebdd..582f298 100644 --- a/src/jail_protocol.c +++ b/src/jail_protocol.c @@ -66,7 +66,8 @@ ssize_t jail_protocol_readhdr(jail_data *dst, unsigned char *buf, if (ntohl(hdr->size) != data_siz) return -1; - switch (ntohl(hdr->type)) { + dst->last_type = ntohl(hdr->type); + switch (dst->last_type) { case PROTO_TYPE_USER: min_siz = MIN(data_siz, USER_LEN); memcpy(dst->user, (char *) buf + sizeof(*hdr), min_siz); @@ -86,14 +87,15 @@ ssize_t jail_protocol_readhdr(jail_data *dst, unsigned char *buf, return data_siz; } -ssize_t jail_protocol_writehdr(jail_protocol_hdr *src, int type, - unsigned char *buf, size_t bufsiz) +ssize_t jail_protocol_writehdr(int type, unsigned char *buf, size_t bufsiz) { jail_protocol_hdr *hdr; size_t data_siz; - assert(src && buf); + assert(buf); + if (bufsiz < sizeof(*hdr)) + return -1; hdr = (jail_protocol_hdr *) buf; hdr->magic = htonl(PROTO_MAGIC); hdr->type = htonl(type); @@ -107,28 +109,34 @@ static int handshake_read_loop(event_ctx *ev_ctx, int src_fd, void *user_data) { jail_event *ev_jail = (jail_event *) user_data; - int siz, rc, dst_fd; + int dst_fd = -1; + ssize_t siz, rc = -1; unsigned char buf[BUFSIZ] = {0}; (void) ev_ctx; - if (src_fd == ev_jail->sock_fd) + if (src_fd == ev_jail->sock_fd) { dst_fd = ev_jail->tty_fd; - else if (src_fd == ev_jail->tty_fd) + } else if (src_fd == ev_jail->tty_fd) { dst_fd = ev_jail->sock_fd; - else - goto error; + } else goto error; siz = read(src_fd, buf, sizeof buf); if (siz <= 0) goto error; - rc = jail_protocol_readhdr(ev_jail->data, buf, sizeof buf); - if (rc < 0) { - rc = write(dst_fd, buf, siz); - goto error; + + if (src_fd == ev_jail->sock_fd) { + rc = jail_protocol_readhdr(ev_jail->data, buf, siz); + + if (rc <= 0) + ev_ctx->active = 0; + if (rc > 0 && ev_jail->data->last_type == PROTO_TYPE_DATA) { + ev_jail->data->used = 1; + ev_ctx->active = 0; + } } - return 1; + return write(dst_fd, buf, siz) == siz; error: ev_ctx->active = 0; return 1; diff --git a/src/jail_protocol.h b/src/jail_protocol.h index fee2ef8..51cdf54 100644 --- a/src/jail_protocol.h +++ b/src/jail_protocol.h @@ -10,14 +10,15 @@ #define USER_LEN 255 #define PASS_LEN 255 +#define PROTO_TIMEOUT 1000 #define PROTO_MAGIC 0xdeadc0de -#define PROTO_TYPE_EHLO 0xcafebabe #define PROTO_TYPE_USER 0x41414141 #define PROTO_TYPE_PASS 0x42424242 #define PROTO_TYPE_DATA 0x43434343 typedef struct __attribute__((packed, aligned(4))) jail_data { int used; + uint32_t last_type; char user[USER_LEN+1]; char pass[PASS_LEN+1]; } jail_data; @@ -32,8 +33,7 @@ typedef struct jail_protocol_hdr { ssize_t jail_protocol_readhdr(jail_data *dst, unsigned char *buf, size_t bufsiz); -ssize_t jail_protocol_writehdr(jail_protocol_hdr *hdr, int type, - unsigned char *buf, size_t bufsiz); +ssize_t jail_protocol_writehdr(int type, unsigned char *buf, size_t bufsiz); int jail_protocol_handshake_read(event_ctx *ev_client, int client_fd, int tty_fd, jail_data *dst); diff --git a/src/pevent.c b/src/pevent.c index bb4d0b0..0d02593 100644 --- a/src/pevent.c +++ b/src/pevent.c @@ -80,19 +80,26 @@ void event_free(event_ctx **ctx) *ctx = NULL; } -int event_setup(event_ctx *ctx, int timeout) +int event_setup(event_ctx *ctx) { assert(ctx); if (ctx->epoll_fd < 0) /* flags == 0 -> obsolete size arg is dropped */ ctx->epoll_fd = epoll_create1(0); + ctx->timeout = POTD_WAITINF; + + return ctx->epoll_fd < 0; +} + +void event_set_timeout(event_ctx *ctx, int timeout) +{ + assert(ctx); + if (timeout < 0) ctx->timeout = POTD_WAITINF; else ctx->timeout = timeout; - - return ctx->epoll_fd < 0; } int event_add_sock(event_ctx *ctx, psocket *sock) @@ -137,6 +144,7 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) sigemptyset(&eset); ctx->active = 1; ctx->has_error = 0; + ctx->has_timeout = 0; while (ctx->active && !ctx->has_error) { errno = 0; @@ -145,6 +153,10 @@ int event_loop(event_ctx *ctx, on_event_cb on_event, void *user_data) saved_errno = errno; if (errno == EINTR) continue; + if (n == 0 && ctx->timeout > POTD_WAITINF) { + ctx->has_timeout = 0; + break; + } if (n < 0) { ctx->has_error = 1; break; diff --git a/src/pevent.h b/src/pevent.h index 607949d..52dfdce 100644 --- a/src/pevent.h +++ b/src/pevent.h @@ -50,6 +50,7 @@ typedef enum forward_state { typedef struct event_ctx { int active; int has_error; + int has_timeout; int timeout; int epoll_fd; @@ -66,7 +67,9 @@ void event_init(event_ctx **ctx); void event_free(event_ctx **ctx); -int event_setup(event_ctx *ctx, int timeout); +int event_setup(event_ctx *ctx); + +void event_set_timeout(event_ctx *ctx, int timeout); int event_add_sock(event_ctx *ctx, psocket *sock); diff --git a/src/redirector.c b/src/redirector.c index 42952ea..3c5acdc 100644 --- a/src/redirector.c +++ b/src/redirector.c @@ -172,7 +172,7 @@ int redirector_setup_event(redirector_ctx *rdr_ctx[], size_t siz, event_ctx **ev assert(siz > 0 && siz < POTD_MAXFD); event_init(ev_ctx); - if (event_setup(*ev_ctx, POTD_WAITINF)) + if (event_setup(*ev_ctx)) return 1; for (size_t i = 0; i < siz; ++i) { @@ -390,7 +390,7 @@ client_mainloop(void *arg) args = (client_thread *) arg; event_init(&ev_ctx); - if (event_setup(ev_ctx, POTD_WAITINF)) { + if (event_setup(ev_ctx)) { E_STRERR("Client event context creation for server fd %d", args->rdr_ctx->sock.fd); goto finish; |