package ssh

import (
	
	
	

	
)

func generateSigner() (ssh.Signer, error) {
	,  := rsa.GenerateKey(rand.Reader, 2048)
	if  != nil {
		return nil, 
	}
	return ssh.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  = 0
	for len() > 0 {
		if  == nil {
			 = make(ssh.TerminalModes)
		}
		 := uint8([0])
		 = [1:]
		if  ==  ||  > 160 {
			break
		}
		var  uint32
		, ,  = parseUint32()
		if ! {
			return
		}
		[] = 
	}
	 = true
	return
}

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()
	if uint32(len()) <  || ! {
		 = false
		return
	}
	,  = string([:]), [:]
	 = true
	return
}

func parseUint32( []byte) (uint32, []byte, bool) {
	if len() < 4 {
		return 0, nil, false
	}
	return binary.BigEndian.Uint32(), [4:], true
}