| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- package cli
- import (
- "crypto/ed25519"
- "crypto/rand"
- "errors"
- "net"
- "strings"
- "testing"
- "time"
- "golang.org/x/crypto/ssh"
- "debtik/internal/auth"
- )
- func TestSSHExecReportsFailureAndPreservesLongCommands(t *testing.T) {
- _, private, err := ed25519.GenerateKey(rand.Reader)
- if err != nil {
- t.Fatal(err)
- }
- signer, err := ssh.NewSignerFromKey(private)
- if err != nil {
- t.Fatal(err)
- }
- config := &ssh.ServerConfig{NoClientAuth: true}
- config.AddHostKey(signer)
- l, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatal(err)
- }
- defer l.Close()
- server := &SSHServer{executor: &Executor{}}
- done := make(chan struct{})
- go func() {
- defer close(done)
- raw, err := l.Accept()
- if err != nil {
- return
- }
- defer raw.Close()
- conn, chans, reqs, err := ssh.NewServerConn(raw, config)
- if err != nil {
- return
- }
- defer conn.Close()
- go ssh.DiscardRequests(reqs)
- for ch := range chans {
- channel, requests, err := ch.Accept()
- if err == nil {
- go server.handleSession(channel, requests, &auth.PublicUser{Role: auth.RoleFull})
- }
- }
- }()
- client, err := ssh.Dial("tcp", l.Addr().String(), &ssh.ClientConfig{User: "test", HostKeyCallback: ssh.FixedHostKey(signer.PublicKey()), Timeout: 3 * time.Second})
- if err != nil {
- t.Fatal(err)
- }
- defer func() { client.Close(); <-done }()
- for _, command := range []string{"/log", "/help", "unknown", "/interface print", strings.Repeat("x", 70000)} {
- session, err := client.NewSession()
- if err != nil {
- t.Fatal(err)
- }
- output, err := session.CombinedOutput(command)
- session.Close()
- if command == "/log" || command == "/help" {
- if err != nil {
- t.Fatalf("valid command failed: %v", err)
- }
- } else {
- var exit *ssh.ExitError
- if !errors.As(err, &exit) || exit.ExitStatus() != 1 {
- t.Fatalf("failure reported success: %v", err)
- }
- if len(command) > 65535 && !strings.Contains(string(output), command) {
- t.Fatal("long command truncated")
- }
- }
- }
- }
|