aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ci/testsshd/go.mod7
-rw-r--r--ci/testsshd/go.sum6
-rw-r--r--ci/testsshd/main.go149
3 files changed, 0 insertions, 162 deletions
diff --git a/ci/testsshd/go.mod b/ci/testsshd/go.mod
deleted file mode 100644
index 88ccdc7..0000000
--- a/ci/testsshd/go.mod
+++ /dev/null
@@ -1,7 +0,0 @@
-module rsend/ci/testsshd
-
-go 1.25.0
-
-require golang.org/x/crypto v0.53.0
-
-require golang.org/x/sys v0.46.0 // indirect
diff --git a/ci/testsshd/go.sum b/ci/testsshd/go.sum
deleted file mode 100644
index 68cadc1..0000000
--- a/ci/testsshd/go.sum
+++ /dev/null
@@ -1,6 +0,0 @@
-golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
-golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
-golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
-golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
-golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
diff --git a/ci/testsshd/main.go b/ci/testsshd/main.go
deleted file mode 100644
index 19a53ac..0000000
--- a/ci/testsshd/main.go
+++ /dev/null
@@ -1,149 +0,0 @@
-// testsshd is a minimal SSH server for rsend integration tests: one host key,
-// an authorized_keys allowlist, and command execution via /bin/sh (so it runs
-// the remote rsync). It is not a product component; it stands in for a real
-// sshd so the full push path can be exercised on a device or in CI.
-package main
-
-import (
- "flag"
- "io"
- "log"
- "net"
- "os"
- "os/exec"
-
- "golang.org/x/crypto/ssh"
-)
-
-func main() {
- addr := flag.String("addr", "127.0.0.1:2222", "listen address")
- hostKeyPath := flag.String("hostkey", "", "OpenSSH private host key (required)")
- authPath := flag.String("authorized", "", "authorized_keys file (required)")
- flag.Parse()
-
- if *hostKeyPath == "" || *authPath == "" {
- log.Fatal("testsshd: -hostkey and -authorized are required")
- }
-
- hostKey := mustSigner(*hostKeyPath)
- allowed := mustAuthorized(*authPath)
-
- cfg := &ssh.ServerConfig{
- PublicKeyCallback: func(_ ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
- if allowed[string(key.Marshal())] {
- return &ssh.Permissions{}, nil
- }
- return nil, io.EOF
- },
- }
- cfg.AddHostKey(hostKey)
-
- ln, err := net.Listen("tcp", *addr)
- if err != nil {
- log.Fatalf("testsshd: listen: %v", err)
- }
- log.Printf("testsshd: listening on %s", ln.Addr())
- for {
- c, err := ln.Accept()
- if err != nil {
- log.Fatalf("testsshd: accept: %v", err)
- }
- go handle(c, cfg)
- }
-}
-
-func mustSigner(path string) ssh.Signer {
- b, err := os.ReadFile(path)
- if err != nil {
- log.Fatalf("testsshd: read host key: %v", err)
- }
- s, err := ssh.ParsePrivateKey(b)
- if err != nil {
- log.Fatalf("testsshd: parse host key: %v", err)
- }
- return s
-}
-
-func mustAuthorized(path string) map[string]bool {
- b, err := os.ReadFile(path)
- if err != nil {
- log.Fatalf("testsshd: read authorized_keys: %v", err)
- }
- m := map[string]bool{}
- for len(b) > 0 {
- key, _, _, rest, err := ssh.ParseAuthorizedKey(b)
- if err != nil {
- break
- }
- m[string(key.Marshal())] = true
- b = rest
- }
- if len(m) == 0 {
- log.Fatal("testsshd: no authorized keys")
- }
- return m
-}
-
-func handle(nConn net.Conn, cfg *ssh.ServerConfig) {
- conn, chans, reqs, err := ssh.NewServerConn(nConn, cfg)
- if err != nil {
- return
- }
- defer conn.Close()
- go ssh.DiscardRequests(reqs)
- for nc := range chans {
- if nc.ChannelType() != "session" {
- nc.Reject(ssh.UnknownChannelType, "only session")
- continue
- }
- ch, requests, err := nc.Accept()
- if err != nil {
- return
- }
- go session(ch, requests)
- }
-}
-
-func session(ch ssh.Channel, requests <-chan *ssh.Request) {
- for req := range requests {
- if req.Type != "exec" {
- if req.WantReply {
- req.Reply(false, nil)
- }
- continue
- }
- var payload struct{ Command string }
- ssh.Unmarshal(req.Payload, &payload)
- if req.WantReply {
- req.Reply(true, nil)
- }
- code := run(payload.Command, ch)
- ch.SendRequest("exit-status", false, ssh.Marshal(struct{ Status uint32 }{uint32(code)}))
- ch.Close()
- return
- }
-}
-
-func run(cmd string, ch ssh.Channel) int {
- c := exec.Command("/bin/sh", "-c", cmd)
- c.Stdout = ch
- c.Stderr = ch.Stderr()
- in, err := c.StdinPipe()
- if err != nil {
- return 1
- }
- if err := c.Start(); err != nil {
- return 1
- }
- go func() {
- io.Copy(in, ch)
- in.Close()
- }()
- if err := c.Wait(); err != nil {
- if ee, ok := err.(*exec.ExitError); ok {
- return ee.ExitCode()
- }
- return 1
- }
- return 0
-}