#include "subnet.h"
#include "keys.h"
#include "random.h"
+#include "sandbox.h"
#include "pidfile.h"
#include "console.h"
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
#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"
"\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"
" 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);
}
}
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;
}
static void sigint_handler(int sig) {
(void)sig;
- fprintf(stderr, "\n");
+ if(write(2, "\n", 1) < 0) {
+ // nothing we can do
+ }
+
shutdown(fd, SHUT_RDWR);
}
#endif
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;
{"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},
char filename[PATH_MAX];
if(node) {
- if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node) >= sizeof(filename)) {
- fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, node);
- free(node);
- return 1;
- }
+ size_t wrote = (size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node);
if(node != line) {
free(node);
node = NULL;
}
+
+ if(wrote >= sizeof(filename)) {
+ fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, node);
+ return 1;
+ }
+
} else {
snprintf(filename, sizeof(filename), "%s", tinc_conf);
}
crypto_init();
prng_init();
+ sandbox_set_level(SANDBOX_NORMAL);
+ sandbox_enter();
+
int result = run_command(argc, argv);
random_exit();