Como o comprimento e a largura do terminal são encaminhados por SSH e telnet?

15

Quando visualizo o comprimento e a largura do meu emulador de terminal stty size, ele tem 271 caracteres e 71 linhas de altura. Quando eu entro em outro servidor pelo SSH e executo stty size, ele também possui 271 caracteres e 71 linhas de altura. Posso até fazer login em algum dispositivo Cisco IOS e o terminal ainda tem 271 caracteres e 71 linhas de altura:

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

Agora, se eu redimensionar minha janela do emulador de terminal (terminal Gnome) na máquina local, tanto stty sizeno servidor remoto quanto em "show terminal" no IOS, mostrarei diferentes comprimentos de linha e número de linhas. Como o comprimento e a largura do terminal são encaminhados por SSH e telnet?

Martin
fonte

Respostas:

20

O protocolo de telnet, descrito em RFC 854 , inclui um modo para enviar comandos dentro da banda, que consiste no carácter IAC , '\255', seguido por várias mais bytes. Esses comandos podem fazer coisas como enviar uma interrupção para o controle remoto, mas geralmente são usados ​​para enviar opções .

Uma visão detalhada de uma troca que envia a opção de tipo de terminal pode ser encontrada no Microsoft Q231866 .

A opção de tamanho da janela é descrita na RFC 1073 . O cliente primeiro envia sua vontade de enviar uma NAWSopção. Se o servidor responder DO NAWS, o cliente poderá enviar os NAWSdados da opção, que são compostos por dois valores de 16 bits.

Exemplo de sessão, em um terminal de 47 linhas 80 colunas:

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)

O protocolo ssh é descrito na RFC 4254 . Consiste em um fluxo de mensagens. Uma dessas mensagens é a "pty-req"que solicita um pseudo-terminal e seus parâmetros incluem a altura e a largura do terminal.

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

Os clientes telnet e ssh capturam o SIGWINCHsinal; portanto, se você redimensionar uma janela do terminal durante uma sessão, eles enviarão uma mensagem apropriada ao servidor com o novo tamanho. O Ssh envia a mensagem de alteração de dimensão da janela:

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
Mark Plotnick
fonte
Você poderia atualizar com um exemplo dos valores hexadecimais que você poderia usar para realmente enviar o Window Dimension Change Message? Não consigo encontrar um exemplo disso em nenhum lugar.
MirroredFate
@MirroredFate O código C que envia essa mensagem é github.com/openssh/openssh-portable/blob/master/… . Não sei de imediato como ver os bytes brutos enviados; pode ser necessário adicionar algum log ao código-fonte openssh.
MarkJackson1
2

Suspeito que seja pelo sinal SIGWINCH- provavelmente entregue no cano.

Da wikipedia :

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

Se eu fizer um (in zsh):

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

... e eu modifico o tamanho do terminal:

[romano:~] % stty size
35 99
[romano:~] % hi
[romano:~] % hi
[romano:~] % hi
[romano:~] % stty size
31 80
Rmano
fonte
0

RFC 4254 Seção 6.9 O nome da mensagem "window-change" é enviado com as novas dimensões. No lado do cliente, pode ser verdade que o SIGWINCH original foi capturado, mas é enviado por essa mensagem, acredito. https://www.ietf.org/rfc/rfc4254.txt

John
fonte