⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttymodes.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
字号:
/* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland *                    All rights reserved * * 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 * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * 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.18 2002/06/19 00:27:55 deraadt Exp $");#include "packet.h"#include "log.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/* * Converts POSIX speed_t to a baud rate.  The values of the * constants for speed_t are not themselves portable. */static intspeed_to_baud(speed_t speed){	switch (speed) {	case B0:		return 0;	case B50:		return 50;	case B75:		return 75;	case B110:		return 110;	case B134:		return 134;	case B150:		return 150;	case B200:		return 200;	case B300:		return 300;	case B600:		return 600;	case B1200:		return 1200;	case B1800:		return 1800;	case B2400:		return 2400;	case B4800:		return 4800;	case B9600:		return 9600;#ifdef B19200	case B19200:		return 19200;#else /* B19200 */#ifdef EXTA	case EXTA:		return 19200;#endif /* EXTA */#endif /* B19200 */#ifdef B38400	case B38400:		return 38400;#else /* B38400 */#ifdef EXTB	case EXTB:		return 38400;#endif /* EXTB */#endif /* B38400 */#ifdef B7200	case B7200:		return 7200;#endif /* B7200 */#ifdef B14400	case B14400:		return 14400;#endif /* B14400 */#ifdef B28800	case B28800:		return 28800;#endif /* B28800 */#ifdef B57600	case B57600:		return 57600;#endif /* B57600 */#ifdef B76800	case B76800:		return 76800;#endif /* B76800 */#ifdef B115200	case B115200:		return 115200;#endif /* B115200 */#ifdef B230400	case B230400:		return 230400;#endif /* B230400 */	default:		return 9600;	}}/* * Converts a numeric baud rate to a POSIX speed_t. */static speed_tbaud_to_speed(int baud){	switch (baud) {	case 0:		return B0;	case 50:		return B50;	case 75:		return B75;	case 110:		return B110;	case 134:		return B134;	case 150:		return B150;	case 200:		return B200;	case 300:		return B300;	case 600:		return B600;	case 1200:		return B1200;	case 1800:		return B1800;	case 2400:		return B2400;	case 4800:		return B4800;	case 9600:		return B9600;#ifdef B19200	case 19200:		return B19200;#else /* B19200 */#ifdef EXTA	case 19200:		return EXTA;#endif /* EXTA */#endif /* B19200 */#ifdef B38400	case 38400:		return B38400;#else /* B38400 */#ifdef EXTB	case 38400:		return EXTB;#endif /* EXTB */#endif /* B38400 */#ifdef B7200	case 7200:		return B7200;#endif /* B7200 */#ifdef B14400	case 14400:		return B14400;#endif /* B14400 */#ifdef B28800	case 28800:		return B28800;#endif /* B28800 */#ifdef B57600	case 57600:		return B57600;#endif /* B57600 */#ifdef B76800	case 76800:		return B76800;#endif /* B76800 */#ifdef B115200	case 115200:		return B115200;#endif /* B115200 */#ifdef B230400	case 230400:		return B230400;#endif /* B230400 */	default:		return B9600;	}}/* * Encodes terminal modes for the terminal referenced by fd * or tiop in a portable manner, and appends the modes to a packet * being constructed. */voidtty_make_modes(int fd, struct termios *tiop){	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 (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);	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);	/* 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]);#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));#include "ttymodes.h"#undef TTYCHAR#undef TTYMODEend:	/* 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);}/* * Decodes terminal modes for the terminal referenced by fd in a portable * manner from a packet being read. */voidtty_parse_modes(int fd, int *n_bytes_ptr){	struct termios tio;	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));		failure = -1;	}	for (;;) {		n_bytes += 1;		opcode = packet_get_char();		switch (opcode) {		case TTY_OP_END:			goto set;		/* XXX: future conflict possible */		case TTY_OP_ISPEED_PROTO1:		case TTY_OP_ISPEED_PROTO2:			n_bytes += 4;			baud = packet_get_int();			debug3("tty_parse_modes: ispeed %d", baud);			if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1)				error("cfsetispeed failed for %d", baud);			break;		/* XXX: future conflict possible */		case TTY_OP_OSPEED_PROTO1:		case TTY_OP_OSPEED_PROTO2:			n_bytes += 4;			baud = packet_get_int();			debug3("tty_parse_modes: ospeed %d", baud);			if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1)				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]); \	  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); \	  break;#include "ttymodes.h"#undef TTYCHAR#undef TTYMODE		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;				}			} else {				/*				 * SSH2:				 * Opcodes 1 to 159 are defined to have				 * a uint32 argument.				 * Opcodes 160 to 255 are undefined and				 * cause parsing to stop.				 */				if (opcode > 0 && opcode < 160) {					n_bytes += 4;					(void) packet_get_int();					break;				} else {					log("parse_tty_modes: unknown opcode %d", opcode);					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 */	/* Set the new modes for the terminal. */	if (tcsetattr(fd, TCSANOW, &tio) == -1)		log("Setting tty modes failed: %.100s", strerror(errno));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -