diff --git a/proto/errors.go b/proto/errors.go index 49f49053..a0ed7256 100644 --- a/proto/errors.go +++ b/proto/errors.go @@ -2,6 +2,7 @@ package proto import ( "errors" + "fmt" ) // ErrMalformedKey parsing error for bad ssh key. @@ -40,7 +41,7 @@ type ErrAuthFailed struct { } // Error returns the boxed error string. -func (e ErrAuthFailed) Error() string { return e.Err.Error() } +func (e ErrAuthFailed) Error() string { return fmt.Sprintf("authentication failed: %s", e.Err) } // Unwrap returns the boxed error. func (e ErrAuthFailed) Unwrap() error { return e.Err } diff --git a/server/ssh.go b/server/ssh.go index b82fd21e..b9f3afc9 100644 --- a/server/ssh.go +++ b/server/ssh.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "log" + "os" + "path/filepath" "time" charm "github.com/charmbracelet/charm/proto" @@ -53,7 +55,7 @@ func NewSSHServer(cfg *Config) (*SSHServer, error) { linkRequests: make(map[charm.Token]chan *charm.Link), } } - srv, err := wish.NewServer( + opts := []ssh.Option{ wish.WithAddress(addr), wish.WithHostKeyPEM(cfg.PrivateKey), wish.WithPublicKeyAuth(s.authHandler), @@ -63,7 +65,13 @@ func NewSSHServer(cfg *Config) (*SSHServer, error) { s.sshMiddleware(), ), ), - ) + } + fp := filepath.Join(cfg.DataDir, ".ssh", "authorized_keys") + if _, err := os.Stat(fp); err == nil { + log.Print("Loading authorized_keys from ", fp) + opts = append(opts, wish.WithAuthorizedKeys(fp)) + } + srv, err := wish.NewServer(opts...) if err != nil { return nil, err }