|
|
@ -87,6 +87,12 @@ enum stream_state {
|
|
|
|
stream_state_ended_error,
|
|
|
|
stream_state_ended_error,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum ip_family {
|
|
|
|
|
|
|
|
ip_family_ipv4 = AF_INET,
|
|
|
|
|
|
|
|
ip_family_ipv6 = AF_INET6,
|
|
|
|
|
|
|
|
ip_family_any = AF_UNSPEC
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned char zeros[24] = {0};
|
|
|
|
static unsigned char zeros[24] = {0};
|
|
|
|
|
|
|
|
|
|
|
|
static const unsigned char ssb_cap[] = {
|
|
|
|
static const unsigned char ssb_cap[] = {
|
|
|
@ -99,12 +105,12 @@ static const unsigned char ssb_cap[] = {
|
|
|
|
static void usage() {
|
|
|
|
static void usage() {
|
|
|
|
fputs("usage: sbotc [-j] [-T]\n"
|
|
|
|
fputs("usage: sbotc [-j] [-T]\n"
|
|
|
|
" [ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]\n"
|
|
|
|
" [ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]\n"
|
|
|
|
" [ [-s <host>] [-p <port>] | [-u <socket_path>] ]\n"
|
|
|
|
" [ [-s <host>] [-p <port>] [ -4 | -6 ] | [-u <socket_path>] ]\n"
|
|
|
|
" [-t <type>] <method> [<argument>...]\n", stderr);
|
|
|
|
" [-t <type>] <method> [<argument>...]\n", stderr);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int tcp_connect(const char *host, const char *port) {
|
|
|
|
static int tcp_connect(const char *host, const char *port, enum ip_family ip_family) {
|
|
|
|
struct addrinfo hints;
|
|
|
|
struct addrinfo hints;
|
|
|
|
struct addrinfo *result, *rp;
|
|
|
|
struct addrinfo *result, *rp;
|
|
|
|
int s;
|
|
|
|
int s;
|
|
|
@ -112,7 +118,7 @@ static int tcp_connect(const char *host, const char *port) {
|
|
|
|
int err;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = AF_UNSPEC;
|
|
|
|
hints.ai_family = ip_family;
|
|
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
|
|
|
|
|
|
|
|
|
|
s = getaddrinfo(host, port, &hints, &result);
|
|
|
|
s = getaddrinfo(host, port, &hints, &result);
|
|
|
@ -863,6 +869,9 @@ int main(int argc, char *argv[]) {
|
|
|
|
bool port_arg = false;
|
|
|
|
bool port_arg = false;
|
|
|
|
bool key_arg = false;
|
|
|
|
bool key_arg = false;
|
|
|
|
bool shs_cap_key_str_arg = false;
|
|
|
|
bool shs_cap_key_str_arg = false;
|
|
|
|
|
|
|
|
bool ipv4_arg = false;
|
|
|
|
|
|
|
|
bool ipv6_arg = false;
|
|
|
|
|
|
|
|
enum ip_family ip_family;
|
|
|
|
|
|
|
|
|
|
|
|
get_app_dir(app_dir, sizeof(app_dir));
|
|
|
|
get_app_dir(app_dir, sizeof(app_dir));
|
|
|
|
|
|
|
|
|
|
|
@ -893,11 +902,19 @@ int main(int argc, char *argv[]) {
|
|
|
|
case 'u': socket_path = argv[++i]; break;
|
|
|
|
case 'u': socket_path = argv[++i]; break;
|
|
|
|
case 't': typestr = argv[++i]; break;
|
|
|
|
case 't': typestr = argv[++i]; break;
|
|
|
|
case 'n': noauth = true; break;
|
|
|
|
case 'n': noauth = true; break;
|
|
|
|
|
|
|
|
case '4': ipv4_arg = true; break;
|
|
|
|
|
|
|
|
case '6': ipv6_arg = true; break;
|
|
|
|
default: usage();
|
|
|
|
default: usage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i < argc) methodstr = argv[i++]; else if (!test) usage();
|
|
|
|
if (i < argc) methodstr = argv[i++]; else if (!test) usage();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ipv4_arg && ipv6_arg) errx(1, "options -4 and -6 conflict");
|
|
|
|
|
|
|
|
ip_family =
|
|
|
|
|
|
|
|
ipv4_arg ? ip_family_ipv4 :
|
|
|
|
|
|
|
|
ipv6_arg ? ip_family_ipv6 :
|
|
|
|
|
|
|
|
ip_family_any;
|
|
|
|
|
|
|
|
|
|
|
|
if (shs_cap_key_str) {
|
|
|
|
if (shs_cap_key_str) {
|
|
|
|
rc = pubkey_decode(shs_cap_key_str, shs_cap_key);
|
|
|
|
rc = pubkey_decode(shs_cap_key_str, shs_cap_key);
|
|
|
|
if (rc < 0) err(1, "unable to decode cap key '%s'", shs_cap_key_str);
|
|
|
|
if (rc < 0) err(1, "unable to decode cap key '%s'", shs_cap_key_str);
|
|
|
@ -957,7 +974,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
memcpy(remote_key, public_key, 32);
|
|
|
|
memcpy(remote_key, public_key, 32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool implied_tcp = host_arg || port_arg;
|
|
|
|
bool implied_tcp = host_arg || port_arg || ipv4_arg || ipv6_arg;
|
|
|
|
bool implied_auth = key_arg || keypair_seed_str || shs_cap_key_str_arg || test;
|
|
|
|
bool implied_auth = key_arg || keypair_seed_str || shs_cap_key_str_arg || test;
|
|
|
|
|
|
|
|
|
|
|
|
if (test) {
|
|
|
|
if (test) {
|
|
|
@ -984,7 +1001,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
do_tcp_connect:
|
|
|
|
do_tcp_connect:
|
|
|
|
s = tcp_connect(host, port);
|
|
|
|
s = tcp_connect(host, port, ip_family);
|
|
|
|
if (s < 0) err(1, "tcp_connect");
|
|
|
|
if (s < 0) err(1, "tcp_connect");
|
|
|
|
infd = outfd = s;
|
|
|
|
infd = outfd = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|