=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ttymodes.c,v retrieving revision 1.8.2.6 retrieving revision 1.9 diff -u -r1.8.2.6 -r1.9 --- src/usr.bin/ssh/ttymodes.c 2002/03/08 17:04:43 1.8.2.6 +++ src/usr.bin/ssh/ttymodes.c 2001/01/19 15:55:12 1.9 @@ -2,6 +2,10 @@ * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved + * Encoding and decoding of terminal modes in a portable way. + * Much of the format is defined in ttymodes.h; it is included multiple times + * into this file with the appropriate macro definitions to generate the + * suitable code. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this @@ -10,56 +14,16 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* - * SSH2 tty modes support by Kevin Steves. - * Copyright (c) 2001 Kevin Steves. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Encoding and decoding of terminal modes in a portable way. - * Much of the format is defined in ttymodes.h; it is included multiple times - * into this file with the appropriate macro definitions to generate the - * suitable code. - */ - #include "includes.h" -RCSID("$OpenBSD: ttymodes.c,v 1.8.2.6 2002/03/08 17:04:43 brad Exp $"); +RCSID("$OpenBSD: ttymodes.c,v 1.9 2001/01/19 15:55:12 markus Exp $"); #include "packet.h" -#include "log.h" +#include "ssh.h" #include "ssh1.h" -#include "compat.h" -#include "buffer.h" -#include "bufaux.h" -#define TTY_OP_END 0 -/* - * uint32 (u_int) follows speed in SSH1 and SSH2 - */ -#define TTY_OP_ISPEED_PROTO1 192 -#define TTY_OP_OSPEED_PROTO1 193 -#define TTY_OP_ISPEED_PROTO2 128 -#define TTY_OP_OSPEED_PROTO2 129 +#define TTY_OP_END 0 +#define TTY_OP_ISPEED 192 /* int follows */ +#define TTY_OP_OSPEED 193 /* int follows */ /* * Converts POSIX speed_t to a baud rate. The values of the @@ -158,7 +122,7 @@ baud_to_speed(int baud) { switch (baud) { - case 0: + case 0: return B0; case 50: return B50; @@ -242,72 +206,47 @@ /* * Encodes terminal modes for the terminal referenced by fd - * or tiop in a portable manner, and appends the modes to a packet + * in a portable manner, and appends the modes to a packet * being constructed. */ void -tty_make_modes(int fd, struct termios *tiop) +tty_make_modes(int fd) { struct termios tio; int baud; - Buffer buf; - int tty_op_ospeed, tty_op_ispeed; - void (*put_arg)(Buffer *, u_int); - buffer_init(&buf); - if (compat20) { - tty_op_ospeed = TTY_OP_OSPEED_PROTO2; - tty_op_ispeed = TTY_OP_ISPEED_PROTO2; - put_arg = buffer_put_int; - } else { - tty_op_ospeed = TTY_OP_OSPEED_PROTO1; - tty_op_ispeed = TTY_OP_ISPEED_PROTO1; - put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; + if (tcgetattr(fd, &tio) < 0) { + packet_put_char(TTY_OP_END); + log("tcgetattr: %.100s", strerror(errno)); + return; } - - if (tiop == NULL) { - if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); - goto end; - } - } else - tio = *tiop; - /* Store input and output baud rates. */ baud = speed_to_baud(cfgetospeed(&tio)); - debug3("tty_make_modes: ospeed %d", baud); - buffer_put_char(&buf, tty_op_ospeed); - buffer_put_int(&buf, baud); + packet_put_char(TTY_OP_OSPEED); + packet_put_int(baud); baud = speed_to_baud(cfgetispeed(&tio)); - debug3("tty_make_modes: ispeed %d", baud); - buffer_put_char(&buf, tty_op_ispeed); - buffer_put_int(&buf, baud); + packet_put_char(TTY_OP_ISPEED); + packet_put_int(baud); /* Store values of mode flags. */ #define TTYCHAR(NAME, OP) \ - debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ - buffer_put_char(&buf, OP); \ - put_arg(&buf, tio.c_cc[NAME]); - + packet_put_char(OP); packet_put_char(tio.c_cc[NAME]); #define TTYMODE(NAME, FIELD, OP) \ - debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ - buffer_put_char(&buf, OP); \ - put_arg(&buf, ((tio.FIELD & NAME) != 0)); + packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0); +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) #include "ttymodes.h" #undef TTYCHAR #undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN -end: /* Mark end of mode data. */ - buffer_put_char(&buf, TTY_OP_END); - if (compat20) - packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); - else - packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); - buffer_free(&buf); - return; + packet_put_char(TTY_OP_END); } /* @@ -321,30 +260,14 @@ int opcode, baud; int n_bytes = 0; int failure = 0; - u_int (*get_arg)(void); - int arg, arg_size; - if (compat20) { - *n_bytes_ptr = packet_get_int(); - debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); - if (*n_bytes_ptr == 0) - return; - get_arg = packet_get_int; - arg_size = 4; - } else { - get_arg = packet_get_char; - arg_size = 1; - } - /* * Get old attributes for the terminal. We will modify these * flags. I am hoping that if there are any machine-specific * modes, they will initially have reasonable values. */ - if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); + if (tcgetattr(fd, &tio) < 0) failure = -1; - } for (;;) { n_bytes += 1; @@ -353,109 +276,90 @@ case TTY_OP_END: goto set; - /* XXX: future conflict possible */ - case TTY_OP_ISPEED_PROTO1: - case TTY_OP_ISPEED_PROTO2: + case TTY_OP_ISPEED: n_bytes += 4; baud = packet_get_int(); - debug3("tty_parse_modes: ispeed %d", baud); - if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) + if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0) error("cfsetispeed failed for %d", baud); break; - /* XXX: future conflict possible */ - case TTY_OP_OSPEED_PROTO1: - case TTY_OP_OSPEED_PROTO2: + case TTY_OP_OSPEED: n_bytes += 4; baud = packet_get_int(); - debug3("tty_parse_modes: ospeed %d", baud); - if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) + if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0) error("cfsetospeed failed for %d", baud); break; -#define TTYCHAR(NAME, OP) \ - case OP: \ - n_bytes += arg_size; \ - tio.c_cc[NAME] = get_arg(); \ - debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ +#define TTYCHAR(NAME, OP) \ + case OP: \ + n_bytes += 1; \ + tio.c_cc[NAME] = packet_get_char(); \ break; -#define TTYMODE(NAME, FIELD, OP) \ - case OP: \ - n_bytes += arg_size; \ - if ((arg = get_arg())) \ - tio.FIELD |= NAME; \ - else \ - tio.FIELD &= ~NAME; \ - debug3("tty_parse_modes: %d %d", OP, arg); \ +#define TTYMODE(NAME, FIELD, OP) \ + case OP: \ + n_bytes += 1; \ + if (packet_get_char()) \ + tio.FIELD |= NAME; \ + else \ + tio.FIELD &= ~NAME; \ break; +#define SGTTYCHAR(NAME, OP) +#define SGTTYMODE(NAME, FIELD, OP) +#define SGTTYMODEN(NAME, FIELD, OP) #include "ttymodes.h" #undef TTYCHAR #undef TTYMODE +#undef SGTTYCHAR +#undef SGTTYMODE +#undef SGTTYMODEN default: debug("Ignoring unsupported tty mode opcode %d (0x%x)", - opcode, opcode); - if (!compat20) { - /* - * SSH1: - * Opcodes 1 to 127 are defined to have - * a one-byte argument. - * Opcodes 128 to 159 are defined to have - * an integer argument. - */ - if (opcode > 0 && opcode < 128) { - n_bytes += 1; - (void) packet_get_char(); - break; - } else if (opcode >= 128 && opcode < 160) { - n_bytes += 4; - (void) packet_get_int(); - break; - } else { - /* - * It is a truly undefined opcode (160 to 255). - * We have no idea about its arguments. So we - * must stop parsing. Note that some data may be - * left in the packet; hopefully there is nothing - * more coming after the mode data. - */ - log("parse_tty_modes: unknown opcode %d", opcode); - goto set; - } + opcode, opcode); + /* + * Opcodes 0 to 127 are defined to have + * a one-byte argument. + */ + if (opcode >= 0 && opcode < 128) { + n_bytes += 1; + (void) packet_get_char(); + break; } else { /* - * SSH2: - * Opcodes 1 to 159 are defined to have - * a uint32 argument. - * Opcodes 160 to 255 are undefined and - * cause parsing to stop. + * Opcodes 128 to 159 are defined to have + * an integer argument. */ - if (opcode > 0 && opcode < 160) { + if (opcode >= 128 && opcode < 160) { n_bytes += 4; (void) packet_get_int(); break; - } else { - log("parse_tty_modes: unknown opcode %d", opcode); - goto set; } - } + } + /* + * It is a truly undefined opcode (160 to 255). + * We have no idea about its arguments. So we + * must stop parsing. Note that some data may be + * left in the packet; hopefully there is nothing + * more coming after the mode data. + */ + log("parse_tty_modes: unknown opcode %d", opcode); + packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); + goto set; } } set: if (*n_bytes_ptr != n_bytes) { *n_bytes_ptr = n_bytes; - log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", - *n_bytes_ptr, n_bytes); return; /* Don't process bytes passed */ } if (failure == -1) - return; /* Packet parsed ok but tcgetattr() failed */ + return; /* Packet parsed ok but tty stuff failed */ /* Set the new modes for the terminal. */ - if (tcsetattr(fd, TCSANOW, &tio) == -1) + if (tcsetattr(fd, TCSANOW, &tio) < 0) log("Setting tty modes failed: %.100s", strerror(errno)); return; }