diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-05-20 13:14:38 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-05-20 13:14:38 +0200 |
commit | de7939699e83a35015328371c45d4e3df3b06279 (patch) | |
tree | 286b96f06708db15043ca4f5a02c734f4ecfd3fa | |
parent | 9b9825fa6a33a4f9703905100a88190aaf030607 (diff) |
POTD skeleton #64.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | src/log.h | 10 | ||||
-rw-r--r-- | src/main.c | 49 | ||||
-rw-r--r-- | src/protocol.c | 5 | ||||
-rw-r--r-- | src/protocol.h | 2 | ||||
-rw-r--r-- | src/protocol_ssh.c | 16 | ||||
-rw-r--r-- | src/utils.c | 23 | ||||
-rw-r--r-- | src/utils.h | 2 |
7 files changed, 93 insertions, 14 deletions
@@ -30,14 +30,20 @@ #define ABORT_ON_FATAL(expr, msg) \ { errno = 0; long rv = (long) expr; \ if (rv) { \ + /* \ E_STRERR("`%s` returned %ld. %s", \ #expr, rv, msg); abort(); \ + */ \ + E_STRERR("%s", msg); abort(); \ } \ } #define GAI_ABORT_ON_FATAL(expr, msg) \ { int rv = expr; \ - if (rv) { E2("`%s` returned: %d", #expr, rv); \ - E_GAIERR(rv, msg); abort(); } } + 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 { @@ -1,4 +1,5 @@ #include <stdio.h> +#include <assert.h> #include <sys/types.h> #include <sys/wait.h> @@ -15,6 +16,31 @@ #include "config.h" #endif +static void ssh_protocol_preinit(const char *ssh_ports[], protocol_ctx *ctx[], + const char *jail_ports[], const size_t siz); +static void ssh_protocol_postinit(protocol_ctx *ctx[], const size_t siz); + + +static void ssh_protocol_preinit(const char *ssh_ports[], protocol_ctx *ctx[], + const char *jail_ports[], const size_t siz) +{ + for (size_t i = 0; i < siz; ++i) { + ABORT_ON_FATAL( proto_init_ctx(&ctx[i], ssh_init_cb), + "SSH Protocol init" ); + ABORT_ON_FATAL( proto_setup(ctx[i], "127.0.0.1", ssh_ports[i], + "127.0.0.1", jail_ports[i]), "SSH Protocol setup" ); + ABORT_ON_FATAL( proto_validate_ctx(ctx[i]), + "SSH validation" ); + } +} + +static void ssh_protocol_postinit(protocol_ctx *ctx[], const size_t siz) +{ + for (size_t i = 0; i < siz; ++i) { + ABORT_ON_FATAL( proto_listen(ctx[i]), + "SSH Protocol listen" ); + } +} int main(int argc, char *argv[]) { @@ -38,7 +64,9 @@ int main(int argc, char *argv[]) arg0 = argv[0]; LOG_SET_FUNCS_VA(LOG_COLORED_FUNCS); +#ifdef HAVE_CONFIG_H N("%s (C) 2018 Toni Uhlig (%s)", PACKAGE_STRING, PACKAGE_BUGREPORT); +#endif if (geteuid() != 0) { E("%s", "I was made for root!"); @@ -60,6 +88,8 @@ int main(int argc, char *argv[]) FATAL("Forking (fork returned %d)", daemon_pid); } D2("Master pid: %d", getpid()); + ABORT_ON_FATAL( set_master_sighandler(), + "Master sighandler" ); memset(jail, 0, sizeof(jail)); jail_ports[0] = "33333"; @@ -85,15 +115,14 @@ int main(int argc, char *argv[]) memset(ssh_proto, 0, sizeof(proto_ports)); proto_ports[0] = "22222"; proto_ports[1] = "22223"; + assert(SIZEOF(proto_ports) == SIZEOF(jail_ports)); + ssh_protocol_preinit(proto_ports, ssh_proto, jail_ports, proto_siz); - for (size_t i = 0; i < proto_siz; ++i) { - ABORT_ON_FATAL( proto_init_ctx(&ssh_proto[i], ssh_init_cb), - "SSH Protocol init" ); - ABORT_ON_FATAL( proto_setup(ssh_proto[i], "127.0.0.1", proto_ports[i], - "127.0.0.1", jail_ports[i]), "SSH Protocol setup" ); - ABORT_ON_FATAL( proto_validate_ctx(ssh_proto[i]), - "SSH validation" ); - } + D2("Main process is dropping privileges to %s:%s", "nobody", "NULL"); + ABORT_ON_FATAL( change_user_group("nobody", NULL), + "Main process dropping privileges" ); + + ssh_protocol_postinit(ssh_proto, proto_siz); memset(rdr, 0, sizeof(rdr)); rdr_ports[0] = "2222"; @@ -115,10 +144,6 @@ int main(int argc, char *argv[]) ABORT_ON_FATAL( redirector_setup_event( rdr, rdr_siz, &rdr_event ), "Redirector event setup" ); - D2("Main process is dropping privileges to %s:%s", "nobody", "NULL"); - ABORT_ON_FATAL( change_user_group("nobody", NULL), - "Main process dropping privileges" ); - N("%s", "Redirector epoll mainloop"); rdr_pid = redirector_daemonize( rdr_event, rdr, rdr_siz ); ABORT_ON_FATAL( rdr_pid < 1, "Server epoll mainloop" ); diff --git a/src/protocol.c b/src/protocol.c index 5b487f1..ad291de 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -32,6 +32,11 @@ int proto_setup(protocol_ctx *ctx, const char *listen_addr, if (fwd_setup_client_silent(&ctx->dst, jail_host, jail_port)) return 1; + return 0; +} + +int proto_listen(protocol_ctx *ctx) +{ if (!ctx->cbs.on_listen) return 1; if (ctx->cbs.on_listen(ctx)) diff --git a/src/protocol.h b/src/protocol.h index 4024aec..cc26d3c 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -30,6 +30,8 @@ int proto_setup(protocol_ctx *ctx, const char *listen_addr, const char *listen_port, const char *jail_host, const char *jail_port); +int proto_listen(protocol_ctx *ctx); + int proto_validate_ctx(const protocol_ctx *ctx); #endif diff --git a/src/protocol_ssh.c b/src/protocol_ssh.c index abed82a..1aaa974 100644 --- a/src/protocol_ssh.c +++ b/src/protocol_ssh.c @@ -154,7 +154,15 @@ int ssh_on_shutdown(protocol_ctx *ctx) static int set_default_keys(ssh_bind sshbind, int rsa_already_set, int dsa_already_set, int ecdsa_already_set) { + const char rsa_key[] = "./ssh_host_rsa_key"; + const char dsa_key[] = "./ssh_host_dsa_key"; + const char ecdsa_key[] = "./ssh_host_ecdsa_key"; + if (!rsa_already_set) { + if (access(rsa_key, R_OK)) { + E_STRERR("RSA key '%s' inaccessible", rsa_key); + return 1; + } if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, "./ssh_host_rsa_key")) { E2("Faled to set RSA key: %s", ssh_get_error(sshbind)); @@ -162,6 +170,10 @@ static int set_default_keys(ssh_bind sshbind, int rsa_already_set, } } if (!dsa_already_set) { + if (access(dsa_key, R_OK)) { + E_STRERR("DSA key '%s' inaccesible", dsa_key); + return 1; + } if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, "./ssh_host_dsa_key")) { E2("Failed to set DSA key: %s", ssh_get_error(sshbind)); @@ -169,6 +181,10 @@ static int set_default_keys(ssh_bind sshbind, int rsa_already_set, } } if (!ecdsa_already_set) { + if (access(ecdsa_key, R_OK)) { + E_STRERR("ECDSA key '%s' inaccesible", ecdsa_key); + return 1; + } if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, "./ssh_host_ecdsa_key")) { E2("Failed to set ECDSA key: %s", ssh_get_error(sshbind)); diff --git a/src/utils.c b/src/utils.c index ca24f6b..455b90d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -26,6 +26,7 @@ char *arg0 = NULL; static int null_fd = -1; static void sighandler_child(int signo); +static void sighandler_master(int signo); static inline void bin2hex_char(unsigned char c, char hexc[5]); @@ -69,6 +70,28 @@ int set_child_sighandler(void) return signal(SIGHUP, sighandler_child) == SIG_ERR; } +static void sighandler_master(int signo) +{ + switch (signo) { + case SIGINT: + case SIGTERM: + case SIGABRT: + kill(0, SIGKILL); + exit(EXIT_FAILURE); + } +} + +int set_master_sighandler(void) +{ + int s = 0; + + s |= signal(SIGINT, sighandler_master) == SIG_ERR; + s |= signal(SIGTERM, sighandler_master) == SIG_ERR; + s |= signal(SIGABRT, sighandler_master) == SIG_ERR; + + return s; +} + void set_procname(const char *new_arg0) { assert(arg0); diff --git a/src/utils.h b/src/utils.h index 3cd82e7..9ea1024 100644 --- a/src/utils.h +++ b/src/utils.h @@ -16,6 +16,8 @@ int set_fd_nonblock(int fd); int set_child_sighandler(void); +int set_master_sighandler(void); + void set_procname(const char *new_arg0); pid_t daemonize(int stay_foreground); |