summaryrefslogtreecommitdiff
path: root/clientloop.c
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 /clientloop.c
parentff55f4ad898137d4703e7a2bcc81167dfe8e9324 (diff)
upstream: client: switch to sshbuf API; ok djm@
OpenBSD-Commit-ID: 60cb0356114acc7625ab85105f6f6a7cd44a8d05
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c202
1 files changed, 113 insertions, 89 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);