From c726d20578c54deb98fa438ae6ce324ab719b259 Mon Sep 17 00:00:00 2001 From: Nate Brown Date: Mon, 7 Jun 2021 17:06:59 -0500 Subject: [PATCH] Fix single command ssh exec (#483) --- CHANGELOG.md | 6 ++++++ ssh.go | 12 ++++++++++++ sshd/session.go | 15 +++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6681ffc..79a9af2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- SSH `print-cert` has a new `-raw` flag to get the PEM representation of a certificate. (#483) + ### Fixed - Valid recv_error packets were incorrectly marked as "spoofing" and ignored. (#482) +- SSH server handles single `exec` requests correctly. (#483) + ## [1.4.0] - 2021-05-11 ### Added diff --git a/ssh.go b/ssh.go index 4cfaf1d..dec676e 100644 --- a/ssh.go +++ b/ssh.go @@ -26,6 +26,7 @@ type sshListHostMapFlags struct { type sshPrintCertFlags struct { Json bool Pretty bool + Raw bool } type sshPrintTunnelFlags struct { @@ -266,6 +267,7 @@ func attachCommands(l *logrus.Logger, ssh *sshd.SSHServer, hostMap *HostMap, pen s := sshPrintCertFlags{} fl.BoolVar(&s.Json, "json", false, "outputs as json") fl.BoolVar(&s.Pretty, "pretty", false, "pretty prints json, assumes -json") + fl.BoolVar(&s.Raw, "raw", false, "raw prints the PEM encoded certificate, not compatible with -json or -pretty") return fl, &s }, Callback: func(fs interface{}, a []string, w sshd.StringWriter) error { @@ -711,6 +713,16 @@ func sshPrintCert(ifce *Interface, fs interface{}, a []string, w sshd.StringWrit return w.WriteBytes(b) } + if args.Raw { + b, err := cert.MarshalToPEM() + if err != nil { + //TODO: handle it + return nil + } + + return w.WriteBytes(b) + } + return w.WriteLine(cert.String()) } diff --git a/sshd/session.go b/sshd/session.go index 864678a..bba2a55 100644 --- a/sshd/session.go +++ b/sshd/session.go @@ -81,11 +81,18 @@ func (s *session) handleRequests(in <-chan *ssh.Request, channel ssh.Channel) { case "exec": var payload = struct{ Value string }{} cErr := ssh.Unmarshal(req.Payload, &payload) - if cErr == nil { - s.dispatchCommand(payload.Value, &stringWriter{channel}) - } else { - //TODO: log it + if cErr != nil { + req.Reply(false, nil) + return } + + req.Reply(true, nil) + s.dispatchCommand(payload.Value, &stringWriter{channel}) + + //TODO: Fix error handling and report the proper status back + status := struct{ Status uint32 }{uint32(0)} + //TODO: I think this is how we shut down a shell as well? + channel.SendRequest("exit-status", false, ssh.Marshal(status)) channel.Close() return