Преглед на файлове

Fix single command ssh exec (#483)

Nate Brown преди 4 години
родител
ревизия
c726d20578
променени са 3 файла, в които са добавени 29 реда и са изтрити 4 реда
  1. 6 0
      CHANGELOG.md
  2. 12 0
      ssh.go
  3. 11 4
      sshd/session.go

+ 6 - 0
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

+ 12 - 0
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())
 }
 

+ 11 - 4
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