Skip to content

Commit

Permalink
Extract client behaviour outside the main (#90)
Browse files Browse the repository at this point in the history
The client's main function now only prepares the transport connection. It then instantiates and manipulates a Client object. This can be used to automatize behaviours and potentially lead to easy ProxyJump implementation (as asked by #44).

* separate QUIC transport logic and user-auth/conversation logic

* use  of options and canonicalize hosts format

* known hosts: design hosts by their canonical representation

* do not log a non-zero exit status as an error
  • Loading branch information
francoismichel authored Jan 3, 2024
1 parent aecfb89 commit 0790a5d
Show file tree
Hide file tree
Showing 11 changed files with 965 additions and 743 deletions.
634 changes: 634 additions & 0 deletions client/client.go

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions client/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package client

import (
"fmt"
"net"
)

type Options struct {
username string
hostname string
port int
urlPath string
authMethods []interface{}
}

func NewOptions(username string, hostname string, port int, urlPath string, authMethods []interface{}) (*Options, error) {
if len(urlPath) == 0 || urlPath[0] != '/' {
urlPath = "/" + urlPath
}
return &Options{
username: username,
hostname: hostname,
port: port,
urlPath: urlPath,
authMethods: authMethods,
}, nil
}

func (o *Options) Username() string {
return o.username
}

func (o *Options) Hostname() string {
return o.hostname
}

// Returns the pair hostname:port in a valid URL format.
// This means that an IPv6 will be written inside square brackets [].
// examples: "127.0.0.1:443", "example.org:1234", "[::1]:22""
func (o *Options) URLHostnamePort() string {
hostnameIsAnIP := net.ParseIP(o.hostname) != nil
if hostnameIsAnIP {
ip := net.ParseIP(o.hostname)
if ip.To4() == nil && ip.To16() != nil {
// enforce the square-bracketed notation for ipv6 UDP addresses
return fmt.Sprintf("[%s]:%d", o.hostname, o.port)
}
}
return fmt.Sprintf("%s:%d", o.hostname, o.port)
}

func (o *Options) Port() int {
return o.port
}
func (o *Options) UrlPath() string {
return o.urlPath
}

// Returns the canonical host representation used by SSH3.
// The format is <urlhostnameport><path>
// <urlhostnameport> is the host:port pair in the format returned by
// URLHostnamePort()
// <path> is the URL path, it always starts with a "/", it is therefore never empty.
func (o *Options) CanonicalHostFormat() string {
return fmt.Sprintf("%s:%d%s", o.hostname, o.port, o.urlPath)
}

func (o *Options) AuthMethods() []interface{} {
return o.authMethods
}
File renamed without changes.
18 changes: 18 additions & 0 deletions client/winsize/winsize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build !windows

package winsize

import (
"os"
"syscall"
"unsafe"
)

func GetWinsize(tty *os.File) (ws WindowSize, err error) {
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tty.Fd()), uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(&ws)))
if errno != 0 {
err = errno
}
return ws, err
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

package winsize

import "os"
import "golang.org/x/term"
import (
"os"

func GetWinsize() (ws WindowSize, err error) {
"golang.org/x/term"
)

func GetWinsize(tty *os.File) (ws WindowSize, err error) {
// for Windows, it is a bit more complicated to get the window size in pixels, so on rely
// on window size expressed in columns
width, height, err := term.GetSize(int(os.Stdout.Fd()))
width, height, err := term.GetSize(int(tty.Fd()))
if err != nil {
return ws, err
}
Expand Down
4 changes: 4 additions & 0 deletions client.go → client_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func (m *OidcAuthMethod) OIDCConfig() *auth.OIDCConfig {
return m.config
}

func (m *OidcAuthMethod) DoPKCE() bool {
return m.doPKCE
}

type PrivkeyFileAuthMethod struct {
filename string
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ssh3-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ func newDataReq(user *unix_util.User, channel ssh3.Channel, request ssh3Messages
func handleAuthAgentSocketConn(conn net.Conn, conversation *ssh3.Conversation) {
channel, err := conversation.OpenChannel("agent-connection", 30000, 10)
if err != nil {
log.Error().Msgf("could not open channel: %s", err.Error())
log.Error().Msgf("could not open channel from server: %s", err.Error())
return
}
go func() {
Expand Down
Loading

0 comments on commit 0790a5d

Please sign in to comment.