package sshimport ()func generateSigner() (ssh.Signer, error) { , := rsa.GenerateKey(rand.Reader, 2048)if != nil {returnnil, }returnssh.NewSignerFromKey()}func parsePtyRequest( []byte) ( Pty, bool) {// From https://datatracker.ietf.org/doc/html/rfc4254 // 6.2. Requesting a Pseudo-Terminal // A pseudo-terminal can be allocated for the session by sending the // following message. // 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// The payload starts from the TERM variable. , , := parseString()if ! {return } , , := parseWindow()if ! {return } , := parseTerminalModes()if ! {return } = Pty{Term: ,Window: ,Modes: , }return}func parseTerminalModes( []byte) ( ssh.TerminalModes, bool) {// From https://datatracker.ietf.org/doc/html/rfc4254 // 8. Encoding of 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). // // The client SHOULD put any modes it knows about in the stream, and the // server MAY ignore any modes it does not know about. This allows some // degree of machine-independence, at least between systems that use a // POSIX-like tty interface. The protocol can support other systems as // well, but the client may need to fill reasonable values for a number // of parameters so the server pty gets set to a reasonable mode (the // server leaves all unspecified mode bits in their default values, and // only some combinations make sense). , , := parseUint32()if ! {return }const = 0forlen() > 0 {if == nil { = make(ssh.TerminalModes) } := uint8([0]) = [1:]if == || > 160 {break }varuint32 , , = parseUint32()if ! {return } [] = } = truereturn}func parseWindow( []byte) ( Window, []byte, bool) {// 6.7. Window Dimension Change Message // When the window (terminal) size changes on the client side, it MAY // send a message to the other side to inform it of the new dimensions.// 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 , , := parseUint32()if ! {return } , , := parseUint32()if ! {return } , , := parseUint32()if ! {return } , , := parseUint32()if ! {return } = Window{Width: int(),Height: int(),WidthPixels: int(),HeightPixels: int(), }return}func parseString( []byte) ( string, []byte, bool) { , , := parseUint32()ifuint32(len()) < || ! { = falsereturn } , = string([:]), [:] = truereturn}func parseUint32( []byte) (uint32, []byte, bool) {iflen() < 4 {return0, nil, false }returnbinary.BigEndian.Uint32(), [4:], true}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.