|
|
@ -51,6 +51,7 @@ struct boxs {
|
|
|
|
unsigned char rx_buf[BOXS_MAXLEN];
|
|
|
|
unsigned char rx_buf[BOXS_MAXLEN];
|
|
|
|
size_t rx_buf_pos;
|
|
|
|
size_t rx_buf_pos;
|
|
|
|
size_t rx_buf_len;
|
|
|
|
size_t rx_buf_len;
|
|
|
|
|
|
|
|
bool noauth;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum pkt_type {
|
|
|
|
enum pkt_type {
|
|
|
@ -95,7 +96,7 @@ static const unsigned char ssb_cap[] = {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void usage() {
|
|
|
|
static void usage() {
|
|
|
|
fputs("usage: sbotc [-j] [-T] [-c <cap>] [-s <host>] [-p <port>] [-k <key>] [-K <keypair_seed>] \n"
|
|
|
|
fputs("usage: sbotc [-j] [-T] [-n] [-c <cap>] [-s <host>] [-p <port>] [-k <key>] [-K <keypair_seed>] \n"
|
|
|
|
" [-t <type>] <method> [<argument>...]\n", stderr);
|
|
|
|
" [-t <type>] <method> [<argument>...]\n", stderr);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -284,6 +285,7 @@ static void shs_connect(int sfd, int infd, int outfd, const unsigned char pubkey
|
|
|
|
bs->rx_buf_pos = 0;
|
|
|
|
bs->rx_buf_pos = 0;
|
|
|
|
bs->rx_buf_len = 0;
|
|
|
|
bs->rx_buf_len = 0;
|
|
|
|
bs->s = sfd;
|
|
|
|
bs->s = sfd;
|
|
|
|
|
|
|
|
bs->noauth = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int pubkey_decode(const char *key_str, unsigned char key[32]) {
|
|
|
|
static int pubkey_decode(const char *key_str, unsigned char key[32]) {
|
|
|
@ -459,6 +461,11 @@ static int bs_read_packet(struct boxs *bs, void *buf, size_t *lenp) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int bs_read(struct boxs *bs, char *buf, size_t len) {
|
|
|
|
static int bs_read(struct boxs *bs, char *buf, size_t len) {
|
|
|
|
|
|
|
|
if (bs->noauth) {
|
|
|
|
|
|
|
|
int rc = read_all(bs->s, buf, len);
|
|
|
|
|
|
|
|
if (rc < 0) err(1, "failed to read packet data");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
size_t remaining;
|
|
|
|
size_t remaining;
|
|
|
|
while (len > 0) {
|
|
|
|
while (len > 0) {
|
|
|
|
remaining = bs->rx_buf_len > len ? len : bs->rx_buf_len;
|
|
|
|
remaining = bs->rx_buf_len > len ? len : bs->rx_buf_len;
|
|
|
@ -508,6 +515,11 @@ static int bs_read_error(struct boxs *bs, int errfd, enum pkt_flags flags, size_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void bs_write(struct boxs *bs, const unsigned char *buf, size_t len) {
|
|
|
|
static void bs_write(struct boxs *bs, const unsigned char *buf, size_t len) {
|
|
|
|
|
|
|
|
if (bs->noauth) {
|
|
|
|
|
|
|
|
int rc = write_all(bs->s, buf, len);
|
|
|
|
|
|
|
|
if (rc < 0) err(1, "failed to write packet");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
while (len > 0) {
|
|
|
|
while (len > 0) {
|
|
|
|
size_t l = len > BOXS_MAXLEN ? BOXS_MAXLEN : len;
|
|
|
|
size_t l = len > BOXS_MAXLEN ? BOXS_MAXLEN : len;
|
|
|
|
bs_write_packet(bs, buf, l);
|
|
|
|
bs_write_packet(bs, buf, l);
|
|
|
@ -817,6 +829,8 @@ int main(int argc, char *argv[]) {
|
|
|
|
char app_dir[_POSIX_PATH_MAX];
|
|
|
|
char app_dir[_POSIX_PATH_MAX];
|
|
|
|
ssize_t len;
|
|
|
|
ssize_t len;
|
|
|
|
bool test = false;
|
|
|
|
bool test = false;
|
|
|
|
|
|
|
|
bool noauth = false;
|
|
|
|
|
|
|
|
bool shs_cap_key_str_arg = false;
|
|
|
|
|
|
|
|
|
|
|
|
get_app_dir(app_dir, sizeof(app_dir));
|
|
|
|
get_app_dir(app_dir, sizeof(app_dir));
|
|
|
|
|
|
|
|
|
|
|
@ -837,7 +851,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < argc && (argv[i][0] == '-'); i++) {
|
|
|
|
for (i = 1; i < argc && (argv[i][0] == '-'); i++) {
|
|
|
|
switch (argv[i][1]) {
|
|
|
|
switch (argv[i][1]) {
|
|
|
|
case 'c': shs_cap_key_str = argv[++i]; break;
|
|
|
|
case 'c': shs_cap_key_str = argv[++i]; shs_cap_key_str_arg = true; break;
|
|
|
|
case 'j': ptype = pkt_type_json; break;
|
|
|
|
case 'j': ptype = pkt_type_json; break;
|
|
|
|
case 'T': test = true; break;
|
|
|
|
case 'T': test = true; break;
|
|
|
|
case 's': host = argv[++i]; break;
|
|
|
|
case 's': host = argv[++i]; break;
|
|
|
@ -845,6 +859,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
case 'K': keypair_seed_str = argv[++i]; break;
|
|
|
|
case 'K': keypair_seed_str = argv[++i]; break;
|
|
|
|
case 'p': port = argv[++i]; break;
|
|
|
|
case 'p': port = argv[++i]; break;
|
|
|
|
case 't': typestr = argv[++i]; break;
|
|
|
|
case 't': typestr = argv[++i]; break;
|
|
|
|
|
|
|
|
case 'n': noauth = true; break;
|
|
|
|
default: usage();
|
|
|
|
default: usage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -920,7 +935,16 @@ int main(int argc, char *argv[]) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct boxs bs;
|
|
|
|
struct boxs bs;
|
|
|
|
|
|
|
|
if (noauth) {
|
|
|
|
|
|
|
|
bs.s = s;
|
|
|
|
|
|
|
|
bs.noauth = true;
|
|
|
|
|
|
|
|
if (key) errx(1, "-k keypair_seed conflicts with -n (noauth)");
|
|
|
|
|
|
|
|
if (keypair_seed_str) errx(1, "-K keypair_seed conflicts with -n (noauth)");
|
|
|
|
|
|
|
|
if (shs_cap_key_str_arg) errx(1, "-c cap_key conflicts with -n (noauth)");
|
|
|
|
|
|
|
|
if (test) errx(1, "-n (noauth) conflicts with -T (test shs)");
|
|
|
|
|
|
|
|
} 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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (test) {
|
|
|
|
if (test) {
|
|
|
|
rc = write_all(outfd, bs.encrypt_key, sizeof(bs.encrypt_key));
|
|
|
|
rc = write_all(outfd, bs.encrypt_key, sizeof(bs.encrypt_key));
|
|
|
|