2

The Guacamole project is using the libssh2 library to create SSH connections to servers. One of the things we've determined is that it would be useful to pass through the VERASE terminal mode encoding option in SSH so that the remote system has a better chance of knowing what the client is sending for the Backspace key. libssh2 contains a function, libssh2_channel_request_pty_ex(), which allows various data about the terminal to be passed on to the SSH server, including these encoding options. The documentation for the function is here:

https://libssh2.org/libssh2_channel_request_pty_ex.html

The modes argument is a char * that is supposed to let you pass the various terminal encoding opcodes and values through, but I'm having trouble figuring out how to put the opcodes and values together into the char *modes variable in order to pass them through in a way that is valid. There's a Java SSH client that has similar options that appears to use a byte[] object to accomplish this, but even it isn't very well-documented.

From looking at the source code for libssh2 and the channel_request_pty() function, it looks like the data specified in modes is just appended to the request buffer that is built up with the other data passed on when requested a pty (the name of the terminal and size of the terminal), so I expect that this char *modes variable expects these opcodes and values to be in the exact format that the SSH server will require when they are passed over the wire and read on the other side, but I'm not really familiar enough with SSH to know what that format is, and am struggling to find documentation or code examples that help me figure that out.

Can anyone provide hints, insight, or examples of this?

Virtually Nick
  • 358
  • 2
  • 8

2 Answers2

2

RFC 4254 defines SSH protocol messages. Section 6.2 describes the message for requesting a PTY:

  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

You can see that the fields in this message line up with the parameters to the libssh2 PTY request function. Libssh2 almost certainly populates the "encoded terminal modes" field from the modes and modes_len parameters.

Section 8 of the RFC describes the encoding of the terminal modes:

All 'encoded terminal modes' (as passed in a pty request) are encoded into a byte stream. It is intended that the coding be portable across different environments. The stream consists of opcode- argument pairs wherein the opcode is a byte value. Opcodes 1 to 159 have a single uint32 argument. Opcodes 160 to 255 are not yet defined, and cause parsing to stop (they should only be used after any other data). The stream is terminated by opcode TTY_OP_END (0x00)....

Community
  • 1
  • 1
Kenster
  • 23,465
  • 21
  • 80
  • 106
  • So, I think I understand that part of it - I guess my question may be even a little more basic: what are the mechanics, in C, of putting together the Opcodes and values (e.g., for VERASE, Opcode of 3 and value of ^?) and getting those into the char pointer array to pass to libssh2? – Virtually Nick Feb 20 '18 at 18:13
0

It turns out the answer to my question was just a slight variation on this post:

An example of how to specify terminal modes/pty-req string for SSH client

...along with the little bit there in the RFC about the values being uint32 (4 bytes wide). So, the following is the code that accomplishes what I need:

char termModes[] = {
    3,
    0, 0, 0, 127,
    0
};
libssh2_channel_request_pty_ex(channel, type, strlen(type), termModes, sizeof(termModes), termWidth, termHeight, 0, 0)

In the above code, the 3 is the opcode for VERASE, and the 0, 0, 0, 127 is the 4-byte (unit32) value for the ASCII backspace code, with the final 0 for the TTY_OP_END terminator.

Virtually Nick
  • 358
  • 2
  • 8