1111package main
1212
1313import (
14+ "bytes"
1415 "context"
1516 "errors"
1617 "flag"
@@ -34,6 +35,7 @@ import (
3435 "github.com/moby/term"
3536 "github.com/op/go-logging"
3637 "go.etcd.io/etcd/client/v3"
38+ "golang.org/x/crypto/ssh"
3739)
3840
3941var (
@@ -206,6 +208,42 @@ type ConnInfo struct {
206208 SSH * SSHInfo // SSH source and destination (from SSH_CONNECTION)
207209}
208210
211+ // GetOriginalCommand returns the force-command included in the client ssh
212+ // certificate, if any. Otherwise, it returns the content of the environment
213+ // variable SSH_ORIGINAL_COMMAND. No error is returned. In case of any error,
214+ // the content of SSH_ORIGINAL_COMMAND will be returned. The second returned
215+ // string is a comment for debugging purpose.
216+ func getOriginalCommand () (string , string ) {
217+ userAuthFile := os .Getenv ("SSH_USER_AUTH" )
218+ if userAuthFile != "" {
219+ // The environment variable is present
220+ content , err := os .ReadFile (userAuthFile )
221+ if err == nil {
222+ // The temporary file is read
223+ prefix := []byte ("publickey " )
224+ key , found := bytes .CutPrefix (content , prefix )
225+ if found {
226+ // The file contains a publickey
227+ pubKey , _ , _ , _ , err := ssh .ParseAuthorizedKey (key )
228+ if err == nil {
229+ // The pubilckey is parsed
230+ cert , ok := pubKey .(* ssh.Certificate )
231+ if ok && cert .Permissions .CriticalOptions != nil && cert .Permissions .CriticalOptions ["force-command" ] != "" {
232+ // the publickey is a certificate, and contains a
233+ // force-command
234+ return cert .Permissions .CriticalOptions ["force-command" ], " (forced) "
235+ }
236+ } else {
237+ log .Warning (err )
238+ }
239+ }
240+ } else {
241+ log .Warning (err )
242+ }
243+ }
244+ return os .Getenv ("SSH_ORIGINAL_COMMAND" ), " "
245+ }
246+
209247func main () {
210248 os .Exit (mainExitCode ())
211249}
@@ -428,8 +466,8 @@ func mainExitCode() int {
428466 }
429467 }()
430468
431- originalCmd := os . Getenv ( "SSH_ORIGINAL_COMMAND" )
432- log .Debugf ("original command = %s" , originalCmd )
469+ originalCmd , comment := getOriginalCommand ( )
470+ log .Debugf ("original command%s = %s" , comment , originalCmd )
433471
434472 interactiveCommand := term .IsTerminal (os .Stdout .Fd ())
435473 log .Debugf ("interactiveCommand = %v" , interactiveCommand )
0 commit comments