xref: /netbsd-src/crypto/external/bsd/openssh/dist/ttymodes.c (revision 17418e98f281f84e3d22de9717222f9c2ee84d3a)
1*17418e98Schristos /*	$NetBSD: ttymodes.c,v 1.12 2021/03/05 17:47:16 christos Exp $	*/
2*17418e98Schristos /* $OpenBSD: ttymodes.c,v 1.36 2021/01/27 09:26:54 djm Exp $ */
355a4608bSchristos 
4ca32bd8dSchristos /*
5ca32bd8dSchristos  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6ca32bd8dSchristos  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
7ca32bd8dSchristos  *                    All rights reserved
8ca32bd8dSchristos  *
9ca32bd8dSchristos  * As far as I am concerned, the code I have written for this software
10ca32bd8dSchristos  * can be used freely for any purpose.  Any derived versions of this
11ca32bd8dSchristos  * software must be clearly marked as such, and if the derived work is
12ca32bd8dSchristos  * incompatible with the protocol description in the RFC file, it must be
13ca32bd8dSchristos  * called by a name other than "ssh" or "Secure Shell".
14ca32bd8dSchristos  */
15ca32bd8dSchristos 
16ca32bd8dSchristos /*
17ca32bd8dSchristos  * SSH2 tty modes support by Kevin Steves.
18ca32bd8dSchristos  * Copyright (c) 2001 Kevin Steves.  All rights reserved.
19ca32bd8dSchristos  *
20ca32bd8dSchristos  * Redistribution and use in source and binary forms, with or without
21ca32bd8dSchristos  * modification, are permitted provided that the following conditions
22ca32bd8dSchristos  * are met:
23ca32bd8dSchristos  * 1. Redistributions of source code must retain the above copyright
24ca32bd8dSchristos  *    notice, this list of conditions and the following disclaimer.
25ca32bd8dSchristos  * 2. Redistributions in binary form must reproduce the above copyright
26ca32bd8dSchristos  *    notice, this list of conditions and the following disclaimer in the
27ca32bd8dSchristos  *    documentation and/or other materials provided with the distribution.
28ca32bd8dSchristos  *
29ca32bd8dSchristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
30ca32bd8dSchristos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31ca32bd8dSchristos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32ca32bd8dSchristos  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33ca32bd8dSchristos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
34ca32bd8dSchristos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35ca32bd8dSchristos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36ca32bd8dSchristos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37ca32bd8dSchristos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38ca32bd8dSchristos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39ca32bd8dSchristos  */
40ca32bd8dSchristos 
41ca32bd8dSchristos /*
42ca32bd8dSchristos  * Encoding and decoding of terminal modes in a portable way.
43ca32bd8dSchristos  * Much of the format is defined in ttymodes.h; it is included multiple times
44ca32bd8dSchristos  * into this file with the appropriate macro definitions to generate the
45ca32bd8dSchristos  * suitable code.
46ca32bd8dSchristos  */
47ca32bd8dSchristos 
48313c6c94Schristos #include "includes.h"
49*17418e98Schristos __RCSID("$NetBSD: ttymodes.c,v 1.12 2021/03/05 17:47:16 christos Exp $");
50ca32bd8dSchristos #include <sys/types.h>
51ca32bd8dSchristos 
52ca32bd8dSchristos #include <errno.h>
53ca32bd8dSchristos #include <string.h>
54ca32bd8dSchristos #include <termios.h>
55ca32bd8dSchristos #include <stdarg.h>
56ca32bd8dSchristos 
57ca32bd8dSchristos #include "packet.h"
58ca32bd8dSchristos #include "log.h"
59ca32bd8dSchristos #include "compat.h"
6055a4608bSchristos #include "sshbuf.h"
6155a4608bSchristos #include "ssherr.h"
62ca32bd8dSchristos 
63ca32bd8dSchristos #define TTY_OP_END		0
64ca32bd8dSchristos /*
657a183406Schristos  * uint32 (u_int) follows speed.
66ca32bd8dSchristos  */
677a183406Schristos #define TTY_OP_ISPEED	128
687a183406Schristos #define TTY_OP_OSPEED	129
69ca32bd8dSchristos 
70ca32bd8dSchristos /*
71ca32bd8dSchristos  * Converts POSIX speed_t to a baud rate.  The values of the
72ca32bd8dSchristos  * constants for speed_t are not themselves portable.
73ca32bd8dSchristos  */
74ca32bd8dSchristos static int
speed_to_baud(speed_t speed)75ca32bd8dSchristos speed_to_baud(speed_t speed)
76ca32bd8dSchristos {
77ca32bd8dSchristos 	switch (speed) {
78ca32bd8dSchristos 	case B0:
79ca32bd8dSchristos 		return 0;
80ca32bd8dSchristos 	case B50:
81ca32bd8dSchristos 		return 50;
82ca32bd8dSchristos 	case B75:
83ca32bd8dSchristos 		return 75;
84ca32bd8dSchristos 	case B110:
85ca32bd8dSchristos 		return 110;
86ca32bd8dSchristos 	case B134:
87ca32bd8dSchristos 		return 134;
88ca32bd8dSchristos 	case B150:
89ca32bd8dSchristos 		return 150;
90ca32bd8dSchristos 	case B200:
91ca32bd8dSchristos 		return 200;
92ca32bd8dSchristos 	case B300:
93ca32bd8dSchristos 		return 300;
94ca32bd8dSchristos 	case B600:
95ca32bd8dSchristos 		return 600;
96ca32bd8dSchristos 	case B1200:
97ca32bd8dSchristos 		return 1200;
98ca32bd8dSchristos 	case B1800:
99ca32bd8dSchristos 		return 1800;
100ca32bd8dSchristos 	case B2400:
101ca32bd8dSchristos 		return 2400;
102ca32bd8dSchristos 	case B4800:
103ca32bd8dSchristos 		return 4800;
104ca32bd8dSchristos 	case B9600:
105ca32bd8dSchristos 		return 9600;
106ca32bd8dSchristos 
107ca32bd8dSchristos #ifdef B19200
108ca32bd8dSchristos 	case B19200:
109ca32bd8dSchristos 		return 19200;
110ca32bd8dSchristos #else /* B19200 */
111ca32bd8dSchristos #ifdef EXTA
112ca32bd8dSchristos 	case EXTA:
113ca32bd8dSchristos 		return 19200;
114ca32bd8dSchristos #endif /* EXTA */
115ca32bd8dSchristos #endif /* B19200 */
116ca32bd8dSchristos 
117ca32bd8dSchristos #ifdef B38400
118ca32bd8dSchristos 	case B38400:
119ca32bd8dSchristos 		return 38400;
120ca32bd8dSchristos #else /* B38400 */
121ca32bd8dSchristos #ifdef EXTB
122ca32bd8dSchristos 	case EXTB:
123ca32bd8dSchristos 		return 38400;
124ca32bd8dSchristos #endif /* EXTB */
125ca32bd8dSchristos #endif /* B38400 */
126ca32bd8dSchristos 
127ca32bd8dSchristos #ifdef B7200
128ca32bd8dSchristos 	case B7200:
129ca32bd8dSchristos 		return 7200;
130ca32bd8dSchristos #endif /* B7200 */
131ca32bd8dSchristos #ifdef B14400
132ca32bd8dSchristos 	case B14400:
133ca32bd8dSchristos 		return 14400;
134ca32bd8dSchristos #endif /* B14400 */
135ca32bd8dSchristos #ifdef B28800
136ca32bd8dSchristos 	case B28800:
137ca32bd8dSchristos 		return 28800;
138ca32bd8dSchristos #endif /* B28800 */
139ca32bd8dSchristos #ifdef B57600
140ca32bd8dSchristos 	case B57600:
141ca32bd8dSchristos 		return 57600;
142ca32bd8dSchristos #endif /* B57600 */
143ca32bd8dSchristos #ifdef B76800
144ca32bd8dSchristos 	case B76800:
145ca32bd8dSchristos 		return 76800;
146ca32bd8dSchristos #endif /* B76800 */
147ca32bd8dSchristos #ifdef B115200
148ca32bd8dSchristos 	case B115200:
149ca32bd8dSchristos 		return 115200;
150ca32bd8dSchristos #endif /* B115200 */
151ca32bd8dSchristos #ifdef B230400
152ca32bd8dSchristos 	case B230400:
153ca32bd8dSchristos 		return 230400;
154ca32bd8dSchristos #endif /* B230400 */
155ca32bd8dSchristos 	default:
156ca32bd8dSchristos 		return 9600;
157ca32bd8dSchristos 	}
158ca32bd8dSchristos }
159ca32bd8dSchristos 
160ca32bd8dSchristos /*
161ca32bd8dSchristos  * Converts a numeric baud rate to a POSIX speed_t.
162ca32bd8dSchristos  */
163ca32bd8dSchristos static speed_t
baud_to_speed(int baud)164ca32bd8dSchristos baud_to_speed(int baud)
165ca32bd8dSchristos {
166ca32bd8dSchristos 	switch (baud) {
167ca32bd8dSchristos 	case 0:
168ca32bd8dSchristos 		return B0;
169ca32bd8dSchristos 	case 50:
170ca32bd8dSchristos 		return B50;
171ca32bd8dSchristos 	case 75:
172ca32bd8dSchristos 		return B75;
173ca32bd8dSchristos 	case 110:
174ca32bd8dSchristos 		return B110;
175ca32bd8dSchristos 	case 134:
176ca32bd8dSchristos 		return B134;
177ca32bd8dSchristos 	case 150:
178ca32bd8dSchristos 		return B150;
179ca32bd8dSchristos 	case 200:
180ca32bd8dSchristos 		return B200;
181ca32bd8dSchristos 	case 300:
182ca32bd8dSchristos 		return B300;
183ca32bd8dSchristos 	case 600:
184ca32bd8dSchristos 		return B600;
185ca32bd8dSchristos 	case 1200:
186ca32bd8dSchristos 		return B1200;
187ca32bd8dSchristos 	case 1800:
188ca32bd8dSchristos 		return B1800;
189ca32bd8dSchristos 	case 2400:
190ca32bd8dSchristos 		return B2400;
191ca32bd8dSchristos 	case 4800:
192ca32bd8dSchristos 		return B4800;
193ca32bd8dSchristos 	case 9600:
194ca32bd8dSchristos 		return B9600;
195ca32bd8dSchristos 
196ca32bd8dSchristos #ifdef B19200
197ca32bd8dSchristos 	case 19200:
198ca32bd8dSchristos 		return B19200;
199ca32bd8dSchristos #else /* B19200 */
200ca32bd8dSchristos #ifdef EXTA
201ca32bd8dSchristos 	case 19200:
202ca32bd8dSchristos 		return EXTA;
203ca32bd8dSchristos #endif /* EXTA */
204ca32bd8dSchristos #endif /* B19200 */
205ca32bd8dSchristos 
206ca32bd8dSchristos #ifdef B38400
207ca32bd8dSchristos 	case 38400:
208ca32bd8dSchristos 		return B38400;
209ca32bd8dSchristos #else /* B38400 */
210ca32bd8dSchristos #ifdef EXTB
211ca32bd8dSchristos 	case 38400:
212ca32bd8dSchristos 		return EXTB;
213ca32bd8dSchristos #endif /* EXTB */
214ca32bd8dSchristos #endif /* B38400 */
215ca32bd8dSchristos 
216ca32bd8dSchristos #ifdef B7200
217ca32bd8dSchristos 	case 7200:
218ca32bd8dSchristos 		return B7200;
219ca32bd8dSchristos #endif /* B7200 */
220ca32bd8dSchristos #ifdef B14400
221ca32bd8dSchristos 	case 14400:
222ca32bd8dSchristos 		return B14400;
223ca32bd8dSchristos #endif /* B14400 */
224ca32bd8dSchristos #ifdef B28800
225ca32bd8dSchristos 	case 28800:
226ca32bd8dSchristos 		return B28800;
227ca32bd8dSchristos #endif /* B28800 */
228ca32bd8dSchristos #ifdef B57600
229ca32bd8dSchristos 	case 57600:
230ca32bd8dSchristos 		return B57600;
231ca32bd8dSchristos #endif /* B57600 */
232ca32bd8dSchristos #ifdef B76800
233ca32bd8dSchristos 	case 76800:
234ca32bd8dSchristos 		return B76800;
235ca32bd8dSchristos #endif /* B76800 */
236ca32bd8dSchristos #ifdef B115200
237ca32bd8dSchristos 	case 115200:
238ca32bd8dSchristos 		return B115200;
239ca32bd8dSchristos #endif /* B115200 */
240ca32bd8dSchristos #ifdef B230400
241ca32bd8dSchristos 	case 230400:
242ca32bd8dSchristos 		return B230400;
243ca32bd8dSchristos #endif /* B230400 */
244ca32bd8dSchristos 	default:
245ca32bd8dSchristos 		return B9600;
246ca32bd8dSchristos 	}
247ca32bd8dSchristos }
248ca32bd8dSchristos 
249ca32bd8dSchristos /*
250ca32bd8dSchristos  * Encodes terminal modes for the terminal referenced by fd
251ca32bd8dSchristos  * or tiop in a portable manner, and appends the modes to a packet
252ca32bd8dSchristos  * being constructed.
253ca32bd8dSchristos  */
254ca32bd8dSchristos void
ssh_tty_make_modes(struct ssh * ssh,int fd,struct termios * tiop)25555a4608bSchristos ssh_tty_make_modes(struct ssh *ssh, int fd, struct termios *tiop)
256ca32bd8dSchristos {
257ca32bd8dSchristos 	struct termios tio;
25855a4608bSchristos 	struct sshbuf *buf;
25955a4608bSchristos 	int r, ibaud, obaud;
260ca32bd8dSchristos 
26155a4608bSchristos 	if ((buf = sshbuf_new()) == NULL)
262*17418e98Schristos 		fatal_f("sshbuf_new failed");
263ca32bd8dSchristos 
264ca32bd8dSchristos 	if (tiop == NULL) {
265ca32bd8dSchristos 		if (fd == -1) {
266*17418e98Schristos 			debug_f("no fd or tio");
267ca32bd8dSchristos 			goto end;
268ca32bd8dSchristos 		}
269ca32bd8dSchristos 		if (tcgetattr(fd, &tio) == -1) {
270ca32bd8dSchristos 			logit("tcgetattr: %.100s", strerror(errno));
271ca32bd8dSchristos 			goto end;
272ca32bd8dSchristos 		}
273ca32bd8dSchristos 	} else
274ca32bd8dSchristos 		tio = *tiop;
275ca32bd8dSchristos 
276ca32bd8dSchristos 	/* Store input and output baud rates. */
27755a4608bSchristos 	obaud = speed_to_baud(cfgetospeed(&tio));
27855a4608bSchristos 	ibaud = speed_to_baud(cfgetispeed(&tio));
27955a4608bSchristos 	if ((r = sshbuf_put_u8(buf, TTY_OP_OSPEED)) != 0 ||
28055a4608bSchristos 	    (r = sshbuf_put_u32(buf, obaud)) != 0 ||
28155a4608bSchristos 	    (r = sshbuf_put_u8(buf, TTY_OP_ISPEED)) != 0 ||
28255a4608bSchristos 	    (r = sshbuf_put_u32(buf, ibaud)) != 0)
283*17418e98Schristos 		fatal_fr(r, "compose");
284ca32bd8dSchristos 
285ca32bd8dSchristos 	/* Store values of mode flags. */
286ca32bd8dSchristos #define TTYCHAR(NAME, OP) \
28755a4608bSchristos 	if ((r = sshbuf_put_u8(buf, OP)) != 0 || \
28855a4608bSchristos 	    (r = sshbuf_put_u32(buf, tio.c_cc[NAME])) != 0) \
289*17418e98Schristos 		fatal_fr(r, "compose %s", #NAME);
290ca32bd8dSchristos 
291ffae97bbSchristos #define SSH_TTYMODE_IUTF8 42  /* for SSH_BUG_UTF8TTYMODE */
292ffae97bbSchristos 
293ca32bd8dSchristos #define TTYMODE(NAME, FIELD, OP) \
294*17418e98Schristos 	if (OP == SSH_TTYMODE_IUTF8 && (ssh->compat & SSH_BUG_UTF8TTYMODE)) { \
295*17418e98Schristos 		debug3_f("SSH_BUG_UTF8TTYMODE"); \
29655a4608bSchristos 	} else if ((r = sshbuf_put_u8(buf, OP)) != 0 || \
29755a4608bSchristos 	    (r = sshbuf_put_u32(buf, ((tio.FIELD & NAME) != 0))) != 0) \
298*17418e98Schristos 		fatal_fr(r, "compose %s", #NAME);
299ca32bd8dSchristos 
300ca32bd8dSchristos #include "ttymodes.h"
301ca32bd8dSchristos 
302ca32bd8dSchristos #undef TTYCHAR
303ca32bd8dSchristos #undef TTYMODE
304ca32bd8dSchristos 
305ca32bd8dSchristos end:
306ca32bd8dSchristos 	/* Mark end of mode data. */
30755a4608bSchristos 	if ((r = sshbuf_put_u8(buf, TTY_OP_END)) != 0 ||
30855a4608bSchristos 	    (r = sshpkt_put_stringb(ssh, buf)) != 0)
309*17418e98Schristos 		fatal_fr(r, "compose end");
31055a4608bSchristos 	sshbuf_free(buf);
311ca32bd8dSchristos }
312ca32bd8dSchristos 
313ca32bd8dSchristos /*
314ca32bd8dSchristos  * Decodes terminal modes for the terminal referenced by fd in a portable
315ca32bd8dSchristos  * manner from a packet being read.
316ca32bd8dSchristos  */
317ca32bd8dSchristos void
ssh_tty_parse_modes(struct ssh * ssh,int fd)31855a4608bSchristos ssh_tty_parse_modes(struct ssh *ssh, int fd)
319ca32bd8dSchristos {
320ca32bd8dSchristos 	struct termios tio;
32155a4608bSchristos 	struct sshbuf *buf;
32255a4608bSchristos 	const u_char *data;
32355a4608bSchristos 	u_char opcode;
32455a4608bSchristos 	u_int baud, u;
32555a4608bSchristos 	int r, failure = 0;
32655a4608bSchristos 	size_t len;
327ca32bd8dSchristos 
32855a4608bSchristos 	if ((r = sshpkt_get_string_direct(ssh, &data, &len)) != 0)
329*17418e98Schristos 		fatal_fr(r, "parse");
33055a4608bSchristos 	if (len == 0)
331ca32bd8dSchristos 		return;
33255a4608bSchristos 	if ((buf = sshbuf_from(data, len)) == NULL) {
333*17418e98Schristos 		error_f("sshbuf_from failed");
33455a4608bSchristos 		return;
33555a4608bSchristos 	}
336ca32bd8dSchristos 
337ca32bd8dSchristos 	/*
338ca32bd8dSchristos 	 * Get old attributes for the terminal.  We will modify these
339ca32bd8dSchristos 	 * flags. I am hoping that if there are any machine-specific
340ca32bd8dSchristos 	 * modes, they will initially have reasonable values.
341ca32bd8dSchristos 	 */
342ca32bd8dSchristos 	if (tcgetattr(fd, &tio) == -1) {
343ca32bd8dSchristos 		logit("tcgetattr: %.100s", strerror(errno));
344ca32bd8dSchristos 		failure = -1;
345ca32bd8dSchristos 	}
346ca32bd8dSchristos 
34755a4608bSchristos 	while (sshbuf_len(buf) > 0) {
34855a4608bSchristos 		if ((r = sshbuf_get_u8(buf, &opcode)) != 0)
349*17418e98Schristos 			fatal_fr(r, "parse opcode");
350ca32bd8dSchristos 		switch (opcode) {
351ca32bd8dSchristos 		case TTY_OP_END:
352ca32bd8dSchristos 			goto set;
353ca32bd8dSchristos 
3547a183406Schristos 		case TTY_OP_ISPEED:
35555a4608bSchristos 			if ((r = sshbuf_get_u32(buf, &baud)) != 0)
356*17418e98Schristos 				fatal_fr(r, "parse ispeed");
357ca32bd8dSchristos 			if (failure != -1 &&
358ca32bd8dSchristos 			    cfsetispeed(&tio, baud_to_speed(baud)) == -1)
359ca32bd8dSchristos 				error("cfsetispeed failed for %d", baud);
360ca32bd8dSchristos 			break;
361ca32bd8dSchristos 
3627a183406Schristos 		case TTY_OP_OSPEED:
36355a4608bSchristos 			if ((r = sshbuf_get_u32(buf, &baud)) != 0)
364*17418e98Schristos 				fatal_fr(r, "parse ospeed");
365ca32bd8dSchristos 			if (failure != -1 &&
366ca32bd8dSchristos 			    cfsetospeed(&tio, baud_to_speed(baud)) == -1)
367ca32bd8dSchristos 				error("cfsetospeed failed for %d", baud);
368ca32bd8dSchristos 			break;
369ca32bd8dSchristos 
370ca32bd8dSchristos #define TTYCHAR(NAME, OP) \
371ca32bd8dSchristos 		case OP: \
37255a4608bSchristos 			if ((r = sshbuf_get_u32(buf, &u)) != 0) \
373*17418e98Schristos 				fatal_fr(r, "parse %s", #NAME); \
37455a4608bSchristos 			tio.c_cc[NAME] = u; \
375ca32bd8dSchristos 			break;
376ca32bd8dSchristos #define TTYMODE(NAME, FIELD, OP) \
377ca32bd8dSchristos 		case OP: \
37855a4608bSchristos 			if ((r = sshbuf_get_u32(buf, &u)) != 0) \
379*17418e98Schristos 				fatal_fr(r, "parse %s", #NAME); \
38055a4608bSchristos 			if (u) \
381ca32bd8dSchristos 				tio.FIELD |= NAME; \
382ca32bd8dSchristos 			else \
383ca32bd8dSchristos 				tio.FIELD &= ~NAME; \
384ca32bd8dSchristos 			break;
385ca32bd8dSchristos 
386ca32bd8dSchristos #include "ttymodes.h"
387ca32bd8dSchristos 
388ca32bd8dSchristos #undef TTYCHAR
389ca32bd8dSchristos #undef TTYMODE
390ca32bd8dSchristos 
391ca32bd8dSchristos 		default:
392ca32bd8dSchristos 			debug("Ignoring unsupported tty mode opcode %d (0x%x)",
393ca32bd8dSchristos 			    opcode, opcode);
394ca32bd8dSchristos 			/*
395ca32bd8dSchristos 			 * SSH2:
3967a183406Schristos 			 * Opcodes 1 to 159 are defined to have a uint32
3977a183406Schristos 			 * argument.
3987a183406Schristos 			 * Opcodes 160 to 255 are undefined and cause parsing
3997a183406Schristos 			 * to stop.
400ca32bd8dSchristos 			 */
401ca32bd8dSchristos 			if (opcode > 0 && opcode < 160) {
40255a4608bSchristos 				if ((r = sshbuf_get_u32(buf, NULL)) != 0)
403*17418e98Schristos 					fatal_fr(r, "parse arg");
404ca32bd8dSchristos 				break;
405ca32bd8dSchristos 			} else {
406*17418e98Schristos 				logit_f("unknown opcode %d", opcode);
407ca32bd8dSchristos 				goto set;
408ca32bd8dSchristos 			}
409ca32bd8dSchristos 		}
410ca32bd8dSchristos 	}
411ca32bd8dSchristos 
412ca32bd8dSchristos set:
41355a4608bSchristos 	len = sshbuf_len(buf);
41455a4608bSchristos 	sshbuf_free(buf);
41555a4608bSchristos 	if (len > 0) {
416*17418e98Schristos 		logit_f("%zu bytes left", len);
417ca32bd8dSchristos 		return;		/* Don't process bytes passed */
418ca32bd8dSchristos 	}
419ca32bd8dSchristos 	if (failure == -1)
420ca32bd8dSchristos 		return;		/* Packet parsed ok but tcgetattr() failed */
421ca32bd8dSchristos 
422ca32bd8dSchristos 	/* Set the new modes for the terminal. */
423ca32bd8dSchristos 	if (tcsetattr(fd, TCSANOW, &tio) == -1)
424ca32bd8dSchristos 		logit("Setting tty modes failed: %.100s", strerror(errno));
425ca32bd8dSchristos }
426