netssh

package module
v0.0.0-...-330ad6c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2020 License: MIT Imports: 15 Imported by: 2

README

Build Status

Package netssh provides net.Conn and net.Listener that uses the ssh binary + authorized_keys file as a transport.

API documentation

See example/ and https://godoc.org/github.com/problame/go-netssh

License

See LICENSE file.

Documentation

Overview

Minimum Go Version

We require Go 1.11 in order to support deadlines: This package uses two *os.File (stdin, stdout) to implement a net.Conn interface. As such, we need to support deadlines, and Go 1.10 introduced deadlines for certain types of *os.File (https://golang.org/doc/go1.10#os). However, apart from OS/FS constraints, deadlines on *os.File only work if the underlying FD can be added to Go's event pool mechanism, which generally requires the FD to be non-blocking at the time the *os.File is created. This is the case for os.Open and so on, but not for os.Std{in,out,err}, which are created using os.NewFile from the existing FDs 0, 1 and 2. Those are blocking by default, and Go does not change them to non-blocking because the parent process might be a terminal and not expect the tty to change to non-blocking mode after the Go process exits.

Hence, in Go 1.10, deadline operations on os.Std{in,out,err} fail with os.ErrDeadline. Go 1.11 improves the behavior of os.NewFile such that iff the FD passed to os.NewFile is already non-blocking, the *os.File / FD is part of the event loop, which makes deadlines work iff the OS supports it at all (this is the case for stdin, stdout, stderr, which are pipes in our specific use case). See https://github.com/golang/go/issues/24842#issuecomment-381268558

How do we deal with this issue in package netssh? We require Go 1.11 via build tag to get the os.NewFile behavior described above and set os.Std{in,out} to non-blocking before sending it over the unix control socket. See usage of github.com/ftrvxmtrx/fd in functions Proxy and Listener.Accept.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContextWithLog

func ContextWithLog(ctx context.Context, log Logger) context.Context

func Proxy

func Proxy(ctx context.Context, server string) (err error)

The process calling Proxy must exit with non-zero exit status if it returns err != nil and a zero exit status if err == nil.

Types

type Endpoint

type Endpoint struct {
	Host         string
	User         string
	Port         uint16
	IdentityFile string
	SSHCommand   string
	Options      []string
}

func (Endpoint) CmdArgs

func (e Endpoint) CmdArgs() (cmd string, args []string, env []string)

type IOError

type IOError struct {
	Cause error
}

func (IOError) Error

func (e IOError) Error() string

func (IOError) GoString

func (e IOError) GoString() string

func (IOError) Temporary

func (e IOError) Temporary() bool

func (IOError) Timeout

func (e IOError) Timeout() bool

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

func Listen

func Listen(unixSockPath string) (*Listener, error)

func (*Listener) Accept

func (l *Listener) Accept() (*ServeConn, error)

func (*Listener) Addr

func (l *Listener) Addr() net.Addr

func (*Listener) Close

func (l *Listener) Close() error

func (*Listener) SetLog

func (l *Listener) SetLog(log Logger)

type Logger

type Logger interface {
	Printf(format string, args ...interface{})
}

type ProtocolError

type ProtocolError struct {
	What string
}

func (ProtocolError) Error

func (e ProtocolError) Error() string

type SSHConn

type SSHConn struct {
	// contains filtered or unexported fields
}

func Dial

func Dial(dialCtx context.Context, endpoint Endpoint) (*SSHConn, error)

Dial connects to the remote endpoint where it expects a command executing Proxy(). Dial performs a handshake consisting of the exchange of banner messages before returning the connection. If the handshake cannot be completed before dialCtx is Done(), the underlying ssh command is killed and the dialCtx.Err() returned. If the handshake completes, dialCtx's deadline does not affect the returned connection.

Errors returned are either dialCtx.Err(), or intances of ProtocolError or *SSHError

func (*SSHConn) Close

func (conn *SSHConn) Close() error

func (*SSHConn) CloseWrite

func (conn *SSHConn) CloseWrite() error

func (*SSHConn) Cmd

func (conn *SSHConn) Cmd() *exec.Cmd

Cmd returns the underlying *exec.Cmd (the ssh client process) Use read-only, should not be necessary for regular users.

func (*SSHConn) CmdCancel

func (conn *SSHConn) CmdCancel()

CmdCancel bypasses the normal shutdown mechanism of SSHConn (that is, calling Close) and cancels the process's context, which usually results in SIGKILL being sent to the process. Intended for integration tests, regular users shouldn't use it.

func (*SSHConn) LocalAddr

func (conn *SSHConn) LocalAddr() net.Addr

func (*SSHConn) Read

func (conn *SSHConn) Read(p []byte) (int, error)

Read implements io.Reader. It returns *IOError for any non-nil error that is != io.EOF.

func (*SSHConn) RemoteAddr

func (conn *SSHConn) RemoteAddr() net.Addr

func (*SSHConn) SetDeadline

func (conn *SSHConn) SetDeadline(t time.Time) error

func (*SSHConn) SetReadDeadline

func (conn *SSHConn) SetReadDeadline(t time.Time) error

func (*SSHConn) SetWriteDeadline

func (conn *SSHConn) SetWriteDeadline(t time.Time) error

func (*SSHConn) Write

func (conn *SSHConn) Write(p []byte) (int, error)

Write implements io.Writer. It returns *IOError for any error != nil.

type SSHError

type SSHError struct {
	RWCError      error
	WhileActivity string
}

func (*SSHError) Error

func (e *SSHError) Error() string

Error() will try to present a one-line error message unless ssh stderr output is longer than one line

type ServeConn

type ServeConn struct {
	// contains filtered or unexported fields
}

func (*ServeConn) Close

func (f *ServeConn) Close() (err error)

func (*ServeConn) CloseWrite

func (f *ServeConn) CloseWrite() error

func (*ServeConn) LocalAddr

func (f *ServeConn) LocalAddr() net.Addr

func (*ServeConn) Read

func (f *ServeConn) Read(p []byte) (n int, err error)

Read implements io.Reader. It returns *IOError for any non-nil error that is != io.EOF.

func (*ServeConn) RemoteAddr

func (f *ServeConn) RemoteAddr() net.Addr

func (*ServeConn) SetDeadline

func (f *ServeConn) SetDeadline(t time.Time) error

func (*ServeConn) SetReadDeadline

func (f *ServeConn) SetReadDeadline(t time.Time) error

func (*ServeConn) SetWriteDeadline

func (f *ServeConn) SetWriteDeadline(t time.Time) error

func (*ServeConn) Write

func (f *ServeConn) Write(p []byte) (n int, err error)

Write implements io.Writer. It returns *IOError for any error != nil.

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL