summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2018-07-09 21:03:30 +0000
committerDamien Miller <djm@mindrot.org>2018-07-10 15:14:26 +1000
commitcecee2d607099a7bba0a84803e2325d15be4277b (patch)
treee5f685fb39c9d8512235334afc4b26e8461bfc36
parentff55f4ad898137d4703e7a2bcc81167dfe8e9324 (diff)
upstream: client: switch to sshbuf API; ok djm@
OpenBSD-Commit-ID: 60cb0356114acc7625ab85105f6f6a7cd44a8d05
-rw-r--r--clientloop.c202
-rw-r--r--clientloop.h4
-rw-r--r--compat.c3
-rw-r--r--mux.c6
-rw-r--r--packet.c5
-rw-r--r--ssh.c29
-rw-r--r--sshconnect.c6
-rw-r--r--sshconnect2.c489
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;
153volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 153volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
154static int last_was_cr; /* Last character was a newline. */ 154static int last_was_cr; /* Last character was a newline. */
155static int exit_status; /* Used to store the command exit status. */ 155static int exit_status; /* Used to store the command exit status. */
156static Buffer stderr_buffer; /* Used for final exit message. */ 156static struct sshbuf *stderr_buffer; /* Used for final exit message. */
157static int connection_in; /* Connection to server (input). */ 157static int connection_in; /* Connection to server (input). */
158static int connection_out; /* Connection to server (output). */ 158static int connection_out; /* Connection to server (output). */
159static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 159static int need_rekeying; /* Set to non-zero if rekeying is requested. */
@@ -188,7 +188,7 @@ TAILQ_HEAD(global_confirms, global_confirm);
188static struct global_confirms global_confirms = 188static struct global_confirms global_confirms =
189 TAILQ_HEAD_INITIALIZER(global_confirms); 189 TAILQ_HEAD_INITIALIZER(global_confirms);
190 190
191void ssh_process_session2_setup(int, int, int, Buffer *); 191void 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
576static void 575static void
577client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) 576client_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)
602static void 601static void
603client_process_net_input(fd_set *readset) 602client_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
894static void 898static void
895print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr) 899print_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 */
927static int 932static int
928process_escapes(struct ssh *ssh, Channel *c, 933process_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
2157void 2180void
2158client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, 2181client_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 **);
46void client_global_request_reply_fwd(int, u_int32_t, void *); 46void client_global_request_reply_fwd(int, u_int32_t, void *);
47void client_session2_setup(struct ssh *, int, int, int, 47void 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 **);
49char *client_request_tun_fwd(struct ssh *, int, int, int); 49char *client_request_tun_fwd(struct ssh *, int, int, int);
50void client_stop_mux(void); 50void client_stop_mux(void);
51 51
diff --git a/compat.c b/compat.c
index d8fd6eaf8..d0afe9084 100644
--- a/compat.c
+++ b/compat.c
@@ -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"
diff --git a/mux.c b/mux.c
index 8433cd8e5..474d610a3 100644
--- a/mux.c
+++ b/mux.c
@@ -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;
87extern int stdin_null_flag; 87extern int stdin_null_flag;
88extern char *host; 88extern char *host;
89extern int subsystem_flag; 89extern int subsystem_flag;
90extern Buffer command; 90extern struct sshbuf *command;
91extern volatile sig_atomic_t quit_pending; 91extern 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) {
diff --git a/packet.c b/packet.c
index 4d91792e0..cacb6eebe 100644
--- a/packet.c
+++ b/packet.c
@@ -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"
diff --git a/ssh.c b/ssh.c
index fe3e1a83a..914167789 100644
--- a/ssh.c
+++ b/ssh.c
@@ -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;
183uid_t original_effective_uid; 183uid_t original_effective_uid;
184 184
185/* command to be executed */ 185/* command to be executed */
186Buffer command; 186struct sshbuf *command;
187 187
188/* Should we execute a command or invoke a subsystem? */ 188/* Should we execute a command or invoke a subsystem? */
189int subsystem_flag = 0; 189int 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)
457void 458void
458userauth(Authctxt *authctxt, char *authlist) 459userauth(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 }
628done: 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
640int 651int
641userauth_gssapi(Authctxt *authctxt) 652userauth_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)
853int 890int
854input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) 891input_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
873int 911int
874userauth_none(Authctxt *authctxt) 912userauth_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
885int 927int
886userauth_passwd(Authctxt *authctxt) 928userauth_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
925input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) 971input_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
1259send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) 1312send_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;
1289out: 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)
1626int 1678int
1627userauth_kbdint(Authctxt *authctxt) 1679userauth_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
1658input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) 1713input_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
1712static int 1777static 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 *
2052authmethods_get(void) 2115authmethods_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