diff options
| author | Felix Fietkau | 2024-12-15 15:19:19 +0000 |
|---|---|---|
| committer | Felix Fietkau | 2024-12-15 18:47:04 +0000 |
| commit | f335f5b40b4ec0b741616d6758aa117183335626 (patch) | |
| tree | 579cb797ad8f24115d215cfe75a5b54d5a067201 | |
| parent | b58920d420cbe523a23932a7a844453a222d629d (diff) | |
| download | unetd-f335f5b40b4ec0b741616d6758aa117183335626.tar.gz | |
unet-cli: add support for generating key from seed
When using a seed passphrase, the key is not stored. Instead, the create and
sign operation will ask for the password.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
| -rwxr-xr-x | scripts/unet-cli | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/scripts/unet-cli b/scripts/unet-cli index 8ab2594..600c332 100755 --- a/scripts/unet-cli +++ b/scripts/unet-cli @@ -1,7 +1,7 @@ #!/usr/bin/env ucode 'use strict'; -import { access, basename, dirname, mkstemp, open, writefile, popen } from 'fs'; +import { access, basename, dirname, mkstemp, open, readfile, writefile, popen } from 'fs'; function assert(cond, message) { if (!cond) { @@ -50,6 +50,7 @@ const usage_message = `Usage: ${basename(sourcepath())} [<flags>] <file> <comman port=<val> set tunnel port (default: ${defaults.port}) pex_port=<val> set peer-exchange port (default: ${defaults.pex_port}, 0: disabled) keepalive=<val> set keepalive interval (seconds, 0: off, default: ${defaults.keepalive}) + seed[=<rounds>] create network private key from seed passphrase stun=[+|-]<host:port>[,<host:port>...] set/add/remove STUN servers - host options (add-host, add-ssh-host, set-host): key=<val> set host public key (required for add-host) @@ -188,9 +189,8 @@ let print_only = false; function fetch_args() { for (let arg in ARGV) { - let vals = match(arg, /^(.[[:alnum:]_-]*)=(.*)$/); - assert(vals, `Invalid argument: ${arg}`); - args[vals[1]] = vals[2] + let vals = split(arg, "=", 2); + args[vals[0]] = vals[1]; } } @@ -239,6 +239,15 @@ function set_service(service) { set_fields(service.config, service_field_types[service.type]); } +function key_arg(file, net_data) { + let rounds = net_data.config.rounds; + let salt = net_data.config.salt; + if (salt && rounds > 0) + return `-p -s ${rounds},${salt}`; + + return `-K ${file}.key`; +} + function sync_ssh_host(host) { let interface = args.interface ?? "unet"; let connect = replace(args.connect ?? "", ",", " "); @@ -348,23 +357,21 @@ if (command == "create") { } } -if (command == "create") { - for (let key, val in defaults) - args[key] ??= `${val}`; - if (!access(`${file}.key`)) - system(`${unet_tool} -G > ${file}.key`); - net_data.config.id = trim(popen(`unet-tool -P -K ${file}.key`).read("all")); -} - if (command == "sign") { - let ret = system(`${unet_tool} -S -K ${file}.key -o ${file}.bin ${file}`); + let ret = system(`${unet_tool} -S ${key_arg(file, net_data)} -o ${file}.bin ${file}`); if (ret != 0) exit(ret); + let pubkey = trim(popen(`unet-tool -b ${file}.bin -P`).read("all")); + if (pubkey != net_data.config.id) { + warn(`Signing key '${pubkey}' does not match network key '${net_data.config.id}'`); + exit(1); + } + if (args.upload) { for (let host in split(args.upload, ",")) { warn(`Uploading ${file}.bin to ${host}\n`); - ret = system(`${unet_tool} -U ${host} -K ${file}.key ${file}.bin`); + ret = system(`${unet_tool} -U ${host} ${file}.bin`); if (ret) warn("Upload failed\n"); } @@ -381,6 +388,34 @@ case 'set-config': }); set_field("int", net_data.config, "peer-exchange-port", args.pex_port); set_field("array", net_data.config, "stun-servers", args.stun); + + for (let key, val in defaults) + args[key] ??= `${val}`; + + let seed_arg; + + if ("seed" in args) { + let salt = readfile("/dev/urandom", 16); + salt = map(split(salt, ""), (v) => ord(v)); + salt = join("", map(salt, (v) => sprintf("%02x", v))); + net_data.config.salt = salt; + net_data.config.rounds = int(args.seed ?? 10000); + delete net_data.config.id; + seed_arg = true; + } + + if (!access(`${file}.key`) && !seed_arg && + system(`${unet_tool} -G -o ${file}.key`)) { + warn("Failed to generate key\n"); + exit(1); + } + + if (!net_data.config.id) { + net_data.config.id = trim(popen(`unet-tool -P ${key_arg(file, net_data)}`).read("all")); + if (!net_data.config.id) + exit(1); + } + break; case 'add-host': |