@ -17,6 +17,7 @@
# include <limits.h>
# include <netdb.h>
# include <netinet/in.h>
# include <signal.h>
# include <stdarg.h>
# include <stdbool.h>
# include <stdio.h>
@ -110,7 +111,7 @@ static void reset_termios() {
static void usage ( ) {
fputs ( " usage: sbotc [-j] [-T] [-l] [-r] [-e] \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 ) ;
exit ( EXIT_FAILURE ) ;
}
@ -150,16 +151,17 @@ static int connect_localhost(const char *port, enum ip_family ip_family) {
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 * result , * rp ;
int s ;
int fd ;
int err ;
int err , rc ;
memset ( & hints , 0 , sizeof ( hints ) ) ;
hints . ai_family = ip_family ;
hints . ai_protocol = IPPROTO_TCP ;
if ( server ) hints . ai_flags = AI_PASSIVE ;
s = getaddrinfo ( host , port , & hints , & result ) ;
if ( s < 0 ) errx ( 1 , " unable to resolve host: %s " , gai_strerror ( s ) ) ;
@ -167,7 +169,15 @@ static int tcp_connect(const char *host, const char *port, enum ip_family ip_fam
for ( rp = result ; rp ; rp = rp - > ai_next ) {
fd = socket ( rp - > ai_family , rp - > ai_socktype , rp - > ai_protocol ) ;
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 ;
close ( fd ) ;
errno = err ;
@ -176,14 +186,31 @@ static int tcp_connect(const char *host, const char *port, enum ip_family ip_fam
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 ) ;
}
if ( server & & fd > - 1 ) {
int client = accept ( fd , NULL , NULL ) ;
err = errno ;
close ( fd ) ;
errno = err ;
return client ;
}
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 ;
const size_t path_len = strlen ( path ) ;
int s , rc ;
@ -193,18 +220,38 @@ static int unix_connect(const char *path) {
memset ( & name , 0 , sizeof ( struct sockaddr_un ) ) ;
name . sun_family = AF_UNIX ;
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 ( 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 ;
}
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 ;
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 " ) ;
int rc = stat ( buf , & st ) ;
if ( rc < 0 ) return - 1 ;
if ( ! ( st . st_mode & S_IFSOCK ) ) { errno = EINVAL ; return - 1 ; }
if ( ! server ) {
if ( rc < 0 ) return - 1 ;
if ( ! ( st . st_mode & S_IFSOCK ) ) { errno = EINVAL ; return - 1 ; }
}
return 0 ;
}
@ -243,121 +290,226 @@ static int write_all(int fd, const void *buf, size_t count) {
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 ;
unsigned char client_pubkey [ 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 ] ;
rc = crypto_box_keypair ( kx_pk , kx_sk ) ;
if ( rc < 0 ) errx ( 1 , " failed to generate auth keypair " ) ;
if ( client ) {
rc = crypto_box_keypair ( kx_pk , kx_sk ) ;
if ( rc < 0 ) errx ( 1 , " failed to generate auth keypair " ) ;
rc = crypto_auth ( local_app_mac , kx_pk , 32 , appkey ) ;
if ( rc < 0 ) err ( 1 , " failed to generate app mac " ) ;
rc = crypto_auth ( local_app_mac , kx_pk , 32 , appkey ) ;
if ( rc < 0 ) err ( 1 , " failed to generate app mac " ) ;
// send challenge
unsigned char buf [ 64 ] ;
memcpy ( buf , local_app_mac , 32 ) ;
memcpy ( buf + 32 , kx_pk , 32 ) ;
rc = write_all ( outfd , buf , sizeof ( buf ) ) ;
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
// send challenge
memcpy ( buf , local_app_mac , 32 ) ;
memcpy ( buf + 32 , kx_pk , 32 ) ;
rc = write_all ( outfd , buf , sizeof ( buf ) ) ;
if ( rc < 0 ) err ( 1 , " failed to send challenge " ) ;
unsigned char secret [ 32 ] ;
rc = crypto_scalarmult ( secret , kx_sk , remote_kx_pk ) ;
if ( rc < 0 ) errx ( 1 , " failed to derive shared secret " ) ;
} else {
// recv challenge
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_sign_ed25519_pk_to_curve25519 ( remote_pk_curve , server_pubkey ) ;
if ( rc < 0 ) errx ( 1 , " failed to curvify remote public key " ) ;
rc = crypto_auth_verify ( buf , remote_kx_pk , 32 , appkey ) ;
if ( rc < 0 ) errx ( 1 , " wrong protocol/version " ) ;
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 ] ;
memcpy ( secret2a , appkey , 32 ) ;
memcpy ( secret2a + 32 , secret , 32 ) ;
memcpy ( secret2a + 64 , a_bob , 32 ) ;
if ( client ) {
// recv challenge
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?) " ) ;
unsigned char secret2 [ 32 ] ;
rc = crypto_hash_sha256 ( secret2 , secret2a , sizeof ( secret2a ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret2 " ) ;
} else {
rc = crypto_box_keypair ( kx_pk , kx_sk ) ;
if ( rc < 0 ) errx ( 1 , " failed to generate auth keypair " ) ;
unsigned char shash [ 32 ] ;
rc = crypto_hash_sha256 ( shash , secret , sizeof ( secret ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret " ) ;
rc = crypto_auth ( local_app_mac , kx_pk , 32 , appkey ) ;
if ( rc < 0 ) err ( 1 , " failed to generate app mac " ) ;
unsigned char signed1 [ 96 ] ;
memcpy ( signed1 , appkey , 32 ) ;
memcpy ( signed1 + 32 , server_pubkey , 32 ) ;
memcpy ( signed1 + 64 , shash , 32 ) ;
// send challenge
memcpy ( buf , local_app_mac , 32 ) ;
memcpy ( buf + 32 , kx_pk , 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 ] ;
memcpy ( hello , sig , 64 ) ;
memcpy ( hello + 64 , pubkey , 32 ) ;
unsigned char secret2 [ 32 ] ;
unsigned char boxed_auth [ 112 ] ;
rc = crypto_secretbox_easy ( boxed_auth , hello , sizeof ( hello ) , zeros , secret2 ) ;
if ( rc < 0 ) errx ( 1 , " failed to box hello " ) ;
unsigned char secret [ 32 ] ;
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 ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to send auth " ) ;
rc = crypto_scalarmult ( secret , kx_sk , remote_kx_pk ) ;
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 = read_all ( infd , boxed_okay , sizeof ( boxed_okay ) ) ;
if ( rc < 0 ) err ( 1 , " hello not accepted " ) ;
rc = crypto_scalarmult ( a_bob , kx_sk , remote_pk_curve ) ;
if ( rc < 0 ) errx ( 1 , " failed to derive a_bob " ) ;
unsigned char local_sk_curve [ 32 ] ;
rc = crypto_sign_ed25519_sk_to_curve25519 ( local_sk_curve , seckey ) ;
if ( rc < 0 ) errx ( 1 , " failed to curvify local secret key " ) ;
memcpy ( secret2a , appkey , 32 ) ;
memcpy ( secret2a + 32 , secret , 32 ) ;
memcpy ( secret2a + 64 , a_bob , 32 ) ;
unsigned char b_alice [ 32 ] ;
rc = crypto_scalarmult ( b_alice , local_sk_curve , remote_kx_pk ) ;
if ( rc < 0 ) errx ( 1 , " failed to derive b_alice " ) ;
rc = crypto_hash_sha256 ( secret2 , secret2a , sizeof ( secret2a ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret2 " ) ;
unsigned char secret3a [ 128 ] ;
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 ( shash , secret , sizeof ( secret ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret " ) ;
unsigned char secret3 [ 32 ] ;
rc = crypto_hash_sha256 ( secret3 , secret3a , sizeof ( secret3a ) ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret3 " ) ;
unsigned char signed1 [ 96 ] ;
memcpy ( signed1 , appkey , 32 ) ;
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 ) ;
if ( rc < 0 ) errx ( 1 , " failed to unbox the okay " ) ;
rc = crypto_scalarmult ( secret , kx_sk , remote_kx_pk ) ;
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 ] ;
memcpy ( signed2 , appkey , 32 ) ;
memcpy ( signed2 + 32 , hello , 96 ) ;
memcpy ( signed2 + 128 , shash , 32 ) ;
if ( client ) {
// verify accept
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 ) ;
if ( rc < 0 ) errx ( 1 , " server not authenticated " ) ;
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 " ) ;
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 ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash secret3 " ) ;
unsigned char enc_key_hashed [ 64 ] ;
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 ) ;
if ( rc < 0 ) errx ( 1 , " failed to hash the encrypt key " ) ;
@ -1062,6 +1214,7 @@ int main(int argc, char *argv[]) {
bool ipv6_arg = false ;
bool passthrough = false ;
bool strings = false ;
bool daemon = false ;
enum ip_family ip_family ;
get_app_dir ( app_dir , sizeof ( app_dir ) ) ;
@ -1095,6 +1248,7 @@ int main(int argc, char *argv[]) {
case ' n ' : noauth = true ; break ;
case ' 4 ' : ipv4_arg = true ; break ;
case ' 6 ' : ipv6_arg = true ; break ;
case ' d ' : daemon = true ; break ;
case ' a ' : passthrough = true ; break ;
case ' l ' : no_newline = true ; break ;
case ' r ' : raw = true ; no_newline = true ; break ;
@ -1190,24 +1344,24 @@ int main(int argc, char *argv[]) {
} else if ( socket_path ) {
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 " ) ;
infd = outfd = s ;
} else if ( ! implied_tcp & & ! implied_auth ) {
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 ) goto do_tcp _connect ;
s = unix_connect ( socket_path_buf );
if ( rc < 0 ) goto do_tcp ;
s = unix_connect ( socket_path_buf , daemon );
if ( s < 0 & & noauth ) err ( 1 , " unix_connect " ) ;
if ( s < 0 ) goto do_tcp _connect ;
if ( s < 0 ) goto do_tcp ;
noauth = true ;
infd = outfd = s ;
} else {
do_tcp _connect :
s = tcp_connect ( host , port , ip_family );
do_tcp :
s = tcp_connect ( host , port , ip_family , daemon );
if ( s < 0 ) err ( 1 , " tcp_connect " ) ;
infd = outfd = s ;
}
@ -1218,7 +1372,7 @@ do_tcp_connect:
bs . noauth = true ;
if ( implied_auth ) errx ( 1 , " -n option conflicts with -k, -K, -c and -T options. " ) ;
} 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 ) {