Add listen mode

Close %ejwI9899mEhcIezmWQUKrubKHEfNaFpkmVVG6xOpUsY=.sha256
main
cel 5 years ago
parent cfb1d40d73
commit 14900624cc

@ -31,9 +31,13 @@ uninstall:
$(DESTDIR)$(BINDIR)/$(BIN) \ $(DESTDIR)$(BINDIR)/$(BIN) \
$(DESTDIR)$(MANDIR)/man1/$(BIN).1 $(DESTDIR)$(MANDIR)/man1/$(BIN).1
test-shs1: test-shs1: test-shs1-client test-shs1-server
@# %lzzcAZlM21slUIoiH4yd/wgDnXu8raNLvwqjxqrU06k=.sha256
shs1testclient ./test-shs-inner.sh $(SHS1_TEST_SEED) test-shs1-client:
shs1testclient ./test-shs-client-inner.sh $(SHS1_TEST_SEED)
test-shs1-server:
shs1testserver ./test-shs-server-inner.sh $(SHS1_TEST_SEED)
clean: clean:
@rm -vf $(BIN) @rm -vf $(BIN)

@ -30,6 +30,7 @@
| |
.Fl 6 .Fl 6
.Oc .Oc
.Op Fl d
| |
.Op Fl u Ar socket_path .Op Fl u Ar socket_path
.Oc .Oc
@ -56,8 +57,7 @@ Raw mode. Disables stdin line buffering/editing and echoing. Implies
.It Fl e .It Fl e
Encode arguments as strings, rather than expecting them to be JSON-encoded. Encode arguments as strings, rather than expecting them to be JSON-encoded.
.It Fl T .It Fl T
Test using shs1-testsuite protocol. Instead of connecting to a server and running Test using shs1-testsuite protocol. Instead of connecting to a peer and calling a RPC method, connect to stdio. On successful handshake, output concatenation of
a command, connect to stdio. On successful handshake, output concatenation of
the encryption key, encryption nonce, decryption key and decryption nonce. the encryption key, encryption nonce, decryption key and decryption nonce.
.It Fl a .It Fl a
Passthrough mode. Instead of making a muxrpc call, pass through the box-stream Passthrough mode. Instead of making a muxrpc call, pass through the box-stream
@ -74,6 +74,8 @@ options have no effect and output a warning if used.
Connect to server over IPv4 only. Connect to server over IPv4 only.
.It Fl 6 .It Fl 6
Connect to server over IPv6 only. Connect to server over IPv6 only.
.It Fl d
Listen for an incoming connection instead of making an outgoing connection.
.It Fl c Ar cap .It Fl c Ar cap
Capability key for secret-handshake. Default is SSB's capability key, Capability key for secret-handshake. Default is SSB's capability key,
.Li 1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s= . .Li 1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s= .
@ -90,7 +92,13 @@ and
.Fl s . .Fl s .
.It Fl k Ar key .It Fl k Ar key
The key to connect to. Default is your public key, as read from your The key to connect to. Default is your public key, as read from your
private key file. private key file or the
.Fl K
option. In listen mode (
.Fl d
), if
.Fl k
is specified, only a connection from the given key is accepted; otherwise a connection from any key is accepted.
.It Fl K Ar keypair .It Fl K Ar keypair
Private key or private key seed to use for secret-handshake. Default is to use the private key Private key or private key seed to use for secret-handshake. Default is to use the private key
from your from your

@ -17,6 +17,7 @@
#include <limits.h> #include <limits.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -116,7 +117,7 @@ static void reset_termios() {
static void usage() { static void usage() {
fputs("usage: sbotc [-j] [-T] [-l] [-r] [-e]\n" fputs("usage: sbotc [-j] [-T] [-l] [-r] [-e]\n"
" [ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]\n" " [ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]\n"
" [ [-s <host>] [-p <port>] [ -4 | -6 ] | [-u <socket_path>] ]\n" " [ [-s <host>] [-p <port>] [ -4 | -6 ] [-d] | [-u <socket_path>] ]\n"
" [ -a | [-t <type>] <method> [<argument>...] ]\n", stderr); " [ -a | [-t <type>] <method> [<argument>...] ]\n", stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -156,16 +157,17 @@ static int connect_localhost(const char *port, enum ip_family ip_family) {
return fd; return fd;
} }
static int tcp_connect(const char *host, const char *port, enum ip_family ip_family) { static int tcp_connect(const char *host, const char *port, enum ip_family ip_family, bool server) {
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *result, *rp; struct addrinfo *result, *rp;
int s; int s;
int fd; int fd;
int err; int err, rc;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = ip_family; hints.ai_family = ip_family;
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
if (server) hints.ai_flags = AI_PASSIVE;
s = getaddrinfo(host, port, &hints, &result); s = getaddrinfo(host, port, &hints, &result);
if (s < 0) errx(1, "unable to resolve host: %s", gai_strerror(s)); if (s < 0) errx(1, "unable to resolve host: %s", gai_strerror(s));
@ -173,7 +175,15 @@ static int tcp_connect(const char *host, const char *port, enum ip_family ip_fam
for (rp = result; rp; rp = rp->ai_next) { for (rp = result; rp; rp = rp->ai_next) {
fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (fd < 0) continue; if (fd < 0) continue;
if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) break; if (server) {
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));
if (rc < 0) goto error;
if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0) goto error;
if (listen(fd, 1) == 0) break;
} else {
if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) break;
}
error:
err = errno; err = errno;
close(fd); close(fd);
errno = err; errno = err;
@ -182,14 +192,31 @@ static int tcp_connect(const char *host, const char *port, enum ip_family ip_fam
freeaddrinfo(result); freeaddrinfo(result);
if (fd == -1 && errno == ECONNREFUSED && (host == NULL || !strcmp(host, "localhost"))) { if (!server && fd == -1 && errno == ECONNREFUSED && (host == NULL || !strcmp(host, "localhost"))) {
return connect_localhost(port, ip_family); return connect_localhost(port, ip_family);
} }
if (server && fd > -1) {
int client = accept(fd, NULL, NULL);
err = errno;
close(fd);
errno = err;
return client;
}
return fd; return fd;
} }
static int unix_connect(const char *path) { static const char *socket_path = NULL;
void cleanup() {
if (socket_path != NULL) {
int rc = unlink(socket_path);
if (rc < 0) warn("unlink");
}
}
static int unix_connect(const char *path, bool server) {
struct sockaddr_un name; struct sockaddr_un name;
const size_t path_len = strlen(path); const size_t path_len = strlen(path);
int s, rc; int s, rc;
@ -199,18 +226,38 @@ static int unix_connect(const char *path) {
memset(&name, 0, sizeof(struct sockaddr_un)); memset(&name, 0, sizeof(struct sockaddr_un));
name.sun_family = AF_UNIX; name.sun_family = AF_UNIX;
strncpy(name.sun_path, path, sizeof(name.sun_path) - 1); strncpy(name.sun_path, path, sizeof(name.sun_path) - 1);
rc = connect(s, (const struct sockaddr *)&name, sizeof name); if (server) {
rc = bind(s, (const struct sockaddr *)&name, sizeof name);
if (rc < 0) return -1;
rc = listen(s, 1);
} else {
rc = connect(s, (const struct sockaddr *)&name, sizeof name);
}
if (rc < 0) return -1; if (rc < 0) return -1;
if (server && rc > -1) {
socket_path = strdup(path);
if (atexit(cleanup) < 0) warn("atexit");
if (signal(SIGINT, exit) == SIG_ERR) warn("signal");
int client = accept(s, NULL, NULL);
int err = errno;
close(s);
errno = err;
return client;
}
return s; return s;
} }
static int get_socket_path(char *buf, size_t len, const char *app_dir) { static int get_socket_path(char *buf, size_t len, const char *app_dir, bool server) {
struct stat st; struct stat st;
int sz = snprintf(buf, len-1, "%s/%s", app_dir, "socket"); int sz = snprintf(buf, len-1, "%s/%s", app_dir, "socket");
if (sz < 0 || sz >= (int)len-1) err(1, "failed to get socket path"); if (sz < 0 || sz >= (int)len-1) err(1, "failed to get socket path");
int rc = stat(buf, &st); int rc = stat(buf, &st);
if (rc < 0) return -1; if (!server) {
if (!(st.st_mode & S_IFSOCK)) { errno = EINVAL; return -1; } if (rc < 0) return -1;
if (!(st.st_mode & S_IFSOCK)) { errno = EINVAL; return -1; }
}
return 0; return 0;
} }
@ -249,121 +296,226 @@ static int write_all(int fd, const void *buf, size_t count) {
return 0; return 0;
} }
static void shs_connect(int sfd, int infd, int outfd, const unsigned char pubkey[32], const unsigned char seckey[64], const unsigned char appkey[32], const unsigned char server_pubkey[32], struct boxs *bs) { static void shs_connect(int sfd, int infd, int outfd, const unsigned char pubkey[32], const unsigned char seckey[64], const unsigned char appkey[32], const unsigned char remote_pubkey[32], struct boxs *bs, bool client, bool specify_client_key) {
int rc; int rc;
unsigned char client_pubkey[32];
unsigned char local_app_mac[32], remote_app_mac[32]; unsigned char local_app_mac[32], remote_app_mac[32];
unsigned char kx_pk[32], kx_sk[32], remote_kx_pk[32];
unsigned char buf[64];
unsigned char kx_pk[32], kx_sk[32]; if (client) {
rc = crypto_box_keypair(kx_pk, kx_sk); rc = crypto_box_keypair(kx_pk, kx_sk);
if (rc < 0) errx(1, "failed to generate auth keypair"); if (rc < 0) errx(1, "failed to generate auth keypair");
rc = crypto_auth(local_app_mac, kx_pk, 32, appkey); rc = crypto_auth(local_app_mac, kx_pk, 32, appkey);
if (rc < 0) err(1, "failed to generate app mac"); if (rc < 0) err(1, "failed to generate app mac");
// send challenge // send challenge
unsigned char buf[64]; memcpy(buf, local_app_mac, 32);
memcpy(buf, local_app_mac, 32); memcpy(buf+32, kx_pk, 32);
memcpy(buf+32, kx_pk, 32); rc = write_all(outfd, buf, sizeof(buf));
rc = write_all(outfd, buf, sizeof(buf)); if (rc < 0) err(1, "failed to send challenge");
if (rc < 0) err(1, "failed to send challenge");
// recv challenge
unsigned char remote_kx_pk[32];
rc = read_all(infd, buf, sizeof(buf));
if (rc < 0) err(1, "challenge not accepted");
memcpy(remote_app_mac, buf, 32);
memcpy(remote_kx_pk, buf+32, 32);
rc = crypto_auth_verify(buf, remote_kx_pk, 32, appkey);
if (rc < 0) errx(1, "wrong protocol (version?)");
// send auth
unsigned char secret[32]; } else {
rc = crypto_scalarmult(secret, kx_sk, remote_kx_pk); // recv challenge
if (rc < 0) errx(1, "failed to derive shared secret"); rc = read_all(infd, buf, sizeof(buf));
if (rc < 0) err(1, "expected challenge");
memcpy(remote_app_mac, buf, 32);
memcpy(remote_kx_pk, buf+32, 32);
unsigned char remote_pk_curve[32]; rc = crypto_auth_verify(buf, remote_kx_pk, 32, appkey);
rc = crypto_sign_ed25519_pk_to_curve25519(remote_pk_curve, server_pubkey); if (rc < 0) errx(1, "wrong protocol/version");
if (rc < 0) errx(1, "failed to curvify remote public key");
unsigned char a_bob[32]; }
rc = crypto_scalarmult(a_bob, kx_sk, remote_pk_curve);
if (rc < 0) errx(1, "failed to derive a_bob");
unsigned char secret2a[96]; if (client) {
memcpy(secret2a, appkey, 32); // recv challenge
memcpy(secret2a+32, secret, 32); rc = read_all(infd, buf, sizeof(buf));
memcpy(secret2a+64, a_bob, 32); if (rc < 0) err(1, "challenge not accepted");
memcpy(remote_app_mac, buf, 32);
memcpy(remote_kx_pk, buf+32, 32);
rc = crypto_auth_verify(buf, remote_kx_pk, 32, appkey);
if (rc < 0) errx(1, "wrong protocol (version?)");
unsigned char secret2[32]; } else {
rc = crypto_hash_sha256(secret2, secret2a, sizeof(secret2a)); rc = crypto_box_keypair(kx_pk, kx_sk);
if (rc < 0) errx(1, "failed to hash secret2"); if (rc < 0) errx(1, "failed to generate auth keypair");
unsigned char shash[32]; rc = crypto_auth(local_app_mac, kx_pk, 32, appkey);
rc = crypto_hash_sha256(shash, secret, sizeof(secret)); if (rc < 0) err(1, "failed to generate app mac");
if (rc < 0) errx(1, "failed to hash secret");
unsigned char signed1[96]; // send challenge
memcpy(signed1, appkey, 32); memcpy(buf, local_app_mac, 32);
memcpy(signed1+32, server_pubkey, 32); memcpy(buf+32, kx_pk, 32);
memcpy(signed1+64, shash, 32); rc = write_all(outfd, buf, sizeof(buf));
if (rc < 0) err(1, "failed to send challenge");
unsigned char sig[64]; }
rc = crypto_sign_detached(sig, NULL, signed1, sizeof(signed1), seckey);
if (rc < 0) errx(1, "failed to sign inner hello");
unsigned char remote_pk_curve[32];
unsigned char hello[96]; unsigned char hello[96];
memcpy(hello, sig, 64); unsigned char secret2[32];
memcpy(hello+64, pubkey, 32);
unsigned char boxed_auth[112]; unsigned char boxed_auth[112];
rc = crypto_secretbox_easy(boxed_auth, hello, sizeof(hello), zeros, secret2); unsigned char secret[32];
if (rc < 0) errx(1, "failed to box hello"); unsigned char a_bob[32];
unsigned char secret2a[96];
unsigned char shash[32];
unsigned char sig[64];
unsigned char signed1[96];
unsigned char local_sk_curve[32];
if (client) {
// send auth
rc = write_all(outfd, boxed_auth, sizeof(boxed_auth)); rc = crypto_scalarmult(secret, kx_sk, remote_kx_pk);
if (rc < 0) errx(1, "failed to send auth"); if (rc < 0) errx(1, "failed to derive shared secret");
// verify accept rc = crypto_sign_ed25519_pk_to_curve25519(remote_pk_curve, remote_pubkey);
if (rc < 0) errx(1, "failed to curvify remote public key");
unsigned char boxed_okay[80]; rc = crypto_scalarmult(a_bob, kx_sk, remote_pk_curve);
rc = read_all(infd, boxed_okay, sizeof(boxed_okay)); if (rc < 0) errx(1, "failed to derive a_bob");
if (rc < 0) err(1, "hello not accepted");
unsigned char local_sk_curve[32]; memcpy(secret2a, appkey, 32);
rc = crypto_sign_ed25519_sk_to_curve25519(local_sk_curve, seckey); memcpy(secret2a+32, secret, 32);
if (rc < 0) errx(1, "failed to curvify local secret key"); memcpy(secret2a+64, a_bob, 32);
unsigned char b_alice[32]; rc = crypto_hash_sha256(secret2, secret2a, sizeof(secret2a));
rc = crypto_scalarmult(b_alice, local_sk_curve, remote_kx_pk); if (rc < 0) errx(1, "failed to hash secret2");
if (rc < 0) errx(1, "failed to derive b_alice");
unsigned char secret3a[128]; rc = crypto_hash_sha256(shash, secret, sizeof(secret));
memcpy(secret3a, appkey, 32); if (rc < 0) errx(1, "failed to hash secret");
memcpy(secret3a+32, secret, 32);
memcpy(secret3a+64, a_bob, 32);
memcpy(secret3a+96, b_alice, 32);
unsigned char secret3[32]; unsigned char signed1[96];
rc = crypto_hash_sha256(secret3, secret3a, sizeof(secret3a)); memcpy(signed1, appkey, 32);
if (rc < 0) errx(1, "failed to hash secret3"); memcpy(signed1+32, remote_pubkey, 32);
memcpy(signed1+64, shash, 32);
rc = crypto_sign_detached(sig, NULL, signed1, sizeof(signed1), seckey);
if (rc < 0) errx(1, "failed to sign inner hello");
memcpy(hello, sig, 64);
memcpy(hello+64, pubkey, 32);
rc = crypto_secretbox_easy(boxed_auth, hello, sizeof(hello), zeros, secret2);
if (rc < 0) errx(1, "failed to box hello");
rc = write_all(outfd, boxed_auth, sizeof(boxed_auth));
if (rc < 0) errx(1, "failed to send auth");
} else {
// read auth
rc = read_all(infd, boxed_auth, sizeof(boxed_auth));
if (rc < 0) err(1, "expected hello");
rc = crypto_secretbox_open_easy(sig, boxed_okay, sizeof(boxed_okay), zeros, secret3); rc = crypto_scalarmult(secret, kx_sk, remote_kx_pk);
if (rc < 0) errx(1, "failed to unbox the okay"); if (rc < 0) errx(1, "failed to derive shared secret");
rc = crypto_hash_sha256(shash, secret, sizeof(secret));
if (rc < 0) errx(1, "failed to hash secret");
rc = crypto_sign_ed25519_sk_to_curve25519(local_sk_curve, seckey);
if (rc < 0) errx(1, "failed to curvify local secret key");
rc = crypto_scalarmult(a_bob, local_sk_curve, remote_kx_pk);
if (rc < 0) errx(1, "failed to derive a_bob");
memcpy(secret2a, appkey, 32);
memcpy(secret2a+32, secret, 32);
memcpy(secret2a+64, a_bob, 32);
rc = crypto_hash_sha256(secret2, secret2a, sizeof(secret2a));
if (rc < 0) errx(1, "failed to hash secret2");
rc = crypto_secretbox_open_easy(hello, boxed_auth, sizeof(boxed_auth), zeros, secret2);
if (rc < 0) errx(1, "failed to unbox client hello");
memcpy(sig, hello, 64);
memcpy(client_pubkey, hello+64, 32);
memcpy(signed1, appkey, 32);
memcpy(signed1+32, pubkey, 32);
memcpy(signed1+64, shash, 32);
rc = crypto_sign_verify_detached(sig, signed1, sizeof(signed1), client_pubkey);
if (rc < 0) errx(1, "wrong number");
}
unsigned char boxed_okay[80];
unsigned char b_alice[32];
unsigned char secret3a[128];
unsigned char secret3[32];
unsigned char signed2[160]; unsigned char signed2[160];
memcpy(signed2, appkey, 32); if (client) {
memcpy(signed2+32, hello, 96); // verify accept
memcpy(signed2+128, shash, 32);
rc = read_all(infd, boxed_okay, sizeof(boxed_okay));
if (rc < 0) err(1, "hello not accepted");
rc = crypto_sign_ed25519_sk_to_curve25519(local_sk_curve, seckey);
if (rc < 0) errx(1, "failed to curvify local secret key");
rc = crypto_scalarmult(b_alice, local_sk_curve, remote_kx_pk);
if (rc < 0) errx(1, "failed to derive b_alice");
rc = crypto_sign_verify_detached(sig, signed2, sizeof(signed2), server_pubkey); memcpy(secret3a, appkey, 32);
if (rc < 0) errx(1, "server not authenticated"); memcpy(secret3a+32, secret, 32);
memcpy(secret3a+64, a_bob, 32);
memcpy(secret3a+96, b_alice, 32);
rc = crypto_hash_sha256(secret3, secret3a, sizeof(secret3a));
if (rc < 0) errx(1, "failed to hash secret3");
rc = crypto_secretbox_open_easy(sig, boxed_okay, sizeof(boxed_okay), zeros, secret3);
if (rc < 0) errx(1, "failed to unbox the okay");
memcpy(signed2, appkey, 32);
memcpy(signed2+32, hello, 96);
memcpy(signed2+128, shash, 32);
rc = crypto_sign_verify_detached(sig, signed2, sizeof(signed2), remote_pubkey);
if (rc < 0) errx(1, "server not authenticated");
} else {
if (specify_client_key && memcmp(client_pubkey, remote_pubkey, 32)) {
errx(1, "unexpected client");
}
// send accept
rc = crypto_sign_ed25519_pk_to_curve25519(remote_pk_curve, client_pubkey);
if (rc < 0) errx(1, "failed to curvify remote public key");
rc = crypto_scalarmult(b_alice, kx_sk, remote_pk_curve);
if (rc < 0) errx(1, "failed to derive b_alice");
memcpy(secret3a, appkey, 32);
memcpy(secret3a+32, secret, 32);
memcpy(secret3a+64, a_bob, 32);
memcpy(secret3a+96, b_alice, 32);
rc = crypto_hash_sha256(secret3, secret3a, sizeof(secret3a));
if (rc < 0) errx(1, "failed to hash secret3");
memcpy(signed2, appkey, 32);
memcpy(signed2+32, hello, 96);
memcpy(signed2+128, shash, 32);
rc = crypto_sign_detached(sig, NULL, signed2, sizeof(signed2), seckey);
if (rc < 0) errx(1, "failed to sign inner accept");
rc = crypto_secretbox_easy(boxed_okay, sig, sizeof(sig), zeros, secret3);
if (rc < 0) errx(1, "failed to box accept");
rc = write_all(outfd, boxed_okay, sizeof(boxed_okay));
if (rc < 0) errx(1, "failed to send accept");
}
rc = crypto_hash_sha256(secret, secret3, 32); rc = crypto_hash_sha256(secret, secret3, 32);
if (rc < 0) errx(1, "failed to hash secret3"); if (rc < 0) errx(1, "failed to hash secret3");
unsigned char enc_key_hashed[64]; unsigned char enc_key_hashed[64];
memcpy(enc_key_hashed, secret, 32); memcpy(enc_key_hashed, secret, 32);
memcpy(enc_key_hashed+32, server_pubkey, 32); memcpy(enc_key_hashed+32, client ? remote_pubkey : client_pubkey, 32);
rc = crypto_hash_sha256(bs->encrypt_key, enc_key_hashed, 64); rc = crypto_hash_sha256(bs->encrypt_key, enc_key_hashed, 64);
if (rc < 0) errx(1, "failed to hash the encrypt key"); if (rc < 0) errx(1, "failed to hash the encrypt key");
@ -1056,6 +1208,7 @@ int main(int argc, char *argv[]) {
bool ipv6_arg = false; bool ipv6_arg = false;
bool passthrough = false; bool passthrough = false;
bool strings = false; bool strings = false;
bool daemon = false;
enum ip_family ip_family; enum ip_family ip_family;
get_app_dir(app_dir, sizeof(app_dir)); get_app_dir(app_dir, sizeof(app_dir));
@ -1089,6 +1242,7 @@ int main(int argc, char *argv[]) {
case 'n': noauth = true; break; case 'n': noauth = true; break;
case '4': ipv4_arg = true; break; case '4': ipv4_arg = true; break;
case '6': ipv6_arg = true; break; case '6': ipv6_arg = true; break;
case 'd': daemon = true; break;
case 'a': passthrough = true; break; case 'a': passthrough = true; break;
case 'l': no_newline = true; break; case 'l': no_newline = true; break;
case 'r': raw = true; no_newline = true; break; case 'r': raw = true; no_newline = true; break;
@ -1184,24 +1338,24 @@ int main(int argc, char *argv[]) {
} else if (socket_path) { } else if (socket_path) {
if (implied_tcp) errx(1, "-u option conflicts with host/port options"); if (implied_tcp) errx(1, "-u option conflicts with host/port options");
s = unix_connect(socket_path); s = unix_connect(socket_path, daemon);
if (s < 0) err(1, "unix_connect"); if (s < 0) err(1, "unix_connect");
infd = outfd = s; infd = outfd = s;
} else if (!implied_tcp && !implied_auth) { } else if (!implied_tcp && !implied_auth) {
char socket_path_buf[_POSIX_PATH_MAX]; char socket_path_buf[_POSIX_PATH_MAX];
rc = get_socket_path(socket_path_buf, sizeof(socket_path_buf), app_dir); rc = get_socket_path(socket_path_buf, sizeof(socket_path_buf), app_dir, daemon);
if (rc < 0 && noauth) err(1, "get_socket_path"); if (rc < 0 && noauth) err(1, "get_socket_path");
if (rc < 0) goto do_tcp_connect; if (rc < 0) goto do_tcp;
s = unix_connect(socket_path_buf); s = unix_connect(socket_path_buf, daemon);
if (s < 0 && noauth) err(1, "unix_connect"); if (s < 0 && noauth) err(1, "unix_connect");
if (s < 0) goto do_tcp_connect; if (s < 0) goto do_tcp;
noauth = true; noauth = true;
infd = outfd = s; infd = outfd = s;
} else { } else {
do_tcp_connect: do_tcp:
s = tcp_connect(host, port, ip_family); s = tcp_connect(host, port, ip_family, daemon);
if (s < 0) err(1, "tcp_connect"); if (s < 0) err(1, "tcp_connect");
infd = outfd = s; infd = outfd = s;
} }
@ -1212,7 +1366,7 @@ do_tcp_connect:
bs.noauth = true; bs.noauth = true;
if (implied_auth) errx(1, "-n option conflicts with -k, -K, -c and -T options."); if (implied_auth) errx(1, "-n option conflicts with -k, -K, -c and -T options.");
} else { } else {
shs_connect(s, infd, outfd, public_key, private_key, shs_cap_key, remote_key, &bs); shs_connect(s, infd, outfd, public_key, private_key, shs_cap_key, remote_key, &bs, !daemon, key_arg);
} }
if (test) { if (test) {

@ -0,0 +1,8 @@
#!/bin/sh
cap_hex=${1?shs cap key}
sk_hex=${2?server secret key}
cap_b64="$(echo -n "$cap_hex" | xxd -r -p | base64)"
sk_b64="$(echo -n "$sk_hex" | xxd -r -p | base64 -w 0)"
exec sbotc -T -d -c "$cap_b64" -K "$sk_b64"
Loading…
Cancel
Save