Compare commits

..

1 Commits

Author SHA1 Message Date
Timmy Welch
bba58e7a3a Stuff
Some checks failed
Push / CI (push) Has been cancelled
Implement certificate authentication, certificate requires :gokrazy: principal
Read first line of /etc/passwd for home and shell
Shell uses `-l` to make it a login shell which will run .profile
2025-02-16 17:53:26 -08:00
7 changed files with 106 additions and 118 deletions

View File

@@ -9,18 +9,21 @@ jobs:
name: CI name: CI
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4
- name: Set up latest stable Go - name: Set up Go 1.x
uses: actions/setup-go@v5 uses: actions/setup-go@v2
with: with:
go-version: 'stable' # Run on the latest minor release of Go 1.19:
go-version: ^1.19
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Ensure all files were formatted as per gofmt - name: Ensure all files were formatted as per gofmt
run: | run: |
[ "$(gofmt -l $(find . -name '*.go') 2>&1)" = "" ] [ "$(gofmt -l $(find . -name '*.go') 2>&1)" = "" ]
- name: Build and test - name: Build packages
run: | run: |
go install ./... go install -v ./...
go test -v ./...

View File

@@ -97,7 +97,7 @@ busybox: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically li
for GNU/Linux 3.7.0, BuildID[sha1]=c9e20e9849ed0ca3c2bd058427ac31a27c008efe, stripped for GNU/Linux 3.7.0, BuildID[sha1]=c9e20e9849ed0ca3c2bd058427ac31a27c008efe, stripped
$ ln -s busybox sh $ ln -s busybox sh
$ tar cf breakglass.tar --dereference sh $ tar cf breakglass.tar --dereference sh
$ breakglass -debug_tarball_pattern=breakglass.tar gokrazy $ breakglass -debug_tarball_pattern=debug.tar gokrazy
/tmp/breakglass564067692 # df -h /tmp/breakglass564067692 # df -h
Filesystem Size Used Available Use% Mounted on Filesystem Size Used Available Use% Mounted on
/dev/root 60.5M 60.5M 0 100% / /dev/root 60.5M 60.5M 0 100% /

View File

@@ -5,10 +5,10 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"context"
"crypto/ed25519"
"crypto/rand" "crypto/rand"
"crypto/rsa"
"crypto/x509" "crypto/x509"
"encoding/json"
"encoding/pem" "encoding/pem"
"errors" "errors"
"flag" "flag"
@@ -16,13 +16,12 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net" "net"
"net/http"
"os" "os"
"path" "path"
"strings" "strings"
"syscall" "syscall"
"github.com/gokrazy/gokapi"
"github.com/gokrazy/gokapi/ondeviceapi"
"github.com/gokrazy/gokrazy" "github.com/gokrazy/gokrazy"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@@ -113,7 +112,7 @@ func loadHostKey(path string) (ssh.Signer, error) {
} }
func createHostKey(path string) (ssh.Signer, error) { func createHostKey(path string) (ssh.Signer, error) {
_, key, err := ed25519.GenerateKey(rand.Reader) key, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -138,16 +137,40 @@ func createHostKey(path string) (ssh.Signer, error) {
} }
func buildTimestamp() (string, error) { func buildTimestamp() (string, error) {
cfg, err := gokapi.ConnectOnDevice() var statusReply struct {
BuildTimestamp string `json:"BuildTimestamp"`
}
pw, err := os.ReadFile("/etc/gokr-pw.txt")
if err != nil { if err != nil {
return "", err return "", err
} }
cl := ondeviceapi.NewAPIClient(cfg) port, err := os.ReadFile("/etc/http-port.txt")
res, _, err := cl.SuperviseApi.Index(context.Background())
if err != nil { if err != nil {
return "", err return "", err
} }
return res.BuildTimestamp, nil req, err := http.NewRequest("GET", "http://gokrazy:"+strings.TrimSpace(string(pw))+"@localhost:"+strings.TrimSpace(string(port))+"/", nil)
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
if got, want := resp.StatusCode, http.StatusOK; got != want {
b, _ := ioutil.ReadAll(resp.Body)
return "", fmt.Errorf("unexpected HTTP status code: got %v, want %v (body: %s)", resp.Status, want, strings.TrimSpace(string(b)))
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
if err := json.Unmarshal(b, &statusReply); err != nil {
return "", err
}
return statusReply.BuildTimestamp, nil
} }
var motd string var motd string
@@ -194,7 +217,7 @@ func main() {
flag.Parse() flag.Parse()
log.SetFlags(log.LstdFlags | log.Lshortfile) log.SetFlags(log.LstdFlags | log.Lshortfile)
installBusybox() gokrazy.DontStartOnBoot()
loadPasswd("/etc/passwd") loadPasswd("/etc/passwd")
@@ -223,7 +246,7 @@ func main() {
UserKeyFallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { UserKeyFallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
if authorizedKeys[string(pubKey.Marshal())] { if authorizedKeys[string(pubKey.Marshal())] {
log.Printf("user %q successfully authorized from remote addr %s", conn.User(), conn.RemoteAddr()) log.Printf("user %q successfully authorized from remote addr %s", conn.User(), conn.RemoteAddr())
return &ssh.Permissions{map[string]string{}, map[string]string{}, map[any]any{}}, nil return &ssh.Permissions{map[string]string{}, map[string]string{}}, nil
} }
return nil, fmt.Errorf("public key not found in %s", *authorizedKeysPath) return nil, fmt.Errorf("public key not found in %s", *authorizedKeysPath)
}, },
@@ -324,7 +347,6 @@ func main() {
} }
} }
gokrazy.WaitFor("net-route")
addrs, err := gokrazy.PrivateInterfaceAddrs() addrs, err := gokrazy.PrivateInterfaceAddrs()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@@ -26,6 +26,7 @@ import (
"github.com/gokrazy/internal/config" "github.com/gokrazy/internal/config"
"github.com/gokrazy/internal/httpclient" "github.com/gokrazy/internal/httpclient"
"github.com/gokrazy/internal/instanceflag" "github.com/gokrazy/internal/instanceflag"
"github.com/gokrazy/internal/tlsflag"
"github.com/gokrazy/internal/updateflag" "github.com/gokrazy/internal/updateflag"
) )
@@ -34,11 +35,9 @@ type bg struct {
cfg *config.Struct cfg *config.Struct
forceRestart bool forceRestart bool
sshConfig string sshConfig string
insecure bool
// state // state
GOARCH string GOARCH string
update updateflag.Value
} }
func (bg *bg) startBreakglass() error { func (bg *bg) startBreakglass() error {
@@ -47,26 +46,35 @@ func (bg *bg) startBreakglass() error {
return err return err
} }
updateHttpClient, _, updateBaseURL, err := httpclient.For(bg.update, bg.cfg) updateHttpClient, foundMatchingCertificate, updateBaseURL, err := httpclient.For(bg.cfg)
if err != nil { if err != nil {
return err return err
} }
updateHttpClient.Jar = jar updateHttpClient.Jar = jar
remoteScheme, err := httpclient.GetRemoteScheme(updateBaseURL)
if remoteScheme == "https" && !tlsflag.Insecure() {
updateBaseURL.Scheme = "https"
updateflag.SetUpdate(updateBaseURL.String())
}
if updateBaseURL.Scheme != "https" && foundMatchingCertificate {
fmt.Printf("\n")
fmt.Printf("!!!WARNING!!! Possible SSL-Stripping detected!\n")
fmt.Printf("Found certificate for hostname in your client configuration but the host does not offer https!\n")
fmt.Printf("\n")
if !tlsflag.Insecure() {
log.Fatalf("update canceled: TLS certificate found, but negotiating a TLS connection with the target failed")
}
fmt.Printf("Proceeding anyway as requested (-insecure).\n")
}
if err != nil {
return err
}
form, err := updateHttpClient.Get(updateBaseURL.String() + "status?path=/user/breakglass") form, err := updateHttpClient.Get(updateBaseURL.String() + "status?path=/user/breakglass")
if err != nil { if err != nil {
if updateBaseURL.Scheme == "https" && bg.insecure {
// Try falling back to HTTP
bg.cfg.Update.UseTLS = "off"
updateHttpClient, _, updateBaseURL, err = httpclient.For(bg.update, bg.cfg)
if err != nil {
return err
}
form, err = updateHttpClient.Get(updateBaseURL.String() + "status?path=/user/breakglass")
if err != nil {
return err
}
}
return err return err
} }
if form.StatusCode == http.StatusNotFound { if form.StatusCode == http.StatusNotFound {
@@ -190,11 +198,6 @@ func breakglass() error {
false, false,
"prepare the SSH connection only, but do not execute SSH (useful for using breakglass within an SSH ProxyCommand)") "prepare the SSH connection only, but do not execute SSH (useful for using breakglass within an SSH ProxyCommand)")
insecure = flag.Bool(
"insecure",
false,
"Fall back to HTTP if HTTPS is configured, but does not work.")
proxy = flag.Bool( proxy = flag.Bool(
"proxy", "proxy",
false, false,
@@ -206,6 +209,13 @@ func breakglass() error {
"an alternative per-user configuration file for ssh and scp") "an alternative per-user configuration file for ssh and scp")
) )
// TODO: remove the -tls and -gokrazy_url flags after 2023-June (half a year
// after the introduction of instance centric config), so that we can then
// merge these flags into tools/internal/oldpacker and remove their global
// state.
tlsflag.RegisterFlags(flag.CommandLine)
updateflag.RegisterFlags(flag.CommandLine, "gokrazy_url")
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Usage of %s:\n\n", os.Args[0])
@@ -221,6 +231,13 @@ func breakglass() error {
log.Fatalf("syntax: breakglass <hostname> [command]") log.Fatalf("syntax: breakglass <hostname> [command]")
} }
// If the user did not explicitly specify -update=yes, we default to it.
// This differs from the gokr-packer, but breakglass is only useful for
// gokrazy instances that already exist.
if updateflag.NewInstallation() {
updateflag.SetUpdate("yes")
}
instance := flag.Arg(0) instance := flag.Arg(0)
instanceflag.SetInstance(instance) instanceflag.SetInstance(instance)
@@ -238,8 +255,6 @@ func breakglass() error {
cfg: cfg, cfg: cfg,
forceRestart: *forceRestart, forceRestart: *forceRestart,
sshConfig: *sshConfig, sshConfig: *sshConfig,
insecure: *insecure,
update: updateflag.Value{Update: "yes"},
} }
if cfg.Update.Hostname == "" { if cfg.Update.Hostname == "" {
cfg.Update.Hostname = cfg.Hostname cfg.Update.Hostname = cfg.Hostname

23
go.mod
View File

@@ -1,27 +1,22 @@
module github.com/gokrazy/breakglass module github.com/gokrazy/breakglass
go 1.24.0 go 1.21
require ( require (
github.com/gokrazy/gokapi v0.0.0-20251205165548-0927bab199d4 github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83
github.com/gokrazy/gokrazy v0.0.0-20251120071335-9c06b898c109 github.com/gokrazy/internal v0.0.0-20250126213949-423a5b587b57
github.com/gokrazy/internal v0.0.0-20251209163600-c74b4e7749e8 github.com/google/renameio/v2 v2.0.0
github.com/google/renameio/v2 v2.0.1
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/kr/pty v1.1.8 github.com/kr/pty v1.1.8
github.com/pkg/sftp v1.13.10 github.com/pkg/sftp v1.13.5
golang.org/x/crypto v0.46.0 golang.org/x/crypto v0.31.0
) )
require ( require (
github.com/antihax/optional v1.0.0 // indirect github.com/creack/pty v1.1.18 // indirect
github.com/creack/pty v1.1.24 // indirect
github.com/kenshaw/evdev v0.1.0 // indirect github.com/kenshaw/evdev v0.1.0 // indirect
github.com/kr/fs v0.1.0 // indirect github.com/kr/fs v0.1.0 // indirect
github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 // indirect github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 // indirect
github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/vishvananda/netlink v1.3.1 // indirect golang.org/x/sys v0.28.0 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sys v0.39.0 // indirect
) )

55
go.sum
View File

@@ -1,31 +1,16 @@
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83 h1:Y4sADvUYd/c0eqnqebipHHl0GMpAxOQeTzPnwI4ievM=
github.com/gokrazy/gokapi v0.0.0-20250222071133-506fdb322775 h1:f5+2UMRRbr3+e/gdWCBNn48chS/KMMljfbmlSSHfRBA= github.com/gokrazy/gokrazy v0.0.0-20230812092215-346db1998f83/go.mod h1:9q5Tg+q+YvRjC3VG0gfMFut46dhbhtAnvUEp4lPjc6c=
github.com/gokrazy/gokapi v0.0.0-20250222071133-506fdb322775/go.mod h1:q9mIV8al0wqmqFXJhKiO3SOHkL9/7Q4kIMynqUQWhgU= github.com/gokrazy/internal v0.0.0-20250126213949-423a5b587b57 h1:f5bEvO4we3fbfiBkECrrUgWQ8OH6J3SdB2Dwxid/Yx4=
github.com/gokrazy/gokapi v0.0.0-20251205165548-0927bab199d4 h1:XFo3EqnHUbmAySp7zqms8ee/tU8bM9k+YzT7L4o5CcQ= github.com/gokrazy/internal v0.0.0-20250126213949-423a5b587b57/go.mod h1:SJG1KwuJQXFEoBgryaNCkMbdISyovDgZd0xmXJRZmiw=
github.com/gokrazy/gokapi v0.0.0-20251205165548-0927bab199d4/go.mod h1:+StofDb/2cMb7vbA2znaNolgp9SadTYeyRIFtdhH1KQ=
github.com/gokrazy/gokrazy v0.0.0-20250222061409-bd0bb5f1d0b5 h1:VQhDGxRliP4ZTQ8+33v4VKtOpX4VzN8pA4zBMZQSSxs=
github.com/gokrazy/gokrazy v0.0.0-20250222061409-bd0bb5f1d0b5/go.mod h1:6fAh0J7aH6o5HWSiwN6uxNlm6Rjx1BxeNMWyNBQZ6sI=
github.com/gokrazy/gokrazy v0.0.0-20251120071335-9c06b898c109 h1:bOGq8uswYxUcDDrhr49SJFaiYBfhBkjaLZq4JXASGWE=
github.com/gokrazy/gokrazy v0.0.0-20251120071335-9c06b898c109/go.mod h1:NtMkrFeDGnwldKLi0dLdd2ipNwoVa7TI4HTxsy7lFRg=
github.com/gokrazy/internal v0.0.0-20251208203110-3c1aa9087c82 h1:4ghNfD9NaZLpFrqQiBF6mPVFeMYXJSky38ubVA4ic2E=
github.com/gokrazy/internal v0.0.0-20251208203110-3c1aa9087c82/go.mod h1:dQY4EMkD4L5ZjYJ0SPtpgYbV7MIUMCxNIXiOfnZ6jP4=
github.com/gokrazy/internal v0.0.0-20251209163600-c74b4e7749e8 h1:oDssNvynxA1AFJEEDDrFnRWwcmrRraj9BoXftZAKut4=
github.com/gokrazy/internal v0.0.0-20251209163600-c74b4e7749e8/go.mod h1:dQY4EMkD4L5ZjYJ0SPtpgYbV7MIUMCxNIXiOfnZ6jP4=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
github.com/google/renameio/v2 v2.0.1 h1:HyOM6qd9gF9sf15AvhbptGHUnaLTpEI9akAFFU3VyW0=
github.com/google/renameio/v2 v2.0.1/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo= github.com/kenshaw/evdev v0.1.0 h1:wmtceEOFfilChgdNT+c/djPJ2JineVsQ0N14kGzFRUo=
@@ -38,46 +23,26 @@ github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 h1:80FAK3TW5lVym
github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5/go.mod h1:z0QjVpjpK4jksEkffQwS3+abQ3XFTm1bnimyDzWyUk0= github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5/go.mod h1:z0QjVpjpK4jksEkffQwS3+abQ3XFTm1bnimyDzWyUk0=
github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

22
ssh.go
View File

@@ -14,7 +14,6 @@ import (
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
"time"
"unsafe" "unsafe"
"github.com/gokrazy/gokrazy" "github.com/gokrazy/gokrazy"
@@ -221,14 +220,6 @@ type exitStatus struct {
Status uint32 Status uint32
} }
func shellWorks(shell string) bool {
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()
cmd := exec.CommandContext(ctx, shell, "-c", "exit 58")
cmd.Run()
return cmd.ProcessState != nil && cmd.ProcessState.ExitCode() == 58
}
func findShell() string { func findShell() string {
if _, err := os.Stat(wellKnownBusybox); err == nil { if _, err := os.Stat(wellKnownBusybox); err == nil {
// Install busybox to /bin to provide the typical userspace utilities // Install busybox to /bin to provide the typical userspace utilities
@@ -238,13 +229,13 @@ func findShell() string {
// fallthrough, we don't return /bin/sh as we read /etc/passwd // fallthrough, we don't return /bin/sh as we read /etc/passwd
} }
} }
if _, err := exec.LookPath(shell); path.IsAbs(shell) && shellWorks(shell) && err == nil { if _, err := exec.LookPath(shell); path.IsAbs(shell) && err == nil {
return shell return shell
} }
if path, err := exec.LookPath("bash"); shellWorks(path) && err == nil { if path, err := exec.LookPath("bash"); err == nil {
return path return path
} }
if path, err := exec.LookPath("sh"); shellWorks(path) && err == nil { if path, err := exec.LookPath("sh"); err == nil {
return path return path
} }
const wellKnownSerialShell = "/tmp/serial-busybox/ash" const wellKnownSerialShell = "/tmp/serial-busybox/ash"
@@ -264,9 +255,6 @@ func (s *session) request(ctx context.Context, req *ssh.Request, conn *ssh.Serve
if err := ssh.Unmarshal(req.Payload, &r); err != nil { if err := ssh.Unmarshal(req.Payload, &r); err != nil {
return err return err
} }
if r.TERM != "" {
s.env = append(s.env, fmt.Sprintf("TERM=%s", r.TERM))
}
var err error var err error
s.ptyf, s.ttyf, err = pty.Open() s.ptyf, s.ttyf, err = pty.Open()
@@ -315,12 +303,12 @@ func (s *session) request(ctx context.Context, req *ssh.Request, conn *ssh.Serve
if err != nil { if err != nil {
return err return err
} }
defer srv.Close()
exitCode := uint32(0) exitCode := uint32(0)
if err := srv.Serve(); err != nil { if err := srv.Serve(); err != nil {
log.Printf("(sftp.Server).Serve(): %v", err) log.Printf("(sftp.Server).Serve(): %v", err)
if err == io.EOF { if err == io.EOF {
defer srv.Close()
log.Printf("sftp client exited session") log.Printf("sftp client exited session")
} else { } else {
exitCode = 1 exitCode = 1
@@ -387,7 +375,7 @@ func (s *session) request(ctx context.Context, req *ssh.Request, conn *ssh.Serve
var cmd *exec.Cmd var cmd *exec.Cmd
if shell := findShell(); shell != "" { if shell := findShell(); shell != "" {
if len(cmdline) == 0 || (len(cmdline) == 1 && cmdline[0] == "sh") { if r.Command == "sh" {
cmd = exec.CommandContext(ctx, shell, "-l") cmd = exec.CommandContext(ctx, shell, "-l")
} else { } else {
cmd = exec.CommandContext(ctx, shell, "-c", r.Command) cmd = exec.CommandContext(ctx, shell, "-c", r.Command)