Add basic pledge/unveil sandbox on OpenBSD
[tinc] / src / tincctl.c
index a882a66..a0a0281 100644 (file)
@@ -41,6 +41,7 @@
 #include "subnet.h"
 #include "keys.h"
 #include "random.h"
+#include "sandbox.h"
 #include "pidfile.h"
 #include "console.h"
 
@@ -80,19 +81,35 @@ char *device = NULL;
 char *iface = NULL;
 int debug_level = -1;
 
+typedef enum option_t {
+       OPT_BAD_OPTION  = '?',
+       OPT_LONG_OPTION =  0,
+
+       // Short options
+       OPT_BATCH       = 'b',
+       OPT_CONFIG_FILE = 'c',
+       OPT_NETNAME     = 'n',
+
+       // Long options
+       OPT_HELP        = 255,
+       OPT_VERSION,
+       OPT_PIDFILE,
+       OPT_FORCE,
+} option_t;
+
 static struct option const long_options[] = {
-       {"batch", no_argument, NULL, 'b'},
-       {"config", required_argument, NULL, 'c'},
-       {"net", required_argument, NULL, 'n'},
-       {"help", no_argument, NULL, 1},
-       {"version", no_argument, NULL, 2},
-       {"pidfile", required_argument, NULL, 3},
-       {"force", no_argument, NULL, 4},
-       {NULL, 0, NULL, 0}
+       {"batch",   no_argument,       NULL, OPT_BATCH},
+       {"config",  required_argument, NULL, OPT_CONFIG_FILE},
+       {"net",     required_argument, NULL, OPT_NETNAME},
+       {"help",    no_argument,       NULL, OPT_HELP},
+       {"version", no_argument,       NULL, OPT_VERSION},
+       {"pidfile", required_argument, NULL, OPT_PIDFILE},
+       {"force",   no_argument,       NULL, OPT_FORCE},
+       {NULL,      0,                 NULL, 0},
 };
 
 static void version(void) {
-       static const char *message =
+       fprintf(stdout,
                "%s version %s (built %s %s, protocol %d.%d)\n"
                "Features:"
 #ifdef HAVE_READLINE
@@ -103,6 +120,9 @@ static void version(void) {
 #endif
 #ifndef DISABLE_LEGACY
                " legacy_protocol"
+#endif
+#ifdef HAVE_SANDBOX
+               " sandbox"
 #endif
                "\n\n"
                "Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
@@ -110,16 +130,15 @@ static void version(void) {
                "\n"
                "tinc comes with ABSOLUTELY NO WARRANTY.  This is free software,\n"
                "and you are welcome to redistribute it under certain conditions;\n"
-               "see the file COPYING for details.\n";
-
-       printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
+               "see the file COPYING for details.\n",
+               PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
 }
 
 static void usage(bool status) {
        if(status) {
                fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
        } else {
-               static const char *message =
+               fprintf(stdout,
                        "Usage: %s [options] command\n"
                        "\n"
                        "Valid options are:\n"
@@ -178,9 +197,8 @@ static void usage(bool status) {
                        "  sign [FILE]                Generate a signed version of a file.\n"
                        "  verify NODE [FILE]         Verify that a file was signed by the given NODE.\n"
                        "\n"
-                       "Report bugs to tinc@tinc-vpn.org.\n";
-
-               printf(message, program_name);
+                       "Report bugs to tinc@tinc-vpn.org.\n",
+                       program_name);
        }
 }
 
@@ -189,47 +207,47 @@ static bool parse_options(int argc, char **argv) {
        int option_index = 0;
 
        while((r = getopt_long(argc, argv, "+bc:n:", long_options, &option_index)) != EOF) {
-               switch(r) {
-               case 0:   /* long option */
+               switch((option_t) r) {
+               case OPT_LONG_OPTION:
                        break;
 
-               case 'b':
+               case OPT_BAD_OPTION:
+                       usage(true);
+                       free_names();
+                       return false;
+
+               case OPT_BATCH:
                        tty = false;
                        break;
 
-               case 'c': /* config file */
+               case OPT_CONFIG_FILE:
                        free(confbase);
                        confbase = xstrdup(optarg);
                        confbasegiven = true;
                        break;
 
-               case 'n': /* net name given */
+               case OPT_NETNAME:
                        free(netname);
                        netname = xstrdup(optarg);
                        break;
 
-               case 1:   /* show help */
+               case OPT_HELP:
                        show_help = true;
                        break;
 
-               case 2:   /* show version */
+               case OPT_VERSION:
                        show_version = true;
                        break;
 
-               case 3:   /* open control socket here */
+               case OPT_PIDFILE:
                        free(pidfilename);
                        pidfilename = xstrdup(optarg);
                        break;
 
-               case 4:   /* force */
+               case OPT_FORCE:
                        force = true;
                        break;
 
-               case '?': /* wrong options */
-                       usage(true);
-                       free_names();
-                       return false;
-
                default:
                        break;
                }
@@ -1607,7 +1625,8 @@ char *get_my_name(bool verbose) {
        return NULL;
 }
 
-ecdsa_t *get_pubkey(FILE *f) {
+static ecdsa_t *get_pubkey(FILE *f) ATTR_MALLOC ATTR_DEALLOCATOR(ecdsa_free);
+static ecdsa_t *get_pubkey(FILE *f) {
        char buf[4096];
        char *value;
 
@@ -1680,6 +1699,7 @@ const var_t variables[] = {
        {"ProcessPriority", VAR_SERVER},
        {"Proxy", VAR_SERVER},
        {"ReplayWindow", VAR_SERVER | VAR_SAFE},
+       {"Sandbox", VAR_SERVER},
        {"ScriptsExtension", VAR_SERVER},
        {"ScriptsInterpreter", VAR_SERVER},
        {"StrictSubnets", VAR_SERVER | VAR_SAFE},
@@ -3335,6 +3355,9 @@ int main(int argc, char *argv[]) {
        crypto_init();
        prng_init();
 
+       sandbox_set_level(SANDBOX_NORMAL);
+       sandbox_enter();
+
        int result = run_command(argc, argv);
 
        random_exit();