From 98b9b13628a7613868e0fda618e6303961932550 Mon Sep 17 00:00:00 2001 Message-Id: <98b9b13628a7613868e0fda618e6303961932550.1715019495.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sat, 19 May 2018 21:51:11 +0100 Subject: [PATCH] server/tripe.c, server/standalone.c: Split `main' out into a seprate file. Organization: Straylight/Edgeware From: Mark Wooding We can also remove the temporary hacks from `test.c'. --- server/Makefile.am | 2 + server/standalone.c | 326 ++++++++++++++++++++++++++++++++++++++++++++ server/test.c | 5 - server/tripe.c | 295 --------------------------------------- 4 files changed, 328 insertions(+), 300 deletions(-) create mode 100644 server/standalone.c diff --git a/server/Makefile.am b/server/Makefile.am index 02984546..607de24c 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -54,6 +54,7 @@ tripe_SOURCES += peer.c tripe_SOURCES += privsep.c tripe_SOURCES += admin.c tripe_SOURCES += tripe.c +tripe_SOURCES += standalone.c ## Tunnel drivers. tripe_SOURCES += tun-std.c @@ -92,6 +93,7 @@ tripe_test_SOURCES += keyset.c tripe_test_SOURCES += peer.c tripe_test_SOURCES += privsep.c tripe_test_SOURCES += servutil.c +tripe_test_SOURCES += tripe.c tripe_test_SOURCES += tun-std.c tripe_test_SOURCES += tun-slip.c diff --git a/server/standalone.c b/server/standalone.c new file mode 100644 index 00000000..9b4976cb --- /dev/null +++ b/server/standalone.c @@ -0,0 +1,326 @@ +/* -*-c-*- + * + * Initialization for the standalone server + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Trivial IP Encryption (TrIPE). + * + * TrIPE is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * TrIPE is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with TrIPE. If not, see . + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "tripe.h" + +/*----- Tunnel table ------------------------------------------------------*/ + +static const tunnel_ops *tunnels[] = { +#ifdef TUN_LINUX + &tun_linux, +#endif +#ifdef TUN_BSD + &tun_bsd, +#endif +#ifdef TUN_UNET + &tun_unet, +#endif + &tun_slip, +}; + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @main@ --- * + * + * Arguments: @int argc@ = number of command line arguments + * @char *argv[]@ = vector of arguments + * + * Returns: Zero if OK, nonzero on error. + * + * Use: Main program. Provides a simple VPN. + */ + +static void usage(FILE *fp) +{ + pquis(fp, "Usage: $ [-DF] [-d DIR] [-b ADDR] [-p PORT] [-n TUNNEL]\n\ + [-U USER] [-G GROUP] [-a SOCKET] [-m MODE] [-T TRACE-OPTS]\n\ + [-k PRIV-KEYRING] [-K PUB-KEYRING] [-t KEY-TAG]\n"); +} + +static void version(FILE *fp) { pquis(fp, "$, version " VERSION "\n"); } + +static void help(FILE *fp) +{ + version(fp); + fputc('\n', fp); + usage(fp); + fputs("\n\ +Options:\n\ +\n\ +-h, --help Display this help text.\n\ +-v, --version Display version number.\n\ +-u, --usage Display pointless usage message.\n\ + --tunnels Display IP tunnel drivers and exit.\n\ +\n\ +-4, --ipv4 Transport over IPv4 only.\n\ +-6, --ipv6 Transport over IPv6 only.\n\ +-D, --daemon Run in the background.\n\ +-F, --foreground Quit when stdin reports end-of-file.\n\ +-d, --directory=DIR Switch to directory DIR [default " CONFIGDIR "].\n\ +-b, --bind-address=ADDR Bind UDP socket to this IP ADDR.\n\ +-p, --port=PORT Select UDP port to listen to " + "[default " STR(TRIPE_PORT) "].\n\ +-n, --tunnel=TUNNEL Seelect default tunnel driver.\n\ +-U, --setuid=USER Set uid to USER after initialization.\n\ +-G, --setgid=GROUP Set gid to GROUP after initialization.\n\ +-k, --priv-keyring=FILE Get private key from FILE.\n\ +-K, --pub-keyring=FILE Get public keys from FILE.\n\ +-t, --tag=KEYTAG Use private key labelled TAG.\n\ +-a, --admin-socket=FILE Use FILE as the adminstration socket.\n\ +-m, --admin-perms=MODE Permissions to set on admin socket [default 600].\n\ +" T( "\ +-T, --trace=OPTIONS Turn on tracing options.\n\ +" ) "\ +", fp); +} + +int main(int argc, char *argv[]) +{ + const char *kr_priv = "keyring", *kr_pub = "keyring.pub"; + const char *tag_priv = 0; + const char *csock = SOCKETDIR "/tripesock"; + int csockmode = 0600; + const char *dir = CONFIGDIR; + const char *p; + const char *bindhost = 0, *bindsvc = STR(TRIPE_PORT); + struct addrinfo aihint = { 0 }, *ailist; + const tunnel_ops *dflt = 0; + unsigned f = 0; + int i; + int err; + unsigned af; + uid_t u = -1; + gid_t g = -1; + +#define f_bogus 1u +#define f_daemon 2u +#define f_foreground 4u + + ego(argv[0]); + T( trace_on(stderr, 0); ) + + if ((p = getenv("TRIPEDIR")) != 0) + dir = p; + if ((p = getenv("TRIPESOCK")) != 0) + csock = p; + aihint.ai_family = AF_UNSPEC; + + for (;;) { + static const struct option opts[] = { + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'v' }, + { "usage", 0, 0, 'u' }, + { "tunnels", 0, 0, '0' }, + + { "ipv4", 0, 0, '4' }, + { "ipv6", 0, 0, '6' }, + { "daemon", 0, 0, 'D' }, + { "foreground", 0, 0, 'F' }, + { "uid", OPTF_ARGREQ, 0, 'U' }, + { "setuid", OPTF_ARGREQ, 0, 'U' }, + { "gid", OPTF_ARGREQ, 0, 'G' }, + { "setgid", OPTF_ARGREQ, 0, 'G' }, + { "bind-address", OPTF_ARGREQ, 0, 'b' }, + { "tunnel", OPTF_ARGREQ, 0, 'n' }, + { "port", OPTF_ARGREQ, 0, 'p' }, + { "directory", OPTF_ARGREQ, 0, 'd' }, + { "priv-keyring", OPTF_ARGREQ, 0, 'k' }, + { "pub-keyring", OPTF_ARGREQ, 0, 'K' }, + { "tag", OPTF_ARGREQ, 0, 't' }, + { "admin-socket", OPTF_ARGREQ, 0, 'a' }, + { "admin-perms", OPTF_ARGREQ, 0, 'm' }, +#ifndef NTRACE + { "trace", OPTF_ARGREQ, 0, 'T' }, +#endif + + { 0, 0, 0, 0 } + }; + + i = mdwopt(argc, argv, "hvu46DFU:G:b:n:p:d:k:K:t:a:m:" T("T:"), + opts, 0, 0, 0); + if (i < 0) + break; + switch (i) { + case 'h': + help(stdout); + exit(0); + case 'v': + version(stdout); + exit(0); + case 'u': + usage(stdout); + exit(0); + + case '4': + aihint.ai_family = AF_INET; + break; + case '6': + aihint.ai_family = AF_INET6; + break; + case 'D': + f |= f_daemon; + break; + case 'U': + u = u_getuser(optarg, &g); + break; + case 'G': + g = u_getgroup(optarg); + break; + case 'F': + f |= f_foreground; + break; + + case 'b': + bindhost = optarg; + break; + case 'p': + bindsvc = optarg; + break; + case 'n': { + int i; + for (i = 0; i < N(tunnels); i++) + if (mystrieq(optarg, tunnels[i]->name)) + { dflt = tunnels[i]; goto found_tun; } + die(EXIT_FAILURE, "unknown tunnel `%s'", optarg); + found_tun:; + } break; + case 'd': + dir = optarg; + break; + case 'k': + kr_priv = optarg; + break; + case 'K': + kr_pub = optarg; + break; + case 'a': + csock = optarg; + break; + case 'm': { + char *p; + csockmode = strtol(optarg, &p, 8); + if (*p) die(EXIT_FAILURE, "bad permissions: `%s'", optarg); + } break; + case 't': + tag_priv = optarg; + break; +#ifndef NTRACE + case 'T': + tr_flags = traceopt(tr_opts, optarg, tr_flags, 0); + trace_level(tr_flags); + break; +#endif + case '0': { + int i; + for (i = 0; i < N(tunnels); i++) + puts(tunnels[i]->name); + exit(0); + } break; + default: + f |= f_bogus; + break; + } + } + + if (optind < argc || (f & f_bogus)) { + usage(stderr); + exit(EXIT_FAILURE); + } + if (!(~f & (f_daemon | f_foreground))) + die(EXIT_FAILURE, "foreground operation for a daemon is silly"); + + aihint.ai_protocol = IPPROTO_UDP; + aihint.ai_socktype = SOCK_DGRAM; + aihint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + if ((err = getaddrinfo(bindhost, bindsvc, &aihint, &ailist)) != 0) { + die(EXIT_FAILURE, "couldn't resolve hostname %c%s%c, port `%s': %s", + bindhost ? '`' : '<', + bindhost ? bindhost : "nil", + bindhost ? '\'' : '>', + bindsvc, gai_strerror(err)); + } + + if (chdir(dir)) { + die(EXIT_FAILURE, "can't set current directory to `%s': %s", + dir, strerror(errno)); + } + + rand_noisesrc(RAND_GLOBAL, &noise_source); + rand_seed(RAND_GLOBAL, MAXHASHSZ); + + lp_init(); + + if (!(f & f_daemon)) { + af = AF_WARN; +#ifndef NTRACE + af |= AF_TRACE; +#endif + if (f & f_foreground) + af |= AF_FOREGROUND; + a_create(STDIN_FILENO, STDOUT_FILENO, af); + a_switcherr(); + } + + p_init(); + for (i = 0; i < N(tunnels); i++) + p_addtun(tunnels[i]); + if (dflt) p_setdflttun(dflt); + p_bind(ailist); freeaddrinfo(ailist); + + for (i = 0; tunnels[i]; i++) { + if (tunnels[i]->flags&TUNF_PRIVOPEN) { + ps_split(f & f_daemon); + break; + } + } + + a_init(); + a_signals(); + a_listen(csock, u, g, csockmode); + u_setugid(u, g); + km_init(kr_priv, kr_pub, tag_priv); + kx_init(); + if (f & f_daemon) { + if (daemonize()) { + a_warn("SERVER", "daemon-error", "?ERRNO", A_END); + exit(EXIT_FAILURE); + } + a_daemon(); + a_switcherr(); + } + + lp_run(); + + p_destroyall(); + p_unbind(); + a_unlisten(); + km_clear(); + ps_quit(); + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/server/test.c b/server/test.c index db98e37e..152a6fe6 100644 --- a/server/test.c +++ b/server/test.c @@ -90,11 +90,6 @@ static const char *getarg(void) static void lastarg(void) { if (*args) die(2, "unexpected argument `%s'", *args); } -void iv_addreason(void) { ; } -void iv_rmreason(void) { ; } - -void lp_end(void) { ; } - int main(int argc, char *argv[]) { const char *kr = "keyring"; diff --git a/server/tripe.c b/server/tripe.c index 637400a5..e4e4e6a2 100644 --- a/server/tripe.c +++ b/server/tripe.c @@ -114,8 +114,6 @@ void iv_rmreason(void) void lp_init(void) { - rand_noisesrc(RAND_GLOBAL, &noise_source); - rand_seed(RAND_GLOBAL, MAXHASHSZ); gettimeofday(&iv_next, 0); iv_next.tv_sec += T_INTERVAL; signal(SIGPIPE, SIG_IGN); sel_init(&sel); @@ -163,297 +161,4 @@ int lp_run(void) return (0); } -/*----- Tunnel table ------------------------------------------------------*/ - -static const tunnel_ops *tunnels[] = { -#ifdef TUN_LINUX - &tun_linux, -#endif -#ifdef TUN_BSD - &tun_bsd, -#endif -#ifdef TUN_UNET - &tun_unet, -#endif - &tun_slip, -}; - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @main@ --- * - * - * Arguments: @int argc@ = number of command line arguments - * @char *argv[]@ = vector of arguments - * - * Returns: Zero if OK, nonzero on error. - * - * Use: Main program. Provides a simple VPN. - */ - -static void usage(FILE *fp) -{ - pquis(fp, "Usage: $ [-DF] [-d DIR] [-b ADDR] [-p PORT] [-n TUNNEL]\n\ - [-U USER] [-G GROUP] [-a SOCKET] [-m MODE] [-T TRACE-OPTS]\n\ - [-k PRIV-KEYRING] [-K PUB-KEYRING] [-t KEY-TAG]\n"); -} - -static void version(FILE *fp) { pquis(fp, "$, version " VERSION "\n"); } - -static void help(FILE *fp) -{ - version(fp); - fputc('\n', fp); - usage(fp); - fputs("\n\ -Options:\n\ -\n\ --h, --help Display this help text.\n\ --v, --version Display version number.\n\ --u, --usage Display pointless usage message.\n\ - --tunnels Display IP tunnel drivers and exit.\n\ -\n\ --4, --ipv4 Transport over IPv4 only.\n\ --6, --ipv6 Transport over IPv6 only.\n\ --D, --daemon Run in the background.\n\ --F, --foreground Quit when stdin reports end-of-file.\n\ --d, --directory=DIR Switch to directory DIR [default " CONFIGDIR "].\n\ --b, --bind-address=ADDR Bind UDP socket to this IP ADDR.\n\ --p, --port=PORT Select UDP port to listen to " - "[default " STR(TRIPE_PORT) "].\n\ --n, --tunnel=TUNNEL Seelect default tunnel driver.\n\ --U, --setuid=USER Set uid to USER after initialization.\n\ --G, --setgid=GROUP Set gid to GROUP after initialization.\n\ --k, --priv-keyring=FILE Get private key from FILE.\n\ --K, --pub-keyring=FILE Get public keys from FILE.\n\ --t, --tag=KEYTAG Use private key labelled TAG.\n\ --a, --admin-socket=FILE Use FILE as the adminstration socket.\n\ --m, --admin-perms=MODE Permissions to set on admin socket [default 600].\n\ -" T( "\ --T, --trace=OPTIONS Turn on tracing options.\n\ -" ) "\ -", fp); -} - -int main(int argc, char *argv[]) -{ - const char *kr_priv = "keyring", *kr_pub = "keyring.pub"; - const char *tag_priv = 0; - const char *csock = SOCKETDIR "/tripesock"; - int csockmode = 0600; - const char *dir = CONFIGDIR; - const char *p; - const char *bindhost = 0, *bindsvc = STR(TRIPE_PORT); - struct addrinfo aihint = { 0 }, *ailist; - const tunnel_ops *dflt = 0; - unsigned f = 0; - int i; - int err; - unsigned af; - uid_t u = -1; - gid_t g = -1; - -#define f_bogus 1u -#define f_daemon 2u -#define f_foreground 4u - - ego(argv[0]); - T( trace_on(stderr, 0); ) - - if ((p = getenv("TRIPEDIR")) != 0) - dir = p; - if ((p = getenv("TRIPESOCK")) != 0) - csock = p; - aihint.ai_family = AF_UNSPEC; - - for (;;) { - static const struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'v' }, - { "usage", 0, 0, 'u' }, - { "tunnels", 0, 0, '0' }, - - { "ipv4", 0, 0, '4' }, - { "ipv6", 0, 0, '6' }, - { "daemon", 0, 0, 'D' }, - { "foreground", 0, 0, 'F' }, - { "uid", OPTF_ARGREQ, 0, 'U' }, - { "setuid", OPTF_ARGREQ, 0, 'U' }, - { "gid", OPTF_ARGREQ, 0, 'G' }, - { "setgid", OPTF_ARGREQ, 0, 'G' }, - { "bind-address", OPTF_ARGREQ, 0, 'b' }, - { "tunnel", OPTF_ARGREQ, 0, 'n' }, - { "port", OPTF_ARGREQ, 0, 'p' }, - { "directory", OPTF_ARGREQ, 0, 'd' }, - { "priv-keyring", OPTF_ARGREQ, 0, 'k' }, - { "pub-keyring", OPTF_ARGREQ, 0, 'K' }, - { "tag", OPTF_ARGREQ, 0, 't' }, - { "admin-socket", OPTF_ARGREQ, 0, 'a' }, - { "admin-perms", OPTF_ARGREQ, 0, 'm' }, -#ifndef NTRACE - { "trace", OPTF_ARGREQ, 0, 'T' }, -#endif - - { 0, 0, 0, 0 } - }; - - i = mdwopt(argc, argv, "hvu46DFU:G:b:n:p:d:k:K:t:a:m:" T("T:"), - opts, 0, 0, 0); - if (i < 0) - break; - switch (i) { - case 'h': - help(stdout); - exit(0); - case 'v': - version(stdout); - exit(0); - case 'u': - usage(stdout); - exit(0); - - case '4': - aihint.ai_family = AF_INET; - break; - case '6': - aihint.ai_family = AF_INET6; - break; - case 'D': - f |= f_daemon; - break; - case 'U': - u = u_getuser(optarg, &g); - break; - case 'G': - g = u_getgroup(optarg); - break; - case 'F': - f |= f_foreground; - break; - - case 'b': - bindhost = optarg; - break; - case 'p': - bindsvc = optarg; - break; - case 'n': { - int i; - for (i = 0; i < N(tunnels); i++) - if (mystrieq(optarg, tunnels[i]->name)) - { dflt = tunnels[i]; goto found_tun; } - die(EXIT_FAILURE, "unknown tunnel `%s'", optarg); - found_tun:; - } break; - case 'd': - dir = optarg; - break; - case 'k': - kr_priv = optarg; - break; - case 'K': - kr_pub = optarg; - break; - case 'a': - csock = optarg; - break; - case 'm': { - char *p; - csockmode = strtol(optarg, &p, 8); - if (*p) die(EXIT_FAILURE, "bad permissions: `%s'", optarg); - } break; - case 't': - tag_priv = optarg; - break; -#ifndef NTRACE - case 'T': - tr_flags = traceopt(tr_opts, optarg, tr_flags, 0); - trace_level(tr_flags); - break; -#endif - case '0': { - int i; - for (i = 0; i < N(tunnels); i++) - puts(tunnels[i]->name); - exit(0); - } break; - default: - f |= f_bogus; - break; - } - } - - if (optind < argc || (f & f_bogus)) { - usage(stderr); - exit(EXIT_FAILURE); - } - if (!(~f & (f_daemon | f_foreground))) - die(EXIT_FAILURE, "foreground operation for a daemon is silly"); - - aihint.ai_protocol = IPPROTO_UDP; - aihint.ai_socktype = SOCK_DGRAM; - aihint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; - if ((err = getaddrinfo(bindhost, bindsvc, &aihint, &ailist)) != 0) { - die(EXIT_FAILURE, "couldn't resolve hostname %c%s%c, port `%s': %s", - bindhost ? '`' : '<', - bindhost ? bindhost : "nil", - bindhost ? '\'' : '>', - bindsvc, gai_strerror(err)); - } - - if (chdir(dir)) { - die(EXIT_FAILURE, "can't set current directory to `%s': %s", - dir, strerror(errno)); - } - - lp_init(); - - if (!(f & f_daemon)) { - af = AF_WARN; -#ifndef NTRACE - af |= AF_TRACE; -#endif - if (f & f_foreground) - af |= AF_FOREGROUND; - a_create(STDIN_FILENO, STDOUT_FILENO, af); - a_switcherr(); - } - - p_init(); - for (i = 0; i < N(tunnels); i++) - p_addtun(tunnels[i]); - if (dflt) p_setdflttun(dflt); - p_bind(ailist); freeaddrinfo(ailist); - - for (i = 0; tunnels[i]; i++) { - if (tunnels[i]->flags&TUNF_PRIVOPEN) { - ps_split(f & f_daemon); - break; - } - } - - a_init(); - a_signals(); - a_listen(csock, u, g, csockmode); - u_setugid(u, g); - km_init(kr_priv, kr_pub, tag_priv); - kx_init(); - if (f & f_daemon) { - if (daemonize()) { - a_warn("SERVER", "daemon-error", "?ERRNO", A_END); - exit(EXIT_FAILURE); - } - a_daemon(); - a_switcherr(); - } - - lp_run(); - - p_destroyall(); - p_unbind(); - a_unlisten(); - km_clear(); - ps_quit(); - return (0); -} - /*----- That's all, folks -------------------------------------------------*/ -- [mdw]