diff options
Diffstat (limited to 'ssh/client.c')
-rw-r--r-- | ssh/client.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/ssh/client.c b/ssh/client.c index 64f8f57..80e14a4 100644 --- a/ssh/client.c +++ b/ssh/client.c @@ -83,6 +83,38 @@ static void splice_scanned(struct readbuffer *rb) { rb->newline_cursor = 0; } +static bool prompt_yn(struct readbuffer *rb, const char *text) { + printf("%s [y/n] ", text); + fflush(stdout); + + while (true) { + struct string_view line = extract_line(rb); + if (line.s == NULL) { + read_more_data(STDIN_FILENO, rb); + continue; + } + + splice_scanned(rb); + + if (line.len <= 3) { + char buf[4]; + memcpy(buf, line.s, line.len); + buf[line.len] = '\0'; + + if (strcmp(buf, "y") == 0 || strcmp(buf, "yes") == 0) { + return true; + } + + if (strcmp(buf, "n") == 0 || strcmp(buf, "no") == 0) { + return false; + } + } + + printf("Please answer with 'y', 'n', 'yes' or 'no'. [y/n] "); + fflush(stdout); + } +} + static struct string_view tokenise_greedy(struct string_view *line) { sv_skip_whitespace(line); return sv_tokenise_word(line); @@ -415,6 +447,17 @@ static void handle_event(struct state *state, const struct tomsg_event event) { } } +static bool hostkey_checker(const unsigned char *hash, size_t length, void *stdinbuf_) { + struct readbuffer *stdinbuf = stdinbuf_; + + const char *fingerprint = tomsg_print_hash(hash, length); + + printf("Server host key fingerprint: %s\n", fingerprint); + return prompt_yn(stdinbuf, + "Does this hash match the one given to you by the server administrator, or by a\n" + "member that you trust and is already connected to the server?"); +} + int main(int argc, char **argv) { if (argc != 2) { printf("Usage: %s <hostname:port>\n", argv[0]); @@ -428,10 +471,13 @@ int main(int argc, char **argv) { return 1; } + struct readbuffer stdinbuf = readbuffer_new(); + printf("Connecting...\n"); struct tomsg_client *client; - enum tomsg_retval ret = tomsg_connect(hostname, port, &client); + enum tomsg_retval ret = tomsg_connect( + hostname, port, hostkey_checker, &stdinbuf, &client); if (ret != TOMSG_OK) { printf("Could not connect: %s\n", tomsg_strerror(ret)); return 1; @@ -439,8 +485,6 @@ int main(int argc, char **argv) { printf("Connected.\n"); - struct readbuffer stdinbuf = readbuffer_new(); - struct state state = (struct state){ .rooms = NULL, .num_rooms = 0, |