diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-04-16 10:32:08 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-04-16 10:32:08 +0200 |
commit | 914f8f335d73c4dd69b72f6f2d8c53257bce497d (patch) | |
tree | 2afd127888557aa244aba2951932af25d5767133 | |
parent | c9b2cd567ed8bbe2df36821a26a56a8d713c2c80 (diff) |
POTD skeleton #9.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | src/main.c | 19 | ||||
-rw-r--r-- | src/server.c | 42 | ||||
-rw-r--r-- | src/server.h | 7 | ||||
-rw-r--r-- | src/server_ssh.c | 39 | ||||
-rw-r--r-- | src/server_ssh.h | 1 | ||||
-rw-r--r-- | src/socket.c | 29 | ||||
-rw-r--r-- | src/socket.h | 2 |
7 files changed, 93 insertions, 46 deletions
@@ -11,7 +11,7 @@ int main(int argc, char *argv[]) { const size_t srv_siz = 3; const char *ssh_ports[srv_siz]; - server_ctx srv[srv_siz]; + server_ctx *srv[srv_siz]; struct addrinfo *netifs = NULL; int epoll_fd; @@ -21,37 +21,38 @@ int main(int argc, char *argv[]) LOG_SET_FUNCS_VA(LOG_COLORED_FUNCS); N("%s (C) 2018 Toni Uhlig (%s)", PACKAGE_STRING, PACKAGE_BUGREPORT); - memset(&srv[0], 0, sizeof(srv)); + memset(srv, 0, sizeof(srv)); ssh_ports[0] = "2222"; ssh_ports[1] = "2223"; ssh_ports[2] = "22050"; + for (size_t i = 0; i < srv_siz; ++i) { D("Initialising redirector service on port %s", ssh_ports[i]); - ABORT_ON_FATAL( server_init_ctx(&srv[i], ssh_init_cb), + ABORT_ON_FATAL( server_init_ctx(&srv[i], ssh_init_cb) == 0, "Server initialisation" ); - server_validate_ctx(&srv[i]); + server_validate_ctx(srv[i]); GAI_ABORT_ON_FATAL( socket_init_in(NULL, ssh_ports[i], &netifs), "Socket initialisation" ); - ABORT_ON_FATAL( socket_bind_in(&srv[i].sock, netifs), + ABORT_ON_FATAL( socket_bind_in(&srv[i]->sock, netifs), "Socket bind" ); - ABORT_ON_FATAL( socket_listen_in(&srv[i].sock), + ABORT_ON_FATAL( socket_listen_in(&srv[i]->sock), "Socket listen" ); - ABORT_ON_FATAL( srv[i].server_cbs.on_listen(&srv[i].server_dat), + ABORT_ON_FATAL( srv[i]->server_cbs.on_listen(&srv[i]->server_dat), "Socket on listen callback" ); } D2("%s", "Server epoll setup"); - epoll_fd = server_setup_epoll( &srv[0], srv_siz ); + epoll_fd = server_setup_epoll( srv, srv_siz ); D2("epoll_fd: %d", epoll_fd); ABORT_ON_FATAL( epoll_fd < 0, "Server epoll setup" ); N("%s", "Server epoll mainloop"); - ABORT_ON_FATAL( server_mainloop_epoll( epoll_fd, &srv[0], srv_siz ), + ABORT_ON_FATAL( server_mainloop_epoll( epoll_fd, srv, srv_siz ), "Server epoll mainloop" ); return 0; diff --git a/src/server.c b/src/server.c index 8c71554..884ec5b 100644 --- a/src/server.c +++ b/src/server.c @@ -17,25 +17,25 @@ typedef struct client_thread_args { const server_ctx *server_ctx; } client_thread_args; -static int server_accept_client(const server_ctx ctx[], +static int server_accept_client(server_ctx *ctx[], size_t siz, struct epoll_event *event); static void * client_mainloop_epoll(void *arg); static int client_io_epoll(struct epoll_event *ev); -server_ctx * -server_init_ctx(server_ctx *ctx, init_cb init_fn) +int server_init_ctx(server_ctx **ctx, init_cb init_fn) { - if (!ctx) - ctx = (server_ctx *) malloc(sizeof(*ctx)); assert(ctx); + if (!*ctx) + *ctx = (server_ctx *) malloc(sizeof(**ctx)); + assert(*ctx || init_fn); - memset(ctx, 0, sizeof(*ctx)); - if (!init_fn(ctx)) - return NULL; + memset(*ctx, 0, sizeof(**ctx)); + if (!init_fn(*ctx)) + return 1; - return ctx; + return 0; } int server_validate_ctx(const server_ctx *ctx) @@ -45,7 +45,7 @@ int server_validate_ctx(const server_ctx *ctx) return 0; } -int server_setup_epoll(server_ctx ctx[], size_t siz) +int server_setup_epoll(server_ctx *ctx[], size_t siz) { int s, fd = epoll_create1(0); /* flags == 0 -> obsolete size arg is dropped */ struct epoll_event ev; @@ -57,19 +57,19 @@ int server_setup_epoll(server_ctx ctx[], size_t siz) for (size_t i = 0; i < siz; ++i) { memset(&ev, 0, sizeof(ev)); - ev.data.fd = ctx[i].sock.fd; + ev.data.fd = ctx[i]->sock.fd; ev.events = EPOLLIN | EPOLLET; - s = socket_addrtostr_in(&ctx[i].sock, - ctx[i].host_buf, ctx[i].service_buf); + s = socket_addrtostr_in(&ctx[i]->sock, + ctx[i]->host_buf, ctx[i]->service_buf); if (s) { E_GAIERR(s, "Convert socket address to string"); return -2; } N("Redirector service listening on %s:%s", - ctx[i].host_buf, ctx[i].service_buf); + ctx[i]->host_buf, ctx[i]->service_buf); - s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i].sock.fd, &ev); + s = epoll_ctl(fd, EPOLL_CTL_ADD, ctx[i]->sock.fd, &ev); if (s) { close(fd); return -3; @@ -79,7 +79,7 @@ int server_setup_epoll(server_ctx ctx[], size_t siz) return fd; } -int server_mainloop_epoll(int epoll_fd, const server_ctx ctx[], size_t siz) +int server_mainloop_epoll(int epoll_fd, server_ctx *ctx[], size_t siz) { static struct epoll_event *events = NULL; @@ -120,7 +120,7 @@ int server_mainloop_epoll(int epoll_fd, const server_ctx ctx[], size_t siz) return 0; } -static int server_accept_client(const server_ctx ctx[], +static int server_accept_client(server_ctx *ctx[], size_t siz, struct epoll_event *event) { size_t i; @@ -128,15 +128,15 @@ static int server_accept_client(const server_ctx ctx[], client_thread_args *args; for (i = 0; i < siz; ++i) { - if (ctx[i].sock.fd == event->data.fd) { + if (ctx[i]->sock.fd == event->data.fd) { args = (client_thread_args *) calloc(1, sizeof(client_thread_args)); - if (socket_accept_in(&ctx[i].sock, &args->client_psock)) { + if (socket_accept_in(&ctx[i]->sock, &args->client_psock)) { E_STRERR("Could not accept client connection"); return 0; } - args->server_ctx = &ctx[i]; + args->server_ctx = ctx[i]; s = socket_addrtostr_in(&args->client_psock, args->host_buf, args->service_buf); if (s) { @@ -145,7 +145,7 @@ static int server_accept_client(const server_ctx ctx[], } N("New connection from %s:%s to %s:%s: %d", args->host_buf, args->service_buf, - ctx[i].host_buf, ctx[i].service_buf, + ctx[i]->host_buf, ctx[i]->service_buf, args->client_psock.fd); if (pthread_create(&args->self, NULL, diff --git a/src/server.h b/src/server.h index 32a711d..07ca93b 100644 --- a/src/server.h +++ b/src/server.h @@ -28,13 +28,12 @@ typedef struct server_ctx { typedef int (*init_cb) (struct server_ctx *ctx); -server_ctx * -server_init_ctx(server_ctx *ctx, init_cb init_fn); +int server_init_ctx(server_ctx **ctx, init_cb init_fn); int server_validate_ctx(const server_ctx *ctx); -int server_setup_epoll(server_ctx ctx[], size_t siz); +int server_setup_epoll(server_ctx *ctx[], size_t siz); -int server_mainloop_epoll(int epoll_fd, const server_ctx ctx[], size_t siz); +int server_mainloop_epoll(int epoll_fd, server_ctx *ctx[], size_t siz); #endif diff --git a/src/server_ssh.c b/src/server_ssh.c index 1c72b61..9f24657 100644 --- a/src/server_ssh.c +++ b/src/server_ssh.c @@ -1,36 +1,47 @@ #include <stdlib.h> +#include <assert.h> #include <libssh/callbacks.h> #include <libssh/server.h> #include "server_ssh.h" #include "server.h" +#include "log.h" struct server_callbacks potd_ssh_callbacks = { .on_listen = ssh_on_listen, .on_shutdown = ssh_on_shutdown }; -static void set_default_keys(ssh_bind sshbind, int rsa_already_set, - int dsa_already_set, int ecdsa_already_set); +static int set_default_keys(ssh_bind sshbind, int rsa_already_set, + int dsa_already_set, int ecdsa_already_set); int ssh_init_cb(struct server_ctx *ctx) { ctx->server_cbs = potd_ssh_callbacks; - ssh_init(); + if (ssh_init()) + return 1; ssh_data *d = (ssh_data *) calloc(1, sizeof(*d)); + assert(d); d->sshbind = ssh_bind_new(); + d->session = ssh_new(); ctx->server_dat.data = d; - if (!d->sshbind) + if (!d->sshbind || !d->session) + return 1; + if (set_default_keys(d->sshbind, 0, 0, 0)) return 1; - set_default_keys(d->sshbind, 0, 0, 0); return 0; } int ssh_on_listen(struct server_data *data) { + ssh_data *d = (ssh_data *) data->data; + + if (ssh_bind_listen(d->sshbind) < 0) { + E("Error listening to SSH socket: %s", ssh_get_error(d->sshbind)); + } return 0; } @@ -39,19 +50,23 @@ int ssh_on_shutdown(struct server_data *data) return 0; } -static void set_default_keys(ssh_bind sshbind, int rsa_already_set, +static int set_default_keys(ssh_bind sshbind, int rsa_already_set, int dsa_already_set, int ecdsa_already_set) { if (!rsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, - "./ssh_host_rsa_key"); + if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, + "./ssh_host_rsa_key")) + return 1; } if (!dsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, - "./ssh_host_dsa_key"); + if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, + "./ssh_host_dsa_key")) + return 1; } if (!ecdsa_already_set) { - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, - "./ssh_host_ecdsa_key"); + if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, + "./ssh_host_ecdsa_key")) + return 1; } + return 0; } diff --git a/src/server_ssh.h b/src/server_ssh.h index 893c2e8..e057814 100644 --- a/src/server_ssh.h +++ b/src/server_ssh.h @@ -7,6 +7,7 @@ typedef struct ssh_data { ssh_bind sshbind; + ssh_session session; } ssh_data; diff --git a/src/socket.c b/src/socket.c index 4fe5e3a..b666eb1 100644 --- a/src/socket.c +++ b/src/socket.c @@ -92,6 +92,35 @@ int socket_accept_in(const psocket *psock, psocket *client_psock) return 0; } +int socket_connect_in(psocket *psock, struct addrinfo *results) +{ + int fd = -1, rv, reuse_enable = 1; + struct addrinfo *rp = NULL; + + assert(psock && results); + + for (rp = results; rp != NULL; rp = rp->ai_next) { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd < 0) + continue; + rv = connect(fd, rp->ai_addr, rp->ai_addrlen); + if (!rv) + break; + close(fd); + } + + if (!rp) + return -1; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_enable, sizeof(int)) < 0) + return -2; + psock->fd = fd; + psock->addr_len = rp->ai_addrlen; + psock->addr = *rp->ai_addr; + freeaddrinfo(results); + return socket_nonblock(psock); +} + int socket_addrtostr_in(const psocket *psock, char hbuf[NI_MAXHOST], char sbuf[NI_MAXSERV]) { diff --git a/src/socket.h b/src/socket.h index 69c2690..cdc556a 100644 --- a/src/socket.h +++ b/src/socket.h @@ -21,6 +21,8 @@ int socket_listen_in(psocket *psock); int socket_accept_in(const psocket *psock, psocket *client_psock); +int socket_connect_in(psocket *psock, struct addrinfo *results); + int socket_addrtostr_in(const psocket *psock, char hbuf[NI_MAXHOST], char sbuf[NI_MAXSERV]); |