diff options
-rw-r--r-- | clientloop.c | 202 | ||||
-rw-r--r-- | clientloop.h | 4 | ||||
-rw-r--r-- | compat.c | 3 | ||||
-rw-r--r-- | mux.c | 6 | ||||
-rw-r--r-- | packet.c | 5 | ||||
-rw-r--r-- | ssh.c | 29 | ||||
-rw-r--r-- | sshconnect.c | 6 | ||||
-rw-r--r-- | sshconnect2.c | 489 |
8 files changed, 416 insertions, 328 deletions
diff --git a/clientloop.c b/clientloop.c index 9a5865b2a..8da5d914e 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.314 2018/06/26 02:02:36 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.315 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -91,7 +91,7 @@ | |||
91 | #include "ssh.h" | 91 | #include "ssh.h" |
92 | #include "ssh2.h" | 92 | #include "ssh2.h" |
93 | #include "packet.h" | 93 | #include "packet.h" |
94 | #include "buffer.h" | 94 | #include "sshbuf.h" |
95 | #include "compat.h" | 95 | #include "compat.h" |
96 | #include "channels.h" | 96 | #include "channels.h" |
97 | #include "dispatch.h" | 97 | #include "dispatch.h" |
@@ -153,7 +153,7 @@ static time_t control_persist_exit_time = 0; | |||
153 | volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ | 153 | volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
154 | static int last_was_cr; /* Last character was a newline. */ | 154 | static int last_was_cr; /* Last character was a newline. */ |
155 | static int exit_status; /* Used to store the command exit status. */ | 155 | static int exit_status; /* Used to store the command exit status. */ |
156 | static Buffer stderr_buffer; /* Used for final exit message. */ | 156 | static struct sshbuf *stderr_buffer; /* Used for final exit message. */ |
157 | static int connection_in; /* Connection to server (input). */ | 157 | static int connection_in; /* Connection to server (input). */ |
158 | static int connection_out; /* Connection to server (output). */ | 158 | static int connection_out; /* Connection to server (output). */ |
159 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ | 159 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
@@ -188,7 +188,7 @@ TAILQ_HEAD(global_confirms, global_confirm); | |||
188 | static struct global_confirms global_confirms = | 188 | static struct global_confirms global_confirms = |
189 | TAILQ_HEAD_INITIALIZER(global_confirms); | 189 | TAILQ_HEAD_INITIALIZER(global_confirms); |
190 | 190 | ||
191 | void ssh_process_session2_setup(int, int, int, Buffer *); | 191 | void ssh_process_session2_setup(int, int, int, struct sshbuf *); |
192 | 192 | ||
193 | /* Restores stdin to blocking mode. */ | 193 | /* Restores stdin to blocking mode. */ |
194 | 194 | ||
@@ -493,7 +493,7 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
493 | struct timeval tv, *tvp; | 493 | struct timeval tv, *tvp; |
494 | int timeout_secs; | 494 | int timeout_secs; |
495 | time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); | 495 | time_t minwait_secs = 0, server_alive_time = 0, now = monotime(); |
496 | int ret; | 496 | int r, ret; |
497 | 497 | ||
498 | /* Add any selections by the channel mechanism. */ | 498 | /* Add any selections by the channel mechanism. */ |
499 | channel_prepare_select(active_state, readsetp, writesetp, maxfdp, | 499 | channel_prepare_select(active_state, readsetp, writesetp, maxfdp, |
@@ -546,8 +546,6 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
546 | 546 | ||
547 | ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); | 547 | ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); |
548 | if (ret < 0) { | 548 | if (ret < 0) { |
549 | char buf[100]; | ||
550 | |||
551 | /* | 549 | /* |
552 | * We have to clear the select masks, because we return. | 550 | * We have to clear the select masks, because we return. |
553 | * We have to return, because the mainloop checks for the flags | 551 | * We have to return, because the mainloop checks for the flags |
@@ -559,8 +557,9 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
559 | if (errno == EINTR) | 557 | if (errno == EINTR) |
560 | return; | 558 | return; |
561 | /* Note: we might still have data in the buffers. */ | 559 | /* Note: we might still have data in the buffers. */ |
562 | snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); | 560 | if ((r = sshbuf_putf(stderr_buffer, |
563 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 561 | "select: %s\r\n", strerror(errno))) != 0) |
562 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
564 | quit_pending = 1; | 563 | quit_pending = 1; |
565 | } else if (ret == 0) { | 564 | } else if (ret == 0) { |
566 | /* | 565 | /* |
@@ -574,15 +573,15 @@ client_wait_until_can_do_something(struct ssh *ssh, | |||
574 | } | 573 | } |
575 | 574 | ||
576 | static void | 575 | static void |
577 | client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) | 576 | client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr) |
578 | { | 577 | { |
579 | /* Flush stdout and stderr buffers. */ | 578 | /* Flush stdout and stderr buffers. */ |
580 | if (buffer_len(bout) > 0) | 579 | if (sshbuf_len(bout) > 0) |
581 | atomicio(vwrite, fileno(stdout), buffer_ptr(bout), | 580 | atomicio(vwrite, fileno(stdout), sshbuf_mutable_ptr(bout), |
582 | buffer_len(bout)); | 581 | sshbuf_len(bout)); |
583 | if (buffer_len(berr) > 0) | 582 | if (sshbuf_len(berr) > 0) |
584 | atomicio(vwrite, fileno(stderr), buffer_ptr(berr), | 583 | atomicio(vwrite, fileno(stderr), sshbuf_mutable_ptr(berr), |
585 | buffer_len(berr)); | 584 | sshbuf_len(berr)); |
586 | 585 | ||
587 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 586 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
588 | 587 | ||
@@ -602,8 +601,8 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) | |||
602 | static void | 601 | static void |
603 | client_process_net_input(fd_set *readset) | 602 | client_process_net_input(fd_set *readset) |
604 | { | 603 | { |
605 | int len; | ||
606 | char buf[SSH_IOBUFSZ]; | 604 | char buf[SSH_IOBUFSZ]; |
605 | int r, len; | ||
607 | 606 | ||
608 | /* | 607 | /* |
609 | * Read input from the server, and add any such data to the buffer of | 608 | * Read input from the server, and add any such data to the buffer of |
@@ -617,10 +616,11 @@ client_process_net_input(fd_set *readset) | |||
617 | * Received EOF. The remote host has closed the | 616 | * Received EOF. The remote host has closed the |
618 | * connection. | 617 | * connection. |
619 | */ | 618 | */ |
620 | snprintf(buf, sizeof buf, | 619 | if ((r = sshbuf_putf(stderr_buffer, |
621 | "Connection to %.300s closed by remote host.\r\n", | 620 | "Connection to %.300s closed by remote host.\r\n", |
622 | host); | 621 | host)) != 0) |
623 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 622 | fatal("%s: buffer error: %s", |
623 | __func__, ssh_err(r)); | ||
624 | quit_pending = 1; | 624 | quit_pending = 1; |
625 | return; | 625 | return; |
626 | } | 626 | } |
@@ -637,10 +637,11 @@ client_process_net_input(fd_set *readset) | |||
637 | * An error has encountered. Perhaps there is a | 637 | * An error has encountered. Perhaps there is a |
638 | * network problem. | 638 | * network problem. |
639 | */ | 639 | */ |
640 | snprintf(buf, sizeof buf, | 640 | if ((r = sshbuf_putf(stderr_buffer, |
641 | "Read from remote host %.300s: %.100s\r\n", | 641 | "Read from remote host %.300s: %.100s\r\n", |
642 | host, strerror(errno)); | 642 | host, strerror(errno))) != 0) |
643 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 643 | fatal("%s: buffer error: %s", |
644 | __func__, ssh_err(r)); | ||
644 | quit_pending = 1; | 645 | quit_pending = 1; |
645 | return; | 646 | return; |
646 | } | 647 | } |
@@ -653,7 +654,7 @@ client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx) | |||
653 | { | 654 | { |
654 | struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; | 655 | struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; |
655 | char errmsg[256]; | 656 | char errmsg[256]; |
656 | int tochan; | 657 | int r, tochan; |
657 | 658 | ||
658 | /* | 659 | /* |
659 | * If a TTY was explicitly requested, then a failure to allocate | 660 | * If a TTY was explicitly requested, then a failure to allocate |
@@ -688,7 +689,10 @@ client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx) | |||
688 | * their stderr. | 689 | * their stderr. |
689 | */ | 690 | */ |
690 | if (tochan) { | 691 | if (tochan) { |
691 | buffer_append(c->extended, errmsg, strlen(errmsg)); | 692 | if ((r = sshbuf_put(c->extended, errmsg, |
693 | strlen(errmsg))) != 0) | ||
694 | fatal("%s: buffer error %s", __func__, | ||
695 | ssh_err(r)); | ||
692 | } else | 696 | } else |
693 | error("%s", errmsg); | 697 | error("%s", errmsg); |
694 | if (cr->action == CONFIRM_TTY) { | 698 | if (cr->action == CONFIRM_TTY) { |
@@ -892,14 +896,15 @@ static struct escape_help_text esc_txt[] = { | |||
892 | }; | 896 | }; |
893 | 897 | ||
894 | static void | 898 | static void |
895 | print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr) | 899 | print_escape_help(struct sshbuf *b, int escape_char, int mux_client, |
900 | int using_stderr) | ||
896 | { | 901 | { |
897 | unsigned int i, suppress_flags; | 902 | unsigned int i, suppress_flags; |
898 | char string[1024]; | 903 | int r; |
899 | 904 | ||
900 | snprintf(string, sizeof string, "%c?\r\n" | 905 | if ((r = sshbuf_putf(b, |
901 | "Supported escape sequences:\r\n", escape_char); | 906 | "%c?\r\nSupported escape sequences:\r\n", escape_char)) != 0) |
902 | buffer_append(b, string, strlen(string)); | 907 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
903 | 908 | ||
904 | suppress_flags = | 909 | suppress_flags = |
905 | (mux_client ? SUPPRESS_MUXCLIENT : 0) | | 910 | (mux_client ? SUPPRESS_MUXCLIENT : 0) | |
@@ -909,16 +914,16 @@ print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr) | |||
909 | for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) { | 914 | for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) { |
910 | if (esc_txt[i].flags & suppress_flags) | 915 | if (esc_txt[i].flags & suppress_flags) |
911 | continue; | 916 | continue; |
912 | snprintf(string, sizeof string, " %c%-3s - %s\r\n", | 917 | if ((r = sshbuf_putf(b, " %c%-3s - %s\r\n", |
913 | escape_char, esc_txt[i].cmd, esc_txt[i].text); | 918 | escape_char, esc_txt[i].cmd, esc_txt[i].text)) != 0) |
914 | buffer_append(b, string, strlen(string)); | 919 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
915 | } | 920 | } |
916 | 921 | ||
917 | snprintf(string, sizeof string, | 922 | if ((r = sshbuf_putf(b, |
918 | " %c%c - send the escape character by typing it twice\r\n" | 923 | " %c%c - send the escape character by typing it twice\r\n" |
919 | "(Note that escapes are only recognized immediately after " | 924 | "(Note that escapes are only recognized immediately after " |
920 | "newline.)\r\n", escape_char, escape_char); | 925 | "newline.)\r\n", escape_char, escape_char)) != 0) |
921 | buffer_append(b, string, strlen(string)); | 926 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
922 | } | 927 | } |
923 | 928 | ||
924 | /* | 929 | /* |
@@ -926,12 +931,11 @@ print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr) | |||
926 | */ | 931 | */ |
927 | static int | 932 | static int |
928 | process_escapes(struct ssh *ssh, Channel *c, | 933 | process_escapes(struct ssh *ssh, Channel *c, |
929 | Buffer *bin, Buffer *bout, Buffer *berr, | 934 | struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr, |
930 | char *buf, int len) | 935 | char *buf, int len) |
931 | { | 936 | { |
932 | char string[1024]; | ||
933 | pid_t pid; | 937 | pid_t pid; |
934 | int bytes = 0; | 938 | int r, bytes = 0; |
935 | u_int i; | 939 | u_int i; |
936 | u_char ch; | 940 | u_char ch; |
937 | char *s; | 941 | char *s; |
@@ -957,10 +961,10 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
957 | switch (ch) { | 961 | switch (ch) { |
958 | case '.': | 962 | case '.': |
959 | /* Terminate the connection. */ | 963 | /* Terminate the connection. */ |
960 | snprintf(string, sizeof string, "%c.\r\n", | 964 | if ((r = sshbuf_putf(berr, "%c.\r\n", |
961 | efc->escape_char); | 965 | efc->escape_char)) != 0) |
962 | buffer_append(berr, string, strlen(string)); | 966 | fatal("%s: buffer error: %s", |
963 | 967 | __func__, ssh_err(r)); | |
964 | if (c && c->ctl_chan != -1) { | 968 | if (c && c->ctl_chan != -1) { |
965 | chan_read_failed(ssh, c); | 969 | chan_read_failed(ssh, c); |
966 | chan_write_failed(ssh, c); | 970 | chan_write_failed(ssh, c); |
@@ -969,7 +973,7 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
969 | c->self, NULL); | 973 | c->self, NULL); |
970 | } | 974 | } |
971 | c->type = SSH_CHANNEL_ABANDONED; | 975 | c->type = SSH_CHANNEL_ABANDONED; |
972 | buffer_clear(c->input); | 976 | sshbuf_reset(c->input); |
973 | chan_ibuf_empty(ssh, c); | 977 | chan_ibuf_empty(ssh, c); |
974 | return 0; | 978 | return 0; |
975 | } else | 979 | } else |
@@ -985,18 +989,20 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
985 | snprintf(b, sizeof b, "^Z"); | 989 | snprintf(b, sizeof b, "^Z"); |
986 | else | 990 | else |
987 | snprintf(b, sizeof b, "%c", ch); | 991 | snprintf(b, sizeof b, "%c", ch); |
988 | snprintf(string, sizeof string, | 992 | if ((r = sshbuf_putf(berr, |
989 | "%c%s escape not available to " | 993 | "%c%s escape not available to " |
990 | "multiplexed sessions\r\n", | 994 | "multiplexed sessions\r\n", |
991 | efc->escape_char, b); | 995 | efc->escape_char, b)) != 0) |
992 | buffer_append(berr, string, | 996 | fatal("%s: buffer error: %s", |
993 | strlen(string)); | 997 | __func__, ssh_err(r)); |
994 | continue; | 998 | continue; |
995 | } | 999 | } |
996 | /* Suspend the program. Inform the user */ | 1000 | /* Suspend the program. Inform the user */ |
997 | snprintf(string, sizeof string, | 1001 | if ((r = sshbuf_putf(berr, |
998 | "%c^Z [suspend ssh]\r\n", efc->escape_char); | 1002 | "%c^Z [suspend ssh]\r\n", |
999 | buffer_append(berr, string, strlen(string)); | 1003 | efc->escape_char)) != 0) |
1004 | fatal("%s: buffer error: %s", | ||
1005 | __func__, ssh_err(r)); | ||
1000 | 1006 | ||
1001 | /* Restore terminal modes and suspend. */ | 1007 | /* Restore terminal modes and suspend. */ |
1002 | client_suspend_self(bin, bout, berr); | 1008 | client_suspend_self(bin, bout, berr); |
@@ -1005,12 +1011,15 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1005 | continue; | 1011 | continue; |
1006 | 1012 | ||
1007 | case 'B': | 1013 | case 'B': |
1008 | snprintf(string, sizeof string, | 1014 | if ((r = sshbuf_putf(berr, |
1009 | "%cB\r\n", efc->escape_char); | 1015 | "%cB\r\n", efc->escape_char)) != 0) |
1010 | buffer_append(berr, string, strlen(string)); | 1016 | fatal("%s: buffer error: %s", |
1017 | __func__, ssh_err(r)); | ||
1011 | channel_request_start(ssh, c->self, "break", 0); | 1018 | channel_request_start(ssh, c->self, "break", 0); |
1012 | packet_put_int(1000); | 1019 | if ((r = sshpkt_put_u32(ssh, 1000)) != 0 || |
1013 | packet_send(); | 1020 | (r = sshpkt_send(ssh)) != 0) |
1021 | fatal("%s: %s", __func__, | ||
1022 | ssh_err(r)); | ||
1014 | continue; | 1023 | continue; |
1015 | 1024 | ||
1016 | case 'R': | 1025 | case 'R': |
@@ -1027,11 +1036,11 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1027 | if (c && c->ctl_chan != -1) | 1036 | if (c && c->ctl_chan != -1) |
1028 | goto noescape; | 1037 | goto noescape; |
1029 | if (!log_is_on_stderr()) { | 1038 | if (!log_is_on_stderr()) { |
1030 | snprintf(string, sizeof string, | 1039 | if ((r = sshbuf_putf(berr, |
1031 | "%c%c [Logging to syslog]\r\n", | 1040 | "%c%c [Logging to syslog]\r\n", |
1032 | efc->escape_char, ch); | 1041 | efc->escape_char, ch)) != 0) |
1033 | buffer_append(berr, string, | 1042 | fatal("%s: buffer error: %s", |
1034 | strlen(string)); | 1043 | __func__, ssh_err(r)); |
1035 | continue; | 1044 | continue; |
1036 | } | 1045 | } |
1037 | if (ch == 'V' && options.log_level > | 1046 | if (ch == 'V' && options.log_level > |
@@ -1040,11 +1049,12 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1040 | if (ch == 'v' && options.log_level < | 1049 | if (ch == 'v' && options.log_level < |
1041 | SYSLOG_LEVEL_DEBUG3) | 1050 | SYSLOG_LEVEL_DEBUG3) |
1042 | log_change_level(++options.log_level); | 1051 | log_change_level(++options.log_level); |
1043 | snprintf(string, sizeof string, | 1052 | if ((r = sshbuf_putf(berr, |
1044 | "%c%c [LogLevel %s]\r\n", | 1053 | "%c%c [LogLevel %s]\r\n", |
1045 | efc->escape_char, ch, | 1054 | efc->escape_char, ch, |
1046 | log_level_name(options.log_level)); | 1055 | log_level_name(options.log_level))) != 0) |
1047 | buffer_append(berr, string, strlen(string)); | 1056 | fatal("%s: buffer error: %s", |
1057 | __func__, ssh_err(r)); | ||
1048 | continue; | 1058 | continue; |
1049 | 1059 | ||
1050 | case '&': | 1060 | case '&': |
@@ -1062,9 +1072,11 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1062 | /* Stop listening for new connections. */ | 1072 | /* Stop listening for new connections. */ |
1063 | channel_stop_listening(ssh); | 1073 | channel_stop_listening(ssh); |
1064 | 1074 | ||
1065 | snprintf(string, sizeof string, | 1075 | if ((r = sshbuf_putf(berr, |
1066 | "%c& [backgrounded]\n", efc->escape_char); | 1076 | "%c& [backgrounded]\n", efc->escape_char)) |
1067 | buffer_append(berr, string, strlen(string)); | 1077 | != 0) |
1078 | fatal("%s: buffer error: %s", | ||
1079 | __func__, ssh_err(r)); | ||
1068 | 1080 | ||
1069 | /* Fork into background. */ | 1081 | /* Fork into background. */ |
1070 | pid = fork(); | 1082 | pid = fork(); |
@@ -1077,8 +1089,10 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1077 | exit(0); | 1089 | exit(0); |
1078 | } | 1090 | } |
1079 | /* The child continues serving connections. */ | 1091 | /* The child continues serving connections. */ |
1080 | buffer_append(bin, "\004", 1); | ||
1081 | /* fake EOF on stdin */ | 1092 | /* fake EOF on stdin */ |
1093 | if ((r = sshbuf_put_u8(bin, 4)) != 0) | ||
1094 | fatal("%s: buffer error: %s", | ||
1095 | __func__, ssh_err(r)); | ||
1082 | return -1; | 1096 | return -1; |
1083 | case '?': | 1097 | case '?': |
1084 | print_escape_help(berr, efc->escape_char, | 1098 | print_escape_help(berr, efc->escape_char, |
@@ -1087,11 +1101,14 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1087 | continue; | 1101 | continue; |
1088 | 1102 | ||
1089 | case '#': | 1103 | case '#': |
1090 | snprintf(string, sizeof string, "%c#\r\n", | 1104 | if ((r = sshbuf_putf(berr, "%c#\r\n", |
1091 | efc->escape_char); | 1105 | efc->escape_char)) != 0) |
1092 | buffer_append(berr, string, strlen(string)); | 1106 | fatal("%s: buffer error: %s", |
1107 | __func__, ssh_err(r)); | ||
1093 | s = channel_open_message(ssh); | 1108 | s = channel_open_message(ssh); |
1094 | buffer_append(berr, s, strlen(s)); | 1109 | if ((r = sshbuf_put(berr, s, strlen(s))) != 0) |
1110 | fatal("%s: buffer error: %s", | ||
1111 | __func__, ssh_err(r)); | ||
1095 | free(s); | 1112 | free(s); |
1096 | continue; | 1113 | continue; |
1097 | 1114 | ||
@@ -1103,7 +1120,10 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1103 | 1120 | ||
1104 | default: | 1121 | default: |
1105 | if (ch != efc->escape_char) { | 1122 | if (ch != efc->escape_char) { |
1106 | buffer_put_char(bin, efc->escape_char); | 1123 | if ((r = sshbuf_put_u8(bin, |
1124 | efc->escape_char)) != 0) | ||
1125 | fatal("%s: buffer error: %s", | ||
1126 | __func__, ssh_err(r)); | ||
1107 | bytes++; | 1127 | bytes++; |
1108 | } | 1128 | } |
1109 | /* Escaped characters fall through here */ | 1129 | /* Escaped characters fall through here */ |
@@ -1129,7 +1149,8 @@ process_escapes(struct ssh *ssh, Channel *c, | |||
1129 | * and append it to the buffer. | 1149 | * and append it to the buffer. |
1130 | */ | 1150 | */ |
1131 | last_was_cr = (ch == '\r' || ch == '\n'); | 1151 | last_was_cr = (ch == '\r' || ch == '\n'); |
1132 | buffer_put_char(bin, ch); | 1152 | if ((r = sshbuf_put_u8(bin, ch)) != 0) |
1153 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1133 | bytes++; | 1154 | bytes++; |
1134 | } | 1155 | } |
1135 | return bytes; | 1156 | return bytes; |
@@ -1253,8 +1274,9 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | |||
1253 | 1274 | ||
1254 | quit_pending = 0; | 1275 | quit_pending = 0; |
1255 | 1276 | ||
1256 | /* Initialize buffers. */ | 1277 | /* Initialize buffer. */ |
1257 | buffer_init(&stderr_buffer); | 1278 | if ((stderr_buffer = sshbuf_new()) == NULL) |
1279 | fatal("%s: sshbuf_new failed", __func__); | ||
1258 | 1280 | ||
1259 | client_init_dispatch(); | 1281 | client_init_dispatch(); |
1260 | 1282 | ||
@@ -1411,24 +1433,25 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, | |||
1411 | * that the connection has been closed. | 1433 | * that the connection has been closed. |
1412 | */ | 1434 | */ |
1413 | if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { | 1435 | if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { |
1414 | snprintf(buf, sizeof buf, | 1436 | if ((r = sshbuf_putf(stderr_buffer, |
1415 | "Connection to %.64s closed.\r\n", host); | 1437 | "Connection to %.64s closed.\r\n", host)) != 0) |
1416 | buffer_append(&stderr_buffer, buf, strlen(buf)); | 1438 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1417 | } | 1439 | } |
1418 | 1440 | ||
1419 | /* Output any buffered data for stderr. */ | 1441 | /* Output any buffered data for stderr. */ |
1420 | if (buffer_len(&stderr_buffer) > 0) { | 1442 | if (sshbuf_len(stderr_buffer) > 0) { |
1421 | len = atomicio(vwrite, fileno(stderr), | 1443 | len = atomicio(vwrite, fileno(stderr), |
1422 | buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); | 1444 | (u_char *)sshbuf_ptr(stderr_buffer), |
1423 | if (len < 0 || (u_int)len != buffer_len(&stderr_buffer)) | 1445 | sshbuf_len(stderr_buffer)); |
1446 | if (len < 0 || (u_int)len != sshbuf_len(stderr_buffer)) | ||
1424 | error("Write failed flushing stderr buffer."); | 1447 | error("Write failed flushing stderr buffer."); |
1425 | else | 1448 | else if ((r = sshbuf_consume(stderr_buffer, len)) != 0) |
1426 | buffer_consume(&stderr_buffer, len); | 1449 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1427 | } | 1450 | } |
1428 | 1451 | ||
1429 | /* Clear and free any buffers. */ | 1452 | /* Clear and free any buffers. */ |
1430 | explicit_bzero(buf, sizeof(buf)); | 1453 | explicit_bzero(buf, sizeof(buf)); |
1431 | buffer_free(&stderr_buffer); | 1454 | sshbuf_free(stderr_buffer); |
1432 | 1455 | ||
1433 | /* Report bytes transferred, and transfer rates. */ | 1456 | /* Report bytes transferred, and transfer rates. */ |
1434 | total_time = monotime_double() - start_time; | 1457 | total_time = monotime_double() - start_time; |
@@ -2156,7 +2179,8 @@ client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) | |||
2156 | 2179 | ||
2157 | void | 2180 | void |
2158 | client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, | 2181 | client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, |
2159 | const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) | 2182 | const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, |
2183 | char **env) | ||
2160 | { | 2184 | { |
2161 | int i, j, matched, len; | 2185 | int i, j, matched, len; |
2162 | char *name, *val; | 2186 | char *name, *val; |
@@ -2242,23 +2266,23 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, | |||
2242 | free(name); | 2266 | free(name); |
2243 | } | 2267 | } |
2244 | 2268 | ||
2245 | len = buffer_len(cmd); | 2269 | len = sshbuf_len(cmd); |
2246 | if (len > 0) { | 2270 | if (len > 0) { |
2247 | if (len > 900) | 2271 | if (len > 900) |
2248 | len = 900; | 2272 | len = 900; |
2249 | if (want_subsystem) { | 2273 | if (want_subsystem) { |
2250 | debug("Sending subsystem: %.*s", | 2274 | debug("Sending subsystem: %.*s", |
2251 | len, (u_char*)buffer_ptr(cmd)); | 2275 | len, (const u_char*)sshbuf_ptr(cmd)); |
2252 | channel_request_start(ssh, id, "subsystem", 1); | 2276 | channel_request_start(ssh, id, "subsystem", 1); |
2253 | client_expect_confirm(ssh, id, "subsystem", | 2277 | client_expect_confirm(ssh, id, "subsystem", |
2254 | CONFIRM_CLOSE); | 2278 | CONFIRM_CLOSE); |
2255 | } else { | 2279 | } else { |
2256 | debug("Sending command: %.*s", | 2280 | debug("Sending command: %.*s", |
2257 | len, (u_char*)buffer_ptr(cmd)); | 2281 | len, (const u_char*)sshbuf_ptr(cmd)); |
2258 | channel_request_start(ssh, id, "exec", 1); | 2282 | channel_request_start(ssh, id, "exec", 1); |
2259 | client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); | 2283 | client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); |
2260 | } | 2284 | } |
2261 | packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); | 2285 | packet_put_string(sshbuf_ptr(cmd), sshbuf_len(cmd)); |
2262 | packet_send(); | 2286 | packet_send(); |
2263 | } else { | 2287 | } else { |
2264 | channel_request_start(ssh, id, "shell", 1); | 2288 | channel_request_start(ssh, id, "shell", 1); |
diff --git a/clientloop.h b/clientloop.h index 8d1f0bff6..bf79c87bf 100644 --- a/clientloop.h +++ b/clientloop.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.h,v 1.35 2017/10/23 05:08:00 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.h,v 1.36 2018/07/09 21:03:30 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -45,7 +45,7 @@ int client_x11_get_proto(struct ssh *, const char *, const char *, | |||
45 | u_int, u_int, char **, char **); | 45 | u_int, u_int, char **, char **); |
46 | void client_global_request_reply_fwd(int, u_int32_t, void *); | 46 | void client_global_request_reply_fwd(int, u_int32_t, void *); |
47 | void client_session2_setup(struct ssh *, int, int, int, | 47 | void client_session2_setup(struct ssh *, int, int, int, |
48 | const char *, struct termios *, int, Buffer *, char **); | 48 | const char *, struct termios *, int, struct sshbuf *, char **); |
49 | char *client_request_tun_fwd(struct ssh *, int, int, int); | 49 | char *client_request_tun_fwd(struct ssh *, int, int, int); |
50 | void client_stop_mux(void); | 50 | void client_stop_mux(void); |
51 | 51 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: compat.c,v 1.110 2018/07/04 13:49:31 djm Exp $ */ | 1 | /* $OpenBSD: compat.c,v 1.111 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -32,7 +32,6 @@ | |||
32 | #include <stdarg.h> | 32 | #include <stdarg.h> |
33 | 33 | ||
34 | #include "xmalloc.h" | 34 | #include "xmalloc.h" |
35 | #include "buffer.h" | ||
36 | #include "packet.h" | 35 | #include "packet.h" |
37 | #include "compat.h" | 36 | #include "compat.h" |
38 | #include "log.h" | 37 | #include "log.h" |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.71 2018/06/09 03:01:12 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.72 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -87,7 +87,7 @@ extern Options options; | |||
87 | extern int stdin_null_flag; | 87 | extern int stdin_null_flag; |
88 | extern char *host; | 88 | extern char *host; |
89 | extern int subsystem_flag; | 89 | extern int subsystem_flag; |
90 | extern Buffer command; | 90 | extern struct sshbuf *command; |
91 | extern volatile sig_atomic_t quit_pending; | 91 | extern volatile sig_atomic_t quit_pending; |
92 | 92 | ||
93 | /* Context for session open confirmation callback */ | 93 | /* Context for session open confirmation callback */ |
@@ -1887,7 +1887,7 @@ mux_client_request_session(int fd) | |||
1887 | buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ? | 1887 | buffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ? |
1888 | 0xffffffff : (u_int)options.escape_char); | 1888 | 0xffffffff : (u_int)options.escape_char); |
1889 | buffer_put_cstring(&m, term == NULL ? "" : term); | 1889 | buffer_put_cstring(&m, term == NULL ? "" : term); |
1890 | buffer_put_string(&m, buffer_ptr(&command), buffer_len(&command)); | 1890 | buffer_put_string(&m, buffer_ptr(command), buffer_len(command)); |
1891 | 1891 | ||
1892 | /* Pass environment */ | 1892 | /* Pass environment */ |
1893 | if (options.num_send_env > 0 && environ != NULL) { | 1893 | if (options.num_send_env > 0 && environ != NULL) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.275 2018/07/09 13:37:10 sf Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.276 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -63,9 +63,6 @@ | |||
63 | 63 | ||
64 | #include <zlib.h> | 64 | #include <zlib.h> |
65 | 65 | ||
66 | #include "buffer.h" /* typedefs XXX */ | ||
67 | #include "key.h" /* typedefs XXX */ | ||
68 | |||
69 | #include "xmalloc.h" | 66 | #include "xmalloc.h" |
70 | #include "crc32.h" | 67 | #include "crc32.h" |
71 | #include "compat.h" | 68 | #include "compat.h" |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.481 2018/06/08 03:35:36 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.482 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -87,7 +87,7 @@ | |||
87 | #include "cipher.h" | 87 | #include "cipher.h" |
88 | #include "digest.h" | 88 | #include "digest.h" |
89 | #include "packet.h" | 89 | #include "packet.h" |
90 | #include "buffer.h" | 90 | #include "sshbuf.h" |
91 | #include "channels.h" | 91 | #include "channels.h" |
92 | #include "key.h" | 92 | #include "key.h" |
93 | #include "authfd.h" | 93 | #include "authfd.h" |
@@ -183,7 +183,7 @@ uid_t original_real_uid; | |||
183 | uid_t original_effective_uid; | 183 | uid_t original_effective_uid; |
184 | 184 | ||
185 | /* command to be executed */ | 185 | /* command to be executed */ |
186 | Buffer command; | 186 | struct sshbuf *command; |
187 | 187 | ||
188 | /* Should we execute a command or invoke a subsystem? */ | 188 | /* Should we execute a command or invoke a subsystem? */ |
189 | int subsystem_flag = 0; | 189 | int subsystem_flag = 0; |
@@ -1042,7 +1042,8 @@ main(int ac, char **av) | |||
1042 | #endif | 1042 | #endif |
1043 | 1043 | ||
1044 | /* Initialize the command to execute on remote host. */ | 1044 | /* Initialize the command to execute on remote host. */ |
1045 | buffer_init(&command); | 1045 | if ((command = sshbuf_new()) == NULL) |
1046 | fatal("sshbuf_new failed"); | ||
1046 | 1047 | ||
1047 | /* | 1048 | /* |
1048 | * Save the command to execute on the remote host in a buffer. There | 1049 | * Save the command to execute on the remote host in a buffer. There |
@@ -1059,9 +1060,10 @@ main(int ac, char **av) | |||
1059 | } else { | 1060 | } else { |
1060 | /* A command has been specified. Store it into the buffer. */ | 1061 | /* A command has been specified. Store it into the buffer. */ |
1061 | for (i = 0; i < ac; i++) { | 1062 | for (i = 0; i < ac; i++) { |
1062 | if (i) | 1063 | if ((r = sshbuf_putf(command, "%s%s", |
1063 | buffer_append(&command, " ", 1); | 1064 | i ? " " : "", av[i])) != 0) |
1064 | buffer_append(&command, av[i], strlen(av[i])); | 1065 | fatal("%s: buffer error: %s", |
1066 | __func__, ssh_err(r)); | ||
1065 | } | 1067 | } |
1066 | } | 1068 | } |
1067 | 1069 | ||
@@ -1234,11 +1236,11 @@ main(int ac, char **av) | |||
1234 | options.use_privileged_port = 0; | 1236 | options.use_privileged_port = 0; |
1235 | #endif | 1237 | #endif |
1236 | 1238 | ||
1237 | if (buffer_len(&command) != 0 && options.remote_command != NULL) | 1239 | if (sshbuf_len(command) != 0 && options.remote_command != NULL) |
1238 | fatal("Cannot execute command-line and remote command."); | 1240 | fatal("Cannot execute command-line and remote command."); |
1239 | 1241 | ||
1240 | /* Cannot fork to background if no command. */ | 1242 | /* Cannot fork to background if no command. */ |
1241 | if (fork_after_authentication_flag && buffer_len(&command) == 0 && | 1243 | if (fork_after_authentication_flag && sshbuf_len(command) == 0 && |
1242 | options.remote_command == NULL && !no_shell_flag) | 1244 | options.remote_command == NULL && !no_shell_flag) |
1243 | fatal("Cannot fork into background without a command " | 1245 | fatal("Cannot fork into background without a command " |
1244 | "to execute."); | 1246 | "to execute."); |
@@ -1251,7 +1253,7 @@ main(int ac, char **av) | |||
1251 | tty_flag = 1; | 1253 | tty_flag = 1; |
1252 | 1254 | ||
1253 | /* Allocate a tty by default if no command specified. */ | 1255 | /* Allocate a tty by default if no command specified. */ |
1254 | if (buffer_len(&command) == 0 && options.remote_command == NULL) | 1256 | if (sshbuf_len(command) == 0 && options.remote_command == NULL) |
1255 | tty_flag = options.request_tty != REQUEST_TTY_NO; | 1257 | tty_flag = options.request_tty != REQUEST_TTY_NO; |
1256 | 1258 | ||
1257 | /* Force no tty */ | 1259 | /* Force no tty */ |
@@ -1313,8 +1315,9 @@ main(int ac, char **av) | |||
1313 | (char *)NULL); | 1315 | (char *)NULL); |
1314 | debug3("expanded RemoteCommand: %s", options.remote_command); | 1316 | debug3("expanded RemoteCommand: %s", options.remote_command); |
1315 | free(cp); | 1317 | free(cp); |
1316 | buffer_append(&command, options.remote_command, | 1318 | if ((r = sshbuf_put(command, options.remote_command, |
1317 | strlen(options.remote_command)); | 1319 | strlen(options.remote_command))) != 0) |
1320 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1318 | } | 1321 | } |
1319 | 1322 | ||
1320 | if (options.control_path != NULL) { | 1323 | if (options.control_path != NULL) { |
@@ -1846,7 +1849,7 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) | |||
1846 | options.ip_qos_interactive, options.ip_qos_bulk); | 1849 | options.ip_qos_interactive, options.ip_qos_bulk); |
1847 | 1850 | ||
1848 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), | 1851 | client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"), |
1849 | NULL, fileno(stdin), &command, environ); | 1852 | NULL, fileno(stdin), command, environ); |
1850 | } | 1853 | } |
1851 | 1854 | ||
1852 | /* open new channel for a session */ | 1855 | /* open new channel for a session */ |
diff --git a/sshconnect.c b/sshconnect.c index 32f9c8b3a..afe294660 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.298 2018/04/10 00:10:49 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.299 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -52,7 +52,7 @@ | |||
52 | #include "key.h" | 52 | #include "key.h" |
53 | #include "hostfile.h" | 53 | #include "hostfile.h" |
54 | #include "ssh.h" | 54 | #include "ssh.h" |
55 | #include "buffer.h" | 55 | #include "sshbuf.h" |
56 | #include "packet.h" | 56 | #include "packet.h" |
57 | #include "uidswap.h" | 57 | #include "uidswap.h" |
58 | #include "compat.h" | 58 | #include "compat.h" |
@@ -771,7 +771,7 @@ check_host_cert(const char *host, const struct sshkey *host_key) | |||
771 | error("%s", reason); | 771 | error("%s", reason); |
772 | return 0; | 772 | return 0; |
773 | } | 773 | } |
774 | if (buffer_len(host_key->cert->critical) != 0) { | 774 | if (sshbuf_len(host_key->cert->critical) != 0) { |
775 | error("Certificate for %s contains unsupported " | 775 | error("Certificate for %s contains unsupported " |
776 | "critical options(s)", host); | 776 | "critical options(s)", host); |
777 | return 0; | 777 | return 0; |
diff --git a/sshconnect2.c b/sshconnect2.c index 4bc0a7034..2194e3a8d 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.277 2018/07/09 13:37:10 sf Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.278 2018/07/09 21:03:30 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -49,11 +49,11 @@ | |||
49 | #include "xmalloc.h" | 49 | #include "xmalloc.h" |
50 | #include "ssh.h" | 50 | #include "ssh.h" |
51 | #include "ssh2.h" | 51 | #include "ssh2.h" |
52 | #include "buffer.h" | 52 | #include "sshbuf.h" |
53 | #include "packet.h" | 53 | #include "packet.h" |
54 | #include "compat.h" | 54 | #include "compat.h" |
55 | #include "cipher.h" | 55 | #include "cipher.h" |
56 | #include "key.h" | 56 | #include "sshkey.h" |
57 | #include "kex.h" | 57 | #include "kex.h" |
58 | #include "myproposal.h" | 58 | #include "myproposal.h" |
59 | #include "sshconnect.h" | 59 | #include "sshconnect.h" |
@@ -232,10 +232,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) | |||
232 | 232 | ||
233 | #ifdef DEBUG_KEXDH | 233 | #ifdef DEBUG_KEXDH |
234 | /* send 1st encrypted/maced/compressed message */ | 234 | /* send 1st encrypted/maced/compressed message */ |
235 | packet_start(SSH2_MSG_IGNORE); | 235 | if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || |
236 | packet_put_cstring("markus"); | 236 | (r = sshpkt_put_cstring(ssh, "markus")) != 0 || |
237 | packet_send(); | 237 | (r = sshpkt_send(ssh)) != 0) |
238 | packet_write_wait(); | 238 | fatal("%s: %s", __func__, ssh_err(r)); |
239 | ssh_packet_write_wait(ssh); | ||
239 | #endif | 240 | #endif |
240 | } | 241 | } |
241 | 242 | ||
@@ -457,6 +458,8 @@ input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) | |||
457 | void | 458 | void |
458 | userauth(Authctxt *authctxt, char *authlist) | 459 | userauth(Authctxt *authctxt, char *authlist) |
459 | { | 460 | { |
461 | struct ssh *ssh = active_state; /* XXX */ | ||
462 | |||
460 | if (authctxt->method != NULL && authctxt->method->cleanup != NULL) | 463 | if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
461 | authctxt->method->cleanup(authctxt); | 464 | authctxt->method->cleanup(authctxt); |
462 | 465 | ||
@@ -476,7 +479,7 @@ userauth(Authctxt *authctxt, char *authlist) | |||
476 | authctxt->method = method; | 479 | authctxt->method = method; |
477 | 480 | ||
478 | /* reset the per method handler */ | 481 | /* reset the per method handler */ |
479 | dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, | 482 | ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_PER_METHOD_MIN, |
480 | SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); | 483 | SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); |
481 | 484 | ||
482 | /* and try new method */ | 485 | /* and try new method */ |
@@ -553,14 +556,16 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
553 | { | 556 | { |
554 | Authctxt *authctxt = ssh->authctxt; | 557 | Authctxt *authctxt = ssh->authctxt; |
555 | char *authlist = NULL; | 558 | char *authlist = NULL; |
556 | int partial; | 559 | u_char partial; |
560 | int r; | ||
557 | 561 | ||
558 | if (authctxt == NULL) | 562 | if (authctxt == NULL) |
559 | fatal("input_userauth_failure: no authentication context"); | 563 | fatal("input_userauth_failure: no authentication context"); |
560 | 564 | ||
561 | authlist = packet_get_string(NULL); | 565 | if ((r = sshpkt_get_cstring(ssh, &authlist, NULL)) != 0 || |
562 | partial = packet_get_char(); | 566 | (r = sshpkt_get_u8(ssh, &partial)) != 0 || |
563 | packet_check_eom(); | 567 | (r = sshpkt_get_end(ssh)) != 0) |
568 | goto out; | ||
564 | 569 | ||
565 | if (partial != 0) { | 570 | if (partial != 0) { |
566 | verbose("Authenticated with partial success."); | 571 | verbose("Authenticated with partial success."); |
@@ -570,6 +575,9 @@ input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) | |||
570 | debug("Authentications that can continue: %s", authlist); | 575 | debug("Authentications that can continue: %s", authlist); |
571 | 576 | ||
572 | userauth(authctxt, authlist); | 577 | userauth(authctxt, authlist); |
578 | authlist = NULL; | ||
579 | out: | ||
580 | free(authlist); | ||
573 | return 0; | 581 | return 0; |
574 | } | 582 | } |
575 | 583 | ||
@@ -581,25 +589,27 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
581 | struct sshkey *key = NULL; | 589 | struct sshkey *key = NULL; |
582 | Identity *id = NULL; | 590 | Identity *id = NULL; |
583 | int pktype, sent = 0; | 591 | int pktype, sent = 0; |
584 | u_int alen, blen; | 592 | size_t blen; |
585 | char *pkalg, *fp; | 593 | char *pkalg = NULL, *fp; |
586 | u_char *pkblob; | 594 | u_char *pkblob = NULL; |
595 | int r; | ||
587 | 596 | ||
588 | if (authctxt == NULL) | 597 | if (authctxt == NULL) |
589 | fatal("input_userauth_pk_ok: no authentication context"); | 598 | fatal("input_userauth_pk_ok: no authentication context"); |
590 | 599 | ||
591 | pkalg = packet_get_string(&alen); | 600 | if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || |
592 | pkblob = packet_get_string(&blen); | 601 | (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 || |
593 | packet_check_eom(); | 602 | (r = sshpkt_get_end(ssh)) != 0) |
603 | goto done; | ||
594 | 604 | ||
595 | debug("Server accepts key: pkalg %s blen %u", pkalg, blen); | 605 | debug("Server accepts key: pkalg %s blen %zu", pkalg, blen); |
596 | 606 | ||
597 | if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { | 607 | if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) { |
598 | debug("unknown pkalg %s", pkalg); | 608 | debug("unknown pkalg %s", pkalg); |
599 | goto done; | 609 | goto done; |
600 | } | 610 | } |
601 | if ((key = key_from_blob(pkblob, blen)) == NULL) { | 611 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |
602 | debug("no key from blob. pkalg %s", pkalg); | 612 | debug("no key from blob. pkalg %s: %s", pkalg, ssh_err(r)); |
603 | goto done; | 613 | goto done; |
604 | } | 614 | } |
605 | if (key->type != pktype) { | 615 | if (key->type != pktype) { |
@@ -620,31 +630,33 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) | |||
620 | * duplicate keys | 630 | * duplicate keys |
621 | */ | 631 | */ |
622 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { | 632 | TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { |
623 | if (key_equal(key, id->key)) { | 633 | if (sshkey_equal(key, id->key)) { |
624 | sent = sign_and_send_pubkey(ssh, authctxt, id); | 634 | sent = sign_and_send_pubkey(ssh, authctxt, id); |
625 | break; | 635 | break; |
626 | } | 636 | } |
627 | } | 637 | } |
628 | done: | 638 | r = 0; |
629 | key_free(key); | 639 | done: |
640 | sshkey_free(key); | ||
630 | free(pkalg); | 641 | free(pkalg); |
631 | free(pkblob); | 642 | free(pkblob); |
632 | 643 | ||
633 | /* try another method if we did not send a packet */ | 644 | /* try another method if we did not send a packet */ |
634 | if (sent == 0) | 645 | if (r == 0 && sent == 0) |
635 | userauth(authctxt, NULL); | 646 | userauth(authctxt, NULL); |
636 | return 0; | 647 | return r; |
637 | } | 648 | } |
638 | 649 | ||
639 | #ifdef GSSAPI | 650 | #ifdef GSSAPI |
640 | int | 651 | int |
641 | userauth_gssapi(Authctxt *authctxt) | 652 | userauth_gssapi(Authctxt *authctxt) |
642 | { | 653 | { |
654 | struct ssh *ssh = active_state; /* XXX */ | ||
643 | Gssctxt *gssctxt = NULL; | 655 | Gssctxt *gssctxt = NULL; |
644 | static gss_OID_set gss_supported = NULL; | 656 | static gss_OID_set gss_supported = NULL; |
645 | static u_int mech = 0; | 657 | static u_int mech = 0; |
646 | OM_uint32 min; | 658 | OM_uint32 min; |
647 | int ok = 0; | 659 | int r, ok = 0; |
648 | 660 | ||
649 | /* Try one GSSAPI method at a time, rather than sending them all at | 661 | /* Try one GSSAPI method at a time, rather than sending them all at |
650 | * once. */ | 662 | * once. */ |
@@ -669,25 +681,26 @@ userauth_gssapi(Authctxt *authctxt) | |||
669 | 681 | ||
670 | authctxt->methoddata=(void *)gssctxt; | 682 | authctxt->methoddata=(void *)gssctxt; |
671 | 683 | ||
672 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 684 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
673 | packet_put_cstring(authctxt->server_user); | 685 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
674 | packet_put_cstring(authctxt->service); | 686 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
675 | packet_put_cstring(authctxt->method->name); | 687 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
676 | 688 | (r = sshpkt_put_u32(ssh, 1)) != 0 || | |
677 | packet_put_int(1); | 689 | (r = sshpkt_put_u32(ssh, |
678 | 690 | (gss_supported->elements[mech].length) + 2)) != 0 || | |
679 | packet_put_int((gss_supported->elements[mech].length) + 2); | 691 | (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || |
680 | packet_put_char(SSH_GSS_OIDTYPE); | 692 | (r = sshpkt_put_u8(ssh, |
681 | packet_put_char(gss_supported->elements[mech].length); | 693 | gss_supported->elements[mech].length)) != 0 || |
682 | packet_put_raw(gss_supported->elements[mech].elements, | 694 | (r = sshpkt_put(ssh, |
683 | gss_supported->elements[mech].length); | 695 | gss_supported->elements[mech].elements, |
684 | 696 | gss_supported->elements[mech].length)) != 0 || | |
685 | packet_send(); | 697 | (r = sshpkt_send(ssh)) != 0) |
698 | fatal("%s: %s", __func__, ssh_err(r)); | ||
686 | 699 | ||
687 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); | 700 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); |
688 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); | 701 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); |
689 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); | 702 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); |
690 | dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); | 703 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); |
691 | 704 | ||
692 | mech++; /* Move along to next candidate */ | 705 | mech++; /* Move along to next candidate */ |
693 | 706 | ||
@@ -703,44 +716,56 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) | |||
703 | gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; | 716 | gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; |
704 | gss_buffer_desc gssbuf; | 717 | gss_buffer_desc gssbuf; |
705 | OM_uint32 status, ms, flags; | 718 | OM_uint32 status, ms, flags; |
706 | Buffer b; | 719 | int r; |
707 | 720 | ||
708 | status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, | 721 | status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, |
709 | recv_tok, &send_tok, &flags); | 722 | recv_tok, &send_tok, &flags); |
710 | 723 | ||
711 | if (send_tok.length > 0) { | 724 | if (send_tok.length > 0) { |
712 | if (GSS_ERROR(status)) | 725 | u_char type = GSS_ERROR(status) ? |
713 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); | 726 | SSH2_MSG_USERAUTH_GSSAPI_ERRTOK : |
714 | else | 727 | SSH2_MSG_USERAUTH_GSSAPI_TOKEN; |
715 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); | 728 | |
729 | if ((r = sshpkt_start(ssh, type)) != 0 || | ||
730 | (r = sshpkt_put_string(ssh, send_tok.value, | ||
731 | send_tok.length)) != 0 || | ||
732 | (r = sshpkt_send(ssh)) != 0) | ||
733 | fatal("%s: %s", __func__, ssh_err(r)); | ||
716 | 734 | ||
717 | packet_put_string(send_tok.value, send_tok.length); | ||
718 | packet_send(); | ||
719 | gss_release_buffer(&ms, &send_tok); | 735 | gss_release_buffer(&ms, &send_tok); |
720 | } | 736 | } |
721 | 737 | ||
722 | if (status == GSS_S_COMPLETE) { | 738 | if (status == GSS_S_COMPLETE) { |
723 | /* send either complete or MIC, depending on mechanism */ | 739 | /* send either complete or MIC, depending on mechanism */ |
724 | if (!(flags & GSS_C_INTEG_FLAG)) { | 740 | if (!(flags & GSS_C_INTEG_FLAG)) { |
725 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); | 741 | if ((r = sshpkt_start(ssh, |
726 | packet_send(); | 742 | SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 || |
743 | (r = sshpkt_send(ssh)) != 0) | ||
744 | fatal("%s: %s", __func__, ssh_err(r)); | ||
727 | } else { | 745 | } else { |
728 | ssh_gssapi_buildmic(&b, authctxt->server_user, | 746 | struct sshbuf *b; |
747 | |||
748 | if ((b = sshbuf_new()) == NULL) | ||
749 | fatal("%s: sshbuf_new failed", __func__); | ||
750 | ssh_gssapi_buildmic(b, authctxt->server_user, | ||
729 | authctxt->service, "gssapi-with-mic"); | 751 | authctxt->service, "gssapi-with-mic"); |
730 | 752 | ||
731 | gssbuf.value = buffer_ptr(&b); | 753 | if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) |
732 | gssbuf.length = buffer_len(&b); | 754 | fatal("%s: sshbuf_mutable_ptr failed", __func__); |
755 | gssbuf.length = sshbuf_len(b); | ||
733 | 756 | ||
734 | status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); | 757 | status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); |
735 | 758 | ||
736 | if (!GSS_ERROR(status)) { | 759 | if (!GSS_ERROR(status)) { |
737 | packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); | 760 | if ((r = sshpkt_start(ssh, |
738 | packet_put_string(mic.value, mic.length); | 761 | SSH2_MSG_USERAUTH_GSSAPI_MIC)) != 0 || |
739 | 762 | (r = sshpkt_put_string(ssh, mic.value, | |
740 | packet_send(); | 763 | mic.length)) != 0 || |
764 | (r = sshpkt_send(ssh)) != 0) | ||
765 | fatal("%s: %s", __func__, ssh_err(r)); | ||
741 | } | 766 | } |
742 | 767 | ||
743 | buffer_free(&b); | 768 | sshbuf_free(b); |
744 | gss_release_buffer(&ms, &mic); | 769 | gss_release_buffer(&ms, &mic); |
745 | } | 770 | } |
746 | } | 771 | } |
@@ -754,39 +779,43 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) | |||
754 | { | 779 | { |
755 | Authctxt *authctxt = ssh->authctxt; | 780 | Authctxt *authctxt = ssh->authctxt; |
756 | Gssctxt *gssctxt; | 781 | Gssctxt *gssctxt; |
757 | int oidlen; | 782 | size_t oidlen; |
758 | char *oidv; | 783 | u_char *oidv = NULL; |
784 | int r; | ||
759 | 785 | ||
760 | if (authctxt == NULL) | 786 | if (authctxt == NULL) |
761 | fatal("input_gssapi_response: no authentication context"); | 787 | fatal("input_gssapi_response: no authentication context"); |
762 | gssctxt = authctxt->methoddata; | 788 | gssctxt = authctxt->methoddata; |
763 | 789 | ||
764 | /* Setup our OID */ | 790 | /* Setup our OID */ |
765 | oidv = packet_get_string(&oidlen); | 791 | if ((r = sshpkt_get_string(ssh, &oidv, &oidlen)) != 0) |
792 | goto done; | ||
766 | 793 | ||
767 | if (oidlen <= 2 || | 794 | if (oidlen <= 2 || |
768 | oidv[0] != SSH_GSS_OIDTYPE || | 795 | oidv[0] != SSH_GSS_OIDTYPE || |
769 | oidv[1] != oidlen - 2) { | 796 | oidv[1] != oidlen - 2) { |
770 | free(oidv); | ||
771 | debug("Badly encoded mechanism OID received"); | 797 | debug("Badly encoded mechanism OID received"); |
772 | userauth(authctxt, NULL); | 798 | userauth(authctxt, NULL); |
773 | return 0; | 799 | goto ok; |
774 | } | 800 | } |
775 | 801 | ||
776 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) | 802 | if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) |
777 | fatal("Server returned different OID than expected"); | 803 | fatal("Server returned different OID than expected"); |
778 | 804 | ||
779 | packet_check_eom(); | 805 | if ((r = sshpkt_get_end(ssh)) != 0) |
780 | 806 | goto done; | |
781 | free(oidv); | ||
782 | 807 | ||
783 | if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) { | 808 | if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) { |
784 | /* Start again with next method on list */ | 809 | /* Start again with next method on list */ |
785 | debug("Trying to start again"); | 810 | debug("Trying to start again"); |
786 | userauth(authctxt, NULL); | 811 | userauth(authctxt, NULL); |
787 | return 0; | 812 | goto ok; |
788 | } | 813 | } |
789 | return 0; | 814 | ok: |
815 | r = 0; | ||
816 | done: | ||
817 | free(oidv); | ||
818 | return r; | ||
790 | } | 819 | } |
791 | 820 | ||
792 | /* ARGSUSED */ | 821 | /* ARGSUSED */ |
@@ -795,27 +824,31 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) | |||
795 | { | 824 | { |
796 | Authctxt *authctxt = ssh->authctxt; | 825 | Authctxt *authctxt = ssh->authctxt; |
797 | gss_buffer_desc recv_tok; | 826 | gss_buffer_desc recv_tok; |
827 | u_char *p = NULL; | ||
828 | size_t len; | ||
798 | OM_uint32 status; | 829 | OM_uint32 status; |
799 | u_int slen; | 830 | int r; |
800 | 831 | ||
801 | if (authctxt == NULL) | 832 | if (authctxt == NULL) |
802 | fatal("input_gssapi_response: no authentication context"); | 833 | fatal("input_gssapi_response: no authentication context"); |
803 | 834 | ||
804 | recv_tok.value = packet_get_string(&slen); | 835 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
805 | recv_tok.length = slen; /* safe typecast */ | 836 | (r = sshpkt_get_end(ssh)) != 0) |
806 | 837 | goto out; | |
807 | packet_check_eom(); | ||
808 | 838 | ||
839 | recv_tok.value = p; | ||
840 | recv_tok.length = len; | ||
809 | status = process_gssapi_token(ssh, &recv_tok); | 841 | status = process_gssapi_token(ssh, &recv_tok); |
810 | 842 | ||
811 | free(recv_tok.value); | 843 | /* Start again with the next method in the list */ |
812 | |||
813 | if (GSS_ERROR(status)) { | 844 | if (GSS_ERROR(status)) { |
814 | /* Start again with the next method in the list */ | ||
815 | userauth(authctxt, NULL); | 845 | userauth(authctxt, NULL); |
816 | return 0; | 846 | /* ok */ |
817 | } | 847 | } |
818 | return 0; | 848 | r = 0; |
849 | out: | ||
850 | free(p); | ||
851 | return r; | ||
819 | } | 852 | } |
820 | 853 | ||
821 | /* ARGSUSED */ | 854 | /* ARGSUSED */ |
@@ -827,22 +860,26 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) | |||
827 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; | 860 | gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
828 | gss_buffer_desc recv_tok; | 861 | gss_buffer_desc recv_tok; |
829 | OM_uint32 ms; | 862 | OM_uint32 ms; |
830 | u_int len; | 863 | u_char *p = NULL; |
864 | size_t len; | ||
865 | int r; | ||
831 | 866 | ||
832 | if (authctxt == NULL) | 867 | if (authctxt == NULL) |
833 | fatal("input_gssapi_response: no authentication context"); | 868 | fatal("input_gssapi_response: no authentication context"); |
834 | gssctxt = authctxt->methoddata; | 869 | gssctxt = authctxt->methoddata; |
835 | 870 | ||
836 | recv_tok.value = packet_get_string(&len); | 871 | if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
837 | recv_tok.length = len; | 872 | (r = sshpkt_get_end(ssh)) != 0) { |
838 | 873 | free(p); | |
839 | packet_check_eom(); | 874 | return r; |
875 | } | ||
840 | 876 | ||
841 | /* Stick it into GSSAPI and see what it says */ | 877 | /* Stick it into GSSAPI and see what it says */ |
878 | recv_tok.value = p; | ||
879 | recv_tok.length = len; | ||
842 | (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, | 880 | (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, |
843 | &recv_tok, &send_tok, NULL); | 881 | &recv_tok, &send_tok, NULL); |
844 | 882 | free(p); | |
845 | free(recv_tok.value); | ||
846 | gss_release_buffer(&ms, &send_tok); | 883 | gss_release_buffer(&ms, &send_tok); |
847 | 884 | ||
848 | /* Server will be returning a failed packet after this one */ | 885 | /* Server will be returning a failed packet after this one */ |
@@ -853,43 +890,50 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) | |||
853 | int | 890 | int |
854 | input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) | 891 | input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) |
855 | { | 892 | { |
856 | char *msg; | 893 | char *msg = NULL; |
857 | char *lang; | 894 | char *lang = NULL; |
858 | 895 | int r; | |
859 | /* maj */(void)packet_get_int(); | ||
860 | /* min */(void)packet_get_int(); | ||
861 | msg=packet_get_string(NULL); | ||
862 | lang=packet_get_string(NULL); | ||
863 | |||
864 | packet_check_eom(); | ||
865 | 896 | ||
897 | if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* maj */ | ||
898 | (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* min */ | ||
899 | (r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 || | ||
900 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) | ||
901 | goto out; | ||
902 | r = sshpkt_get_end(ssh); | ||
866 | debug("Server GSSAPI Error:\n%s", msg); | 903 | debug("Server GSSAPI Error:\n%s", msg); |
904 | out: | ||
867 | free(msg); | 905 | free(msg); |
868 | free(lang); | 906 | free(lang); |
869 | return 0; | 907 | return r; |
870 | } | 908 | } |
871 | #endif /* GSSAPI */ | 909 | #endif /* GSSAPI */ |
872 | 910 | ||
873 | int | 911 | int |
874 | userauth_none(Authctxt *authctxt) | 912 | userauth_none(Authctxt *authctxt) |
875 | { | 913 | { |
914 | struct ssh *ssh = active_state; /* XXX */ | ||
915 | int r; | ||
916 | |||
876 | /* initial userauth request */ | 917 | /* initial userauth request */ |
877 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 918 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
878 | packet_put_cstring(authctxt->server_user); | 919 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
879 | packet_put_cstring(authctxt->service); | 920 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
880 | packet_put_cstring(authctxt->method->name); | 921 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
881 | packet_send(); | 922 | (r = sshpkt_send(ssh)) != 0) |
923 | fatal("%s: %s", __func__, ssh_err(r)); | ||
882 | return 1; | 924 | return 1; |
883 | } | 925 | } |
884 | 926 | ||
885 | int | 927 | int |
886 | userauth_passwd(Authctxt *authctxt) | 928 | userauth_passwd(Authctxt *authctxt) |
887 | { | 929 | { |
930 | struct ssh *ssh = active_state; /* XXX */ | ||
888 | static int attempt = 0; | 931 | static int attempt = 0; |
889 | char prompt[256]; | 932 | char prompt[256]; |
890 | char *password; | 933 | char *password; |
891 | const char *host = options.host_key_alias ? options.host_key_alias : | 934 | const char *host = options.host_key_alias ? options.host_key_alias : |
892 | authctxt->host; | 935 | authctxt->host; |
936 | int r; | ||
893 | 937 | ||
894 | if (attempt++ >= options.number_of_password_prompts) | 938 | if (attempt++ >= options.number_of_password_prompts) |
895 | return 0; | 939 | return 0; |
@@ -900,18 +944,20 @@ userauth_passwd(Authctxt *authctxt) | |||
900 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", | 944 | snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", |
901 | authctxt->server_user, host); | 945 | authctxt->server_user, host); |
902 | password = read_passphrase(prompt, 0); | 946 | password = read_passphrase(prompt, 0); |
903 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 947 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
904 | packet_put_cstring(authctxt->server_user); | 948 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
905 | packet_put_cstring(authctxt->service); | 949 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
906 | packet_put_cstring(authctxt->method->name); | 950 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
907 | packet_put_char(0); | 951 | (r = sshpkt_put_u8(ssh, 0)) != 0 || |
908 | packet_put_cstring(password); | 952 | (r = sshpkt_put_cstring(ssh, password)) != 0 || |
909 | explicit_bzero(password, strlen(password)); | 953 | (r = sshpkt_add_padding(ssh, 64)) != 0 || |
910 | free(password); | 954 | (r = sshpkt_send(ssh)) != 0) |
911 | packet_add_padding(64); | 955 | fatal("%s: %s", __func__, ssh_err(r)); |
912 | packet_send(); | 956 | |
913 | 957 | if (password) | |
914 | dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | 958 | freezero(password, strlen(password)); |
959 | |||
960 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | ||
915 | &input_userauth_passwd_changereq); | 961 | &input_userauth_passwd_changereq); |
916 | 962 | ||
917 | return 1; | 963 | return 1; |
@@ -925,9 +971,10 @@ int | |||
925 | input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | 971 | input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) |
926 | { | 972 | { |
927 | Authctxt *authctxt = ssh->authctxt; | 973 | Authctxt *authctxt = ssh->authctxt; |
928 | char *info, *lang, *password = NULL, *retype = NULL; | 974 | char *info = NULL, *lang = NULL, *password = NULL, *retype = NULL; |
929 | char prompt[256]; | 975 | char prompt[256]; |
930 | const char *host; | 976 | const char *host; |
977 | int r; | ||
931 | 978 | ||
932 | debug2("input_userauth_passwd_changereq"); | 979 | debug2("input_userauth_passwd_changereq"); |
933 | 980 | ||
@@ -936,24 +983,26 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | |||
936 | "no authentication context"); | 983 | "no authentication context"); |
937 | host = options.host_key_alias ? options.host_key_alias : authctxt->host; | 984 | host = options.host_key_alias ? options.host_key_alias : authctxt->host; |
938 | 985 | ||
939 | info = packet_get_string(NULL); | 986 | if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 || |
940 | lang = packet_get_string(NULL); | 987 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) |
988 | goto out; | ||
941 | if (strlen(info) > 0) | 989 | if (strlen(info) > 0) |
942 | logit("%s", info); | 990 | logit("%s", info); |
943 | free(info); | 991 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
944 | free(lang); | 992 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
945 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 993 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
946 | packet_put_cstring(authctxt->server_user); | 994 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
947 | packet_put_cstring(authctxt->service); | 995 | (r = sshpkt_put_u8(ssh, 1)) != 0) /* additional info */ |
948 | packet_put_cstring(authctxt->method->name); | 996 | goto out; |
949 | packet_put_char(1); /* additional info */ | 997 | |
950 | snprintf(prompt, sizeof(prompt), | 998 | snprintf(prompt, sizeof(prompt), |
951 | "Enter %.30s@%.128s's old password: ", | 999 | "Enter %.30s@%.128s's old password: ", |
952 | authctxt->server_user, host); | 1000 | authctxt->server_user, host); |
953 | password = read_passphrase(prompt, 0); | 1001 | password = read_passphrase(prompt, 0); |
954 | packet_put_cstring(password); | 1002 | if ((r = sshpkt_put_cstring(ssh, password)) != 0) |
955 | explicit_bzero(password, strlen(password)); | 1003 | goto out; |
956 | free(password); | 1004 | |
1005 | freezero(password, strlen(password)); | ||
957 | password = NULL; | 1006 | password = NULL; |
958 | while (password == NULL) { | 1007 | while (password == NULL) { |
959 | snprintf(prompt, sizeof(prompt), | 1008 | snprintf(prompt, sizeof(prompt), |
@@ -962,30 +1011,34 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) | |||
962 | password = read_passphrase(prompt, RP_ALLOW_EOF); | 1011 | password = read_passphrase(prompt, RP_ALLOW_EOF); |
963 | if (password == NULL) { | 1012 | if (password == NULL) { |
964 | /* bail out */ | 1013 | /* bail out */ |
965 | return 0; | 1014 | r = 0; |
1015 | goto out; | ||
966 | } | 1016 | } |
967 | snprintf(prompt, sizeof(prompt), | 1017 | snprintf(prompt, sizeof(prompt), |
968 | "Retype %.30s@%.128s's new password: ", | 1018 | "Retype %.30s@%.128s's new password: ", |
969 | authctxt->server_user, host); | 1019 | authctxt->server_user, host); |
970 | retype = read_passphrase(prompt, 0); | 1020 | retype = read_passphrase(prompt, 0); |
971 | if (strcmp(password, retype) != 0) { | 1021 | if (strcmp(password, retype) != 0) { |
972 | explicit_bzero(password, strlen(password)); | 1022 | freezero(password, strlen(password)); |
973 | free(password); | ||
974 | logit("Mismatch; try again, EOF to quit."); | 1023 | logit("Mismatch; try again, EOF to quit."); |
975 | password = NULL; | 1024 | password = NULL; |
976 | } | 1025 | } |
977 | explicit_bzero(retype, strlen(retype)); | 1026 | freezero(retype, strlen(retype)); |
978 | free(retype); | ||
979 | } | 1027 | } |
980 | packet_put_cstring(password); | 1028 | if ((r = sshpkt_put_cstring(ssh, password)) != 0 || |
981 | explicit_bzero(password, strlen(password)); | 1029 | (r = sshpkt_add_padding(ssh, 64)) != 0 || |
982 | free(password); | 1030 | (r = sshpkt_send(ssh)) != 0) |
983 | packet_add_padding(64); | 1031 | goto out; |
984 | packet_send(); | ||
985 | 1032 | ||
986 | dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, | 1033 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, |
987 | &input_userauth_passwd_changereq); | 1034 | &input_userauth_passwd_changereq); |
988 | return 0; | 1035 | r = 0; |
1036 | out: | ||
1037 | if (password) | ||
1038 | freezero(password, strlen(password)); | ||
1039 | free(info); | ||
1040 | free(lang); | ||
1041 | return r; | ||
989 | } | 1042 | } |
990 | 1043 | ||
991 | /* | 1044 | /* |
@@ -1192,7 +1245,7 @@ sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id) | |||
1192 | __func__, ssh_err(r)); | 1245 | __func__, ssh_err(r)); |
1193 | } | 1246 | } |
1194 | } | 1247 | } |
1195 | skip = buffer_len(b); | 1248 | skip = sshbuf_len(b); |
1196 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || | 1249 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1197 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || | 1250 | (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || |
1198 | (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || | 1251 | (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || |
@@ -1259,34 +1312,36 @@ static int | |||
1259 | send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) | 1312 | send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
1260 | { | 1313 | { |
1261 | u_char *blob = NULL; | 1314 | u_char *blob = NULL; |
1262 | u_int bloblen, have_sig = 0; | ||
1263 | char *alg = NULL; | 1315 | char *alg = NULL; |
1264 | int sent = 0; | 1316 | size_t bloblen; |
1317 | u_int have_sig = 0; | ||
1318 | int sent = 0, r; | ||
1265 | 1319 | ||
1266 | if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) { | 1320 | if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) { |
1267 | debug("%s: no mutual signature algorithm", __func__); | 1321 | debug("%s: no mutual signature algorithm", __func__); |
1268 | goto out; | 1322 | goto out; |
1269 | } | 1323 | } |
1270 | 1324 | ||
1271 | if (key_to_blob(id->key, &blob, &bloblen) == 0) { | 1325 | if ((r = sshkey_to_blob(id->key, &blob, &bloblen)) != 0) { |
1272 | /* we cannot handle this key */ | 1326 | /* we cannot handle this key */ |
1273 | debug3("%s: cannot handle key", __func__); | 1327 | debug3("%s: cannot handle key", __func__); |
1274 | goto out; | 1328 | goto out; |
1275 | } | 1329 | } |
1276 | /* register callback for USERAUTH_PK_OK message */ | 1330 | /* register callback for USERAUTH_PK_OK message */ |
1277 | dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); | 1331 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); |
1278 | 1332 | ||
1279 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1333 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1280 | packet_put_cstring(authctxt->server_user); | 1334 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
1281 | packet_put_cstring(authctxt->service); | 1335 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
1282 | packet_put_cstring(authctxt->method->name); | 1336 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
1283 | packet_put_char(have_sig); | 1337 | (r = sshpkt_put_u8(ssh, have_sig)) != 0 || |
1284 | packet_put_cstring(alg); | 1338 | (r = sshpkt_put_cstring(ssh, alg)) != 0 || |
1285 | packet_put_string(blob, bloblen); | 1339 | (r = sshpkt_put_string(ssh, blob, bloblen)) != 0 || |
1286 | packet_send(); | 1340 | (r = sshpkt_send(ssh)) != 0) |
1287 | /* success */ | 1341 | fatal("%s: %s", __func__, ssh_err(r)); |
1288 | sent = 1; | 1342 | sent = 1; |
1289 | out: | 1343 | |
1344 | out: | ||
1290 | free(alg); | 1345 | free(alg); |
1291 | free(blob); | 1346 | free(blob); |
1292 | return sent; | 1347 | return sent; |
@@ -1347,10 +1402,8 @@ load_identity_file(Identity *id) | |||
1347 | !(id->key && id->isprivate)) | 1402 | !(id->key && id->isprivate)) |
1348 | maybe_add_key_to_agent(id->filename, private, comment, | 1403 | maybe_add_key_to_agent(id->filename, private, comment, |
1349 | passphrase); | 1404 | passphrase); |
1350 | if (i > 0) { | 1405 | if (i > 0) |
1351 | explicit_bzero(passphrase, strlen(passphrase)); | 1406 | freezero(passphrase, strlen(passphrase)); |
1352 | free(passphrase); | ||
1353 | } | ||
1354 | free(comment); | 1407 | free(comment); |
1355 | if (private != NULL || quit) | 1408 | if (private != NULL || quit) |
1356 | break; | 1409 | break; |
@@ -1427,7 +1480,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1427 | /* list of certificates specified by user */ | 1480 | /* list of certificates specified by user */ |
1428 | for (i = 0; i < options.num_certificate_files; i++) { | 1481 | for (i = 0; i < options.num_certificate_files; i++) { |
1429 | key = options.certificates[i]; | 1482 | key = options.certificates[i]; |
1430 | if (!key_is_cert(key) || key->cert == NULL || | 1483 | if (!sshkey_is_cert(key) || key->cert == NULL || |
1431 | key->cert->type != SSH2_CERT_TYPE_USER) | 1484 | key->cert->type != SSH2_CERT_TYPE_USER) |
1432 | continue; | 1485 | continue; |
1433 | id = xcalloc(1, sizeof(*id)); | 1486 | id = xcalloc(1, sizeof(*id)); |
@@ -1501,8 +1554,7 @@ pubkey_prepare(Authctxt *authctxt) | |||
1501 | /* If IdentitiesOnly set and key not found then don't use it */ | 1554 | /* If IdentitiesOnly set and key not found then don't use it */ |
1502 | if (!found && options.identities_only) { | 1555 | if (!found && options.identities_only) { |
1503 | TAILQ_REMOVE(&files, id, next); | 1556 | TAILQ_REMOVE(&files, id, next); |
1504 | explicit_bzero(id, sizeof(*id)); | 1557 | freezero(id, sizeof(*id)); |
1505 | free(id); | ||
1506 | } | 1558 | } |
1507 | } | 1559 | } |
1508 | /* append remaining keys from the config file */ | 1560 | /* append remaining keys from the config file */ |
@@ -1609,7 +1661,7 @@ userauth_pubkey(Authctxt *authctxt) | |||
1609 | sent = sign_and_send_pubkey(ssh, | 1661 | sent = sign_and_send_pubkey(ssh, |
1610 | authctxt, id); | 1662 | authctxt, id); |
1611 | } | 1663 | } |
1612 | key_free(id->key); | 1664 | sshkey_free(id->key); |
1613 | id->key = NULL; | 1665 | id->key = NULL; |
1614 | id->isprivate = 0; | 1666 | id->isprivate = 0; |
1615 | } | 1667 | } |
@@ -1626,28 +1678,31 @@ userauth_pubkey(Authctxt *authctxt) | |||
1626 | int | 1678 | int |
1627 | userauth_kbdint(Authctxt *authctxt) | 1679 | userauth_kbdint(Authctxt *authctxt) |
1628 | { | 1680 | { |
1681 | struct ssh *ssh = active_state; /* XXX */ | ||
1629 | static int attempt = 0; | 1682 | static int attempt = 0; |
1683 | int r; | ||
1630 | 1684 | ||
1631 | if (attempt++ >= options.number_of_password_prompts) | 1685 | if (attempt++ >= options.number_of_password_prompts) |
1632 | return 0; | 1686 | return 0; |
1633 | /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ | 1687 | /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ |
1634 | if (attempt > 1 && !authctxt->info_req_seen) { | 1688 | if (attempt > 1 && !authctxt->info_req_seen) { |
1635 | debug3("userauth_kbdint: disable: no info_req_seen"); | 1689 | debug3("userauth_kbdint: disable: no info_req_seen"); |
1636 | dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); | 1690 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); |
1637 | return 0; | 1691 | return 0; |
1638 | } | 1692 | } |
1639 | 1693 | ||
1640 | debug2("userauth_kbdint"); | 1694 | debug2("userauth_kbdint"); |
1641 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1695 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
1642 | packet_put_cstring(authctxt->server_user); | 1696 | (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || |
1643 | packet_put_cstring(authctxt->service); | 1697 | (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
1644 | packet_put_cstring(authctxt->method->name); | 1698 | (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
1645 | packet_put_cstring(""); /* lang */ | 1699 | (r = sshpkt_put_cstring(ssh, "")) != 0 || /* lang */ |
1646 | packet_put_cstring(options.kbd_interactive_devices ? | 1700 | (r = sshpkt_put_cstring(ssh, options.kbd_interactive_devices ? |
1647 | options.kbd_interactive_devices : ""); | 1701 | options.kbd_interactive_devices : "")) != 0 || |
1648 | packet_send(); | 1702 | (r = sshpkt_send(ssh)) != 0) |
1649 | 1703 | fatal("%s: %s", __func__, ssh_err(r)); | |
1650 | dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); | 1704 | |
1705 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); | ||
1651 | return 1; | 1706 | return 1; |
1652 | } | 1707 | } |
1653 | 1708 | ||
@@ -1658,9 +1713,11 @@ int | |||
1658 | input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) | 1713 | input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) |
1659 | { | 1714 | { |
1660 | Authctxt *authctxt = ssh->authctxt; | 1715 | Authctxt *authctxt = ssh->authctxt; |
1661 | char *name, *inst, *lang, *prompt, *response; | 1716 | char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL; |
1717 | char *response = NULL; | ||
1718 | u_char echo = 0; | ||
1662 | u_int num_prompts, i; | 1719 | u_int num_prompts, i; |
1663 | int echo = 0; | 1720 | int r; |
1664 | 1721 | ||
1665 | debug2("input_userauth_info_req"); | 1722 | debug2("input_userauth_info_req"); |
1666 | 1723 | ||
@@ -1669,44 +1726,52 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) | |||
1669 | 1726 | ||
1670 | authctxt->info_req_seen = 1; | 1727 | authctxt->info_req_seen = 1; |
1671 | 1728 | ||
1672 | name = packet_get_string(NULL); | 1729 | if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 || |
1673 | inst = packet_get_string(NULL); | 1730 | (r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 || |
1674 | lang = packet_get_string(NULL); | 1731 | (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) |
1732 | goto out; | ||
1675 | if (strlen(name) > 0) | 1733 | if (strlen(name) > 0) |
1676 | logit("%s", name); | 1734 | logit("%s", name); |
1677 | if (strlen(inst) > 0) | 1735 | if (strlen(inst) > 0) |
1678 | logit("%s", inst); | 1736 | logit("%s", inst); |
1679 | free(name); | ||
1680 | free(inst); | ||
1681 | free(lang); | ||
1682 | 1737 | ||
1683 | num_prompts = packet_get_int(); | 1738 | if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0) |
1739 | goto out; | ||
1684 | /* | 1740 | /* |
1685 | * Begin to build info response packet based on prompts requested. | 1741 | * Begin to build info response packet based on prompts requested. |
1686 | * We commit to providing the correct number of responses, so if | 1742 | * We commit to providing the correct number of responses, so if |
1687 | * further on we run into a problem that prevents this, we have to | 1743 | * further on we run into a problem that prevents this, we have to |
1688 | * be sure and clean this up and send a correct error response. | 1744 | * be sure and clean this up and send a correct error response. |
1689 | */ | 1745 | */ |
1690 | packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); | 1746 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE)) != 0 || |
1691 | packet_put_int(num_prompts); | 1747 | (r = sshpkt_put_u32(ssh, num_prompts)) != 0) |
1748 | goto out; | ||
1692 | 1749 | ||
1693 | debug2("input_userauth_info_req: num_prompts %d", num_prompts); | 1750 | debug2("input_userauth_info_req: num_prompts %d", num_prompts); |
1694 | for (i = 0; i < num_prompts; i++) { | 1751 | for (i = 0; i < num_prompts; i++) { |
1695 | prompt = packet_get_string(NULL); | 1752 | if ((r = sshpkt_get_cstring(ssh, &prompt, NULL)) != 0 || |
1696 | echo = packet_get_char(); | 1753 | (r = sshpkt_get_u8(ssh, &echo)) != 0) |
1697 | 1754 | goto out; | |
1698 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); | 1755 | response = read_passphrase(prompt, echo ? RP_ECHO : 0); |
1699 | 1756 | if ((r = sshpkt_put_cstring(ssh, response)) != 0) | |
1700 | packet_put_cstring(response); | 1757 | goto out; |
1701 | explicit_bzero(response, strlen(response)); | 1758 | freezero(response, strlen(response)); |
1702 | free(response); | ||
1703 | free(prompt); | 1759 | free(prompt); |
1760 | response = prompt = NULL; | ||
1704 | } | 1761 | } |
1705 | packet_check_eom(); /* done with parsing incoming message. */ | 1762 | /* done with parsing incoming message. */ |
1706 | 1763 | if ((r = sshpkt_get_end(ssh)) != 0 || | |
1707 | packet_add_padding(64); | 1764 | (r = sshpkt_add_padding(ssh, 64)) != 0) |
1708 | packet_send(); | 1765 | goto out; |
1709 | return 0; | 1766 | r = sshpkt_send(ssh); |
1767 | out: | ||
1768 | if (response) | ||
1769 | freezero(response, strlen(response)); | ||
1770 | free(prompt); | ||
1771 | free(name); | ||
1772 | free(inst); | ||
1773 | free(lang); | ||
1774 | return r; | ||
1710 | } | 1775 | } |
1711 | 1776 | ||
1712 | static int | 1777 | static int |
@@ -1952,10 +2017,8 @@ userauth_hostbased(Authctxt *authctxt) | |||
1952 | success = 1; | 2017 | success = 1; |
1953 | 2018 | ||
1954 | out: | 2019 | out: |
1955 | if (sig != NULL) { | 2020 | if (sig != NULL) |
1956 | explicit_bzero(sig, siglen); | 2021 | freezero(sig, siglen); |
1957 | free(sig); | ||
1958 | } | ||
1959 | free(keyblob); | 2022 | free(keyblob); |
1960 | free(lname); | 2023 | free(lname); |
1961 | free(fp); | 2024 | free(fp); |
@@ -2052,20 +2115,22 @@ static char * | |||
2052 | authmethods_get(void) | 2115 | authmethods_get(void) |
2053 | { | 2116 | { |
2054 | Authmethod *method = NULL; | 2117 | Authmethod *method = NULL; |
2055 | Buffer b; | 2118 | struct sshbuf *b; |
2056 | char *list; | 2119 | char *list; |
2120 | int r; | ||
2057 | 2121 | ||
2058 | buffer_init(&b); | 2122 | if ((b = sshbuf_new()) == NULL) |
2123 | fatal("%s: sshbuf_new failed", __func__); | ||
2059 | for (method = authmethods; method->name != NULL; method++) { | 2124 | for (method = authmethods; method->name != NULL; method++) { |
2060 | if (authmethod_is_enabled(method)) { | 2125 | if (authmethod_is_enabled(method)) { |
2061 | if (buffer_len(&b) > 0) | 2126 | if ((r = sshbuf_putf(b, "%s%s", |
2062 | buffer_append(&b, ",", 1); | 2127 | sshbuf_len(b) ? "," : "", method->name)) != 0) |
2063 | buffer_append(&b, method->name, strlen(method->name)); | 2128 | fatal("%s: buffer error: %s", |
2129 | __func__, ssh_err(r)); | ||
2064 | } | 2130 | } |
2065 | } | 2131 | } |
2066 | if ((list = sshbuf_dup_string(&b)) == NULL) | 2132 | if ((list = sshbuf_dup_string(b)) == NULL) |
2067 | fatal("%s: sshbuf_dup_string failed", __func__); | 2133 | fatal("%s: sshbuf_dup_string failed", __func__); |
2068 | buffer_free(&b); | 2134 | sshbuf_free(b); |
2069 | return list; | 2135 | return list; |
2070 | } | 2136 | } |
2071 | |||