aboutsummaryrefslogtreecommitdiff
path: root/ssh/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh/client.c')
-rw-r--r--ssh/client.c50
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,