Как длина и ширина терминала передаются по SSH и telnet?

15

Когда я просматриваю длину и ширину моего эмулятора терминала, stty sizeто он имеет длину 271 символ и высоту 71 строка. Когда я вхожу на другой сервер через SSH и выполняю stty size, он также имеет длину 271 символ и высоту 71 строка. Я даже могу войти в какое-то устройство Cisco IOS, и терминал по-прежнему имеет длину 271 символ и высоту 71 строка:

C1841#show terminal | i Len|Wid
Length: 71 lines, Width: 271 columns
C1841#

Теперь, если я изменю размер окна своего эмулятора терминала (терминала Gnome) на локальном компьютере, и stty sizeна удаленном сервере, и в «show Terminal» в IOS отобразятся разные длины и количество строк. Как длина и ширина терминала передаются по SSH и telnet?

Мартин
источник

Ответы:

20

Протокол Telnet, описанный в RFC 854 , включает в себя способ для отправки команд в полосе, состоящий из характера IAC , '\255'с последующим еще несколько байт. Эти команды могут выполнять такие действия, как отправка прерывания на удаленный компьютер, но обычно они используются для отправки параметров. .

Подробный обзор обмена, который отправляет параметр типа терминала, можно найти в Microsoft Q231866. .

Опция размера окна описана в RFC 1073 . Клиент сначала отправляет свою готовность отправить NAWSопцию. Если сервер отвечает DO NAWS, клиент может затем отправить NAWSданные опции, которые состоят из двух 16-битных значений.

Пример сеанса на терминале с 47 строками и 80 столбцами:

telnet> set options
Will show option processing.
telnet> open localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SENT WILL NAWS
RCVD DO NAWS
SENT IAC SB NAWS 0 80 (80) 0 47 (47)

Протокол ssh описан в RFC 4254 . Он состоит из потока сообщений. Одним из таких сообщений является "pty-req"запрос псевдотерминала, а его параметры включают в себя высоту и ширину терминала.

byte      SSH_MSG_CHANNEL_REQUEST
uint32    recipient channel
string    "pty-req"
boolean   want_reply
string    TERM environment variable value (e.g., vt100)
uint32    terminal width, characters (e.g., 80)
uint32    terminal height, rows (e.g., 24)
uint32    terminal width, pixels (e.g., 640)
uint32    terminal height, pixels (e.g., 480)
string    encoded terminal modes

Клиенты telnet и ssh поймают SIGWINCHсигнал, поэтому, если вы измените размер окна терминала во время сеанса, они отправят соответствующее сообщение на сервер с новым размером. Ssh отправляет сообщение об изменении размера окна:

byte      SSH_MSG_CHANNEL_REQUEST
uint32    recipient channel
string    "window-change"
boolean   FALSE
uint32    terminal width, columns
uint32    terminal height, rows
uint32    terminal width, pixels
uint32    terminal height, pixels
Марк Плотник
источник
Не могли бы вы обновить пример шестнадцатеричных значений, которые вы могли бы использовать для фактической отправки Window Dimension Change Message? Я не могу найти пример этого нигде.
MirroredFate
@MirroredFate Код C, который отправляет это сообщение: github.com/openssh/openssh-portable/blob/master/… . Я не знаю, как посмотреть, как отправляются необработанные байты; Возможно, вам придется добавить некоторые записи в исходный код openssh.
Марк Плотник
2

Я подозреваю, что это через сигнал SIGWINCH- вероятно, доставлен по трубе.

Из википедии :

SIGWINCH
    The SIGWINCH signal is sent to a process when its controlling
     terminal changes its size (a window change).

Если я сделаю (в zsh):

[romano:~] 1 % TRAPWINCH() {echo hi;}

... и я изменяю размер терминала:

[romano:~] % stty size
35 99
[romano:~] % hi
[romano:~] % hi
[romano:~] % hi
[romano:~] % stty size
31 80
Rmano
источник
0

RFC 4254 Раздел 6.9 Имя сообщения «изменение окна» отправляется с новыми размерами. На стороне клиента это может быть правдой, что оригинальный SIGWINCH перехватывается, но он отправляется через то сообщение, которое я считаю. https://www.ietf.org/rfc/rfc4254.txt

Джон
источник