diff --git a/Gopkg.lock b/Gopkg.lock index fe240ed3..33ded270 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -96,7 +96,7 @@ branch = "master" name = "golang.org/x/crypto" packages = ["curve25519","ed25519","ed25519/internal/edwards25519","internal/chacha20","internal/subtle","poly1305","ssh","ssh/knownhosts","ssh/testdata"] - revision = "90ce128f82205b845596a209e55f128f7c4000ec" + revision = "0a9e5a7b288dccb74e2efd0fe62005aaf2a6ddbb" source = "https://github.com/tg123/sshpiper.crypto" [[projects]] diff --git a/sshpiperd/challenger/welcometext/welcometext.go b/sshpiperd/challenger/welcometext/welcometext.go deleted file mode 100644 index 8ba0def5..00000000 --- a/sshpiperd/challenger/welcometext/welcometext.go +++ /dev/null @@ -1,34 +0,0 @@ -package challenger - -import ( - "log" - - "golang.org/x/crypto/ssh" - - "github.com/tg123/sshpiper/sshpiperd/challenger" -) - -func makeWelcomeChallenger(text string) challenger.Handler { - return func(conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge) (ssh.AdditionalChallengeContext, error) { - - client(conn.User(), text, nil, nil) - - return nil, nil - } -} - -func init() { - - var h challenger.Handler - - config := &struct { - WelcomeText string `long:"challenger-welcometext" description:"Show a welcome text when connect to sshpiper server" env:"SSHPIPERD_CHALLENGER_WELCOMETEXT" ini-name:"challenger-welcometext"` - }{} - - challenger.Register("welcometext", challenger.NewFromHandler("welcometext", func() challenger.Handler { - return h - }, config, func(logger *log.Logger) error { - h = makeWelcomeChallenger(config.WelcomeText) - return nil - })) -} diff --git a/sshpiperd/loader.go b/sshpiperd/loader.go index 362bbb60..019452e4 100644 --- a/sshpiperd/loader.go +++ b/sshpiperd/loader.go @@ -6,7 +6,6 @@ import ( _ "github.com/tg123/sshpiper/sshpiperd/challenger/azdevicecode" _ "github.com/tg123/sshpiper/sshpiperd/challenger/pam" - _ "github.com/tg123/sshpiper/sshpiperd/challenger/welcometext" _ "github.com/tg123/sshpiper/sshpiperd/auditor/typescriptlogger" ) diff --git a/sshpiperd/sshpiperd.go b/sshpiperd/sshpiperd.go index 6f291ad5..04425f2a 100644 --- a/sshpiperd/sshpiperd.go +++ b/sshpiperd/sshpiperd.go @@ -21,7 +21,10 @@ type piperdConfig struct { UpstreamDriver string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"` ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"` - AuditorDriver string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper " env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"` + AuditorDriver string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper" env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"` + + BannerText string `long:"banner-text" description:"Display a banner before authentication, would be ignored if banner file was set" env:"SSHPIPERD_BANNERTEXT" ini-name:"banner-text" ` + BannerFile string `long:"banner-file" description:"Display a banner from file before authentication" env:"SSHPIPERD_BANNERFILE" ini-name:"banner-file" ` } func getAndInstall(reg, name string, get func(n string) registry.Plugin, install func(plugin registry.Plugin) error, logger *log.Logger) error { @@ -121,11 +124,13 @@ func startPiper(config *piperdConfig, logger *log.Logger) error { piper := &ssh.PiperConfig{} + // drivers bigbro, err := installDrivers(piper, config, logger) if err != nil { return err } + // listeners privateBytes, err := ioutil.ReadFile(config.PiperKeyFile) if err != nil { return err @@ -144,6 +149,26 @@ func startPiper(config *piperdConfig, logger *log.Logger) error { } defer listener.Close() + // banner + if config.BannerFile != "" { + + piper.BannerCallback = func(conn ssh.ConnMetadata) string { + + msg, err := ioutil.ReadFile(config.BannerFile) + + if err != nil { + logger.Printf("failed to read banner file: %v", err) + return "" + } + + return string(msg) + } + } else if config.BannerText != "" { + piper.BannerCallback = func(conn ssh.ConnMetadata) string { + return config.BannerText + "\n" + } + } + logger.Printf("sshpiperd started") for { diff --git a/vendor/golang.org/x/crypto/ssh/sshpiper.go b/vendor/golang.org/x/crypto/ssh/sshpiper.go index 412ed259..9bda4b56 100644 --- a/vendor/golang.org/x/crypto/ssh/sshpiper.go +++ b/vendor/golang.org/x/crypto/ssh/sshpiper.go @@ -98,6 +98,10 @@ type PiperConfig struct { // Note that RFC 4253 section 4.2 requires that this string start with // "SSH-2.0-". ServerVersion string + + // BannerCallback, if present, is called and the return string is sent to + // the client after key exchange completed but before authentication. + BannerCallback func(conn ConnMetadata) string } type upstream struct{ *connection } @@ -207,6 +211,18 @@ func NewSSHPiperConn(conn net.Conn, piper *PiperConfig) (pipe *PiperConn, err er d.user = userAuthReq.User + if piper.BannerCallback != nil { + msg := piper.BannerCallback(d) + if msg != "" { + bannerMsg := &userAuthBannerMsg{ + Message: msg, + } + if err := d.transport.writePacket(Marshal(bannerMsg)); err != nil { + return nil, err + } + } + } + var challengeCtx AdditionalChallengeContext // need additional challenge