diff --git a/Gopkg.lock b/Gopkg.lock index fb77aa73..87b1f74b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -25,14 +25,6 @@ revision = "3f9954f6f6697845b082ca57995849ddf614f450" version = "v1.3.3" -[[projects]] - branch = "master" - digest = "1:1a200e7e73293b75eb8e5c93d023b5472663432da0b663e1532624fcfede9ca8" - name = "github.com/anmitsu/go-shlex" - packages = ["."] - pruneopts = "UT" - revision = "648efa622239a2f6ff949fed78ee37b48d499ba4" - [[projects]] digest = "1:d6afaeed1502aa28e80a4ed0981d570ad91b2579193404256ce672ed0a609e0d" name = "github.com/beorn7/perks" @@ -120,14 +112,6 @@ revision = "95778dfbb74eb7e4dbaf43bf7d71809650ef8076" version = "v19" -[[projects]] - digest = "1:385dff5bf83bf1c9d40ef2b0f2e697f0d1973fc9e24ae9401cf41698612bbebc" - name = "github.com/creack/pty" - packages = ["."] - pruneopts = "UT" - revision = "2769f65a3a94eb8f876f44a0459d24ae7ad2e488" - version = "v1.1.7" - [[projects]] digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" name = "github.com/davecgh/go-spew" @@ -193,14 +177,6 @@ pruneopts = "UT" revision = "ed7bcb39ff10f39ab08e317ce16df282845852fa" -[[projects]] - digest = "1:0a01355005024757ae2a1f62e8fe68a30b4f5fde7a08ac88b3685e7999ac354b" - name = "github.com/gliderlabs/ssh" - packages = ["."] - pruneopts = "UT" - revision = "5b6cc7030f17095c0cf23bb063b0bfe824fe5f8b" - version = "v0.2.2" - [[projects]] digest = "1:ec6f9bf5e274c833c911923c9193867f3f18788c461f76f05f62bb1510e0ae65" name = "github.com/go-sql-driver/mysql" @@ -757,12 +733,10 @@ "github.com/coredns/coredns/request", "github.com/coreos/go-oidc", "github.com/coreos/go-systemd/daemon", - "github.com/creack/pty", "github.com/denisenkom/go-mssqldb", "github.com/equinox-io/equinox", "github.com/facebookgo/grace/gracenet", "github.com/getsentry/raven-go", - "github.com/gliderlabs/ssh", "github.com/go-sql-driver/mysql", "github.com/golang-collections/collections/queue", "github.com/google/uuid", diff --git a/Gopkg.toml b/Gopkg.toml index 252b8690..da88ce70 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -115,11 +115,3 @@ [[constraint]] branch = "v2" name = "github.com/coreos/go-oidc" - -[[constraint]] - name = "github.com/gliderlabs/ssh" - version = "0.2.2" - -[[constraint]] - name = "github.com/creack/pty" - version = "1.1.7" diff --git a/RELEASE_NOTES b/RELEASE_NOTES index b9175c7f..085653e9 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,9 +1,3 @@ -2019.8.2 -- 2019-08-20 STOR-519: Add db-connect, a SQL over HTTPS server -- 2019-08-11 TUN-2163: Add GrapQLType method to Scope interface -- 2019-08-06 TUN-2152: Requests with a query in the URL are erroneously escaped -- 2019-07-18 AUTH-1941: Adds initial SSH server implementation - 2019.8.1 - 2019-08-05 TUN-2111: Implement custom serialization logic for FallibleConfig and OriginConfig - 2019-08-06 Revert "TUN-1736: Missing headers when passing an invalid path" diff --git a/cmd/cloudflared/tunnel/cmd.go b/cmd/cloudflared/tunnel/cmd.go index cc37123d..20409045 100644 --- a/cmd/cloudflared/tunnel/cmd.go +++ b/cmd/cloudflared/tunnel/cmd.go @@ -8,32 +8,31 @@ import ( "net/url" "os" "reflect" - "runtime" "runtime/trace" "sync" "time" + "github.com/cloudflare/cloudflared/dbconnect" + "github.com/cloudflare/cloudflared/tunnelrpc/pogs" + + "github.com/cloudflare/cloudflared/connection" + "github.com/cloudflare/cloudflared/supervisor" + "github.com/google/uuid" + + "github.com/getsentry/raven-go" + "github.com/cloudflare/cloudflared/cmd/cloudflared/buildinfo" "github.com/cloudflare/cloudflared/cmd/cloudflared/config" "github.com/cloudflare/cloudflared/cmd/cloudflared/updater" - "github.com/cloudflare/cloudflared/connection" - "github.com/cloudflare/cloudflared/dbconnect" "github.com/cloudflare/cloudflared/hello" "github.com/cloudflare/cloudflared/metrics" "github.com/cloudflare/cloudflared/origin" "github.com/cloudflare/cloudflared/signal" - "github.com/cloudflare/cloudflared/sshserver" - "github.com/cloudflare/cloudflared/supervisor" "github.com/cloudflare/cloudflared/tlsconfig" "github.com/cloudflare/cloudflared/tunneldns" - "github.com/cloudflare/cloudflared/tunnelrpc/pogs" "github.com/cloudflare/cloudflared/websocket" - "github.com/coreos/go-systemd/daemon" "github.com/facebookgo/grace/gracenet" - "github.com/getsentry/raven-go" - "github.com/gliderlabs/ssh" - "github.com/google/uuid" "github.com/pkg/errors" "gopkg.in/urfave/cli.v2" "gopkg.in/urfave/cli.v2/altsrc" @@ -291,31 +290,6 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan c.Set("url", "https://"+helloListener.Addr().String()) } - if c.IsSet("ssh-server") { - if runtime.GOOS != "darwin" && runtime.GOOS != "linux" { - logger.Errorf("--ssh-server is not supported on %s", runtime.GOOS) - return errors.New(fmt.Sprintf("--ssh-server is not supported on %s", runtime.GOOS)) - - } - - logger.Infof("ssh-server set") - - sshServerAddress := "127.0.0.1:" + c.String("local-ssh-port") - server, err := sshserver.New(logger, sshServerAddress, shutdownC) - if err != nil { - logger.WithError(err).Error("Cannot create new SSH Server") - return errors.Wrap(err, "Cannot create new SSH Server") - } - wg.Add(1) - go func() { - defer wg.Done() - if err = server.Start(); err != nil && err != ssh.ErrServerClosed { - logger.WithError(err).Error("SSH server error") - } - }() - c.Set("url", "ssh://"+sshServerAddress) - } - if host := hostnameFromURI(c.String("url")); host != "" { listener, err := net.Listen("tcp", "127.0.0.1:") if err != nil { @@ -339,7 +313,6 @@ func StartServer(c *cli.Context, version string, shutdownC, graceShutdownC chan go func() { defer wg.Done() errC <- origin.StartTunnelDaemon(ctx, tunnelConfig, connectedSignal, cloudflaredID) - errC <- origin.StartTunnelDaemon(ctx, tunnelConfig, connectedSignal, cloudflaredID) }() return waitToShutdown(&wg, errC, shutdownC, graceShutdownC, c.Duration("grace-period")) @@ -776,13 +749,6 @@ func tunnelFlags(shouldHide bool) []cli.Flag { EnvVars: []string{"TUNNEL_HELLO_WORLD"}, Hidden: shouldHide, }), - altsrc.NewBoolFlag(&cli.BoolFlag{ - Name: "ssh-server", - Value: false, - Usage: "Run an SSH Server", - EnvVars: []string{"TUNNEL_SSH_SERVER"}, - Hidden: true, // TODO: remove when feature is complete - }), altsrc.NewStringFlag(&cli.StringFlag{ Name: "pidfile", Usage: "Write the application's PID to this file after first successful connection.", @@ -925,12 +891,5 @@ func tunnelFlags(shouldHide bool) []cli.Flag { EnvVars: []string{"DIAL_EDGE_TIMEOUT"}, Hidden: true, }), - altsrc.NewStringFlag(&cli.StringFlag{ - Name: "local-ssh-port", - Usage: "Localhost port that cloudflared SSH server will run on", - Value: "22", - EnvVars: []string{"LOCAL_SSH_PORT"}, - Hidden: true, - }), } } diff --git a/sshserver/sshserver.go b/sshserver/sshserver.go deleted file mode 100644 index a8379df1..00000000 --- a/sshserver/sshserver.go +++ /dev/null @@ -1,168 +0,0 @@ -package sshserver - -import ( - "bufio" - "fmt" - "github.com/pkg/errors" - "io" - "os" - "os/exec" - "os/user" - "strconv" - "syscall" - "unsafe" - - "github.com/creack/pty" - "github.com/gliderlabs/ssh" - "github.com/sirupsen/logrus" -) - -type SSHServer struct { - ssh.Server - logger *logrus.Logger - shutdownC chan struct{} -} - -const DefaultShellPrompt = `\e[0;31m[\u@\h \W]\$ \e[m ` - -func New(logger *logrus.Logger, address string, shutdownC chan struct{}) (*SSHServer, error) { - currentUser, err := user.Current() - if err != nil { - return nil, err - } - if currentUser.Uid != "0" { - return nil, errors.New("cloudflared ssh server needs to run as root") - } - - sshServer := SSHServer{ssh.Server{Addr: address}, logger, shutdownC} - return &sshServer, nil -} - -func (s *SSHServer) Start() error { - s.logger.Infof("Starting SSH server at %s", s.Addr) - - go func() { - <-s.shutdownC - if err := s.Close(); err != nil { - s.logger.WithError(err).Error("Cannot close SSH server") - } - }() - - s.Handle(s.connectionHandler) - return s.ListenAndServe() -} - -func (s *SSHServer) connectionHandler(session ssh.Session) { - - // Get uid and gid of user attempting to login - uid, gid, err := getUser(session.User()) - if err != nil { - if _, err := io.WriteString(session, "Invalid credentials\n"); err != nil { - s.logger.WithError(err).Error("Invalid credentials: Failed to write to SSH session") - } - if err := session.Exit(1); err != nil { - s.logger.WithError(err).Error("Failed to close SSH session") - } - return - } - - // Spawn shell under user - cmd := exec.Command("/bin/bash") - cmd.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: uid, Gid: gid}} - - ptyReq, winCh, isPty := session.Pty() - if !isPty { - if _, err := io.WriteString(session, "No PTY requested.\n"); err != nil { - s.logger.WithError(err).Error("No PTY requested: Failed to write to SSH session") - } - - if err := session.Exit(1); err != nil { - s.logger.WithError(err).Error("Failed to close SSH session") - } - return - } - - cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term)) - cmd.Env = append(cmd.Env, fmt.Sprintf("PS1=%s", DefaultShellPrompt)) - psuedoTTY, err := pty.Start(cmd) - if err != nil { - s.logger.WithError(err).Error("Failed to start pty session") - if err := session.Exit(1); err != nil { - s.logger.WithError(err).Error("Failed to close SSH session") - } - close(s.shutdownC) - return - } - - // Handle terminal window size changes - go func() { - for win := range winCh { - if errNo := setWinsize(psuedoTTY, win.Width, win.Height); errNo != 0 { - s.logger.WithError(err).Error("Failed to set pty window size: ", err.Error()) - if err := session.Exit(1); err != nil { - s.logger.WithError(err).Error("Failed to close SSH session") - } - close(s.shutdownC) - return - } - } - }() - - // Write incoming commands to PTY - go func() { - if _, err := io.Copy(psuedoTTY, session); err != nil { - s.logger.WithError(err).Error("Failed to write incoming command to pty") - } - }() - pr, pw := io.Pipe() - scanner := bufio.NewScanner(pr) - go func() { - for scanner.Scan() { - s.logger.Info(scanner.Text()) - } - }() - - // Write outgoing command output to both the command recorder, and remote user - mw := io.MultiWriter(pw, session) - if _, err := io.Copy(mw, psuedoTTY); err != nil { - s.logger.WithError(err).Error("Failed to write command output to user") - } - - if err := pw.Close(); err != nil { - s.logger.WithError(err).Error("Failed to close pipe writer") - } - - if err := pr.Close(); err != nil { - s.logger.WithError(err).Error("Failed to close pipe reader") - } - - // Wait for all resources associated with cmd to be released - // Returns error if shell exited with a non-zero status or received a signal - if err := cmd.Wait(); err != nil { - s.logger.WithError(err).Debug("Shell did not close correctly") - } -} - -// Sets PTY window size for terminal -func setWinsize(f *os.File, w, h int) syscall.Errno { - _, _, errNo := syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(syscall.TIOCSWINSZ), - uintptr(unsafe.Pointer(&struct{ h, w, x, y uint16 }{uint16(h), uint16(w), 0, 0}))) - return errNo -} - -// Only works on POSIX systems -func getUser(username string) (uint32, uint32, error) { - sshUser, err := user.Lookup(username) - if err != nil { - return 0, 0, err - } - uid, err := strconv.ParseUint(sshUser.Uid, 10, 32) - if err != nil { - return 0, 0, err - } - gid, err := strconv.ParseUint(sshUser.Gid, 10, 32) - if err != nil { - return 0, 0, err - } - return uint32(uid), uint32(gid), nil -} diff --git a/vendor/github.com/anmitsu/go-shlex/.gitignore b/vendor/github.com/anmitsu/go-shlex/.gitignore deleted file mode 100644 index 0b46bb5d..00000000 --- a/vendor/github.com/anmitsu/go-shlex/.gitignore +++ /dev/null @@ -1 +0,0 @@ -shlex.test diff --git a/vendor/github.com/anmitsu/go-shlex/LICENSE b/vendor/github.com/anmitsu/go-shlex/LICENSE deleted file mode 100644 index 4a17268a..00000000 --- a/vendor/github.com/anmitsu/go-shlex/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) anmitsu - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/anmitsu/go-shlex/README.md b/vendor/github.com/anmitsu/go-shlex/README.md deleted file mode 100644 index c4ffe72b..00000000 --- a/vendor/github.com/anmitsu/go-shlex/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# go-shlex - -go-shlex is a library to make a lexical analyzer like Unix shell for -Go. - -## Install - - go get -u "github.com/anmitsu/go-shlex" - -## Usage - -```go -package main - -import ( - "fmt" - "log" - - "github.com/anmitsu/go-shlex" -) - -func main() { - cmd := `cp -Rdp "file name" 'file name2' dir\ name` - words, err := shlex.Split(cmd, true) - if err != nil { - log.Fatal(err) - } - - for _, w := range words { - fmt.Println(w) - } -} -``` - -## Documentation - -http://godoc.org/github.com/anmitsu/go-shlex - diff --git a/vendor/github.com/anmitsu/go-shlex/shlex.go b/vendor/github.com/anmitsu/go-shlex/shlex.go deleted file mode 100644 index e742c38a..00000000 --- a/vendor/github.com/anmitsu/go-shlex/shlex.go +++ /dev/null @@ -1,193 +0,0 @@ -// Package shlex provides a simple lexical analysis like Unix shell. -package shlex - -import ( - "bufio" - "errors" - "io" - "strings" - "unicode" -) - -var ( - ErrNoClosing = errors.New("No closing quotation") - ErrNoEscaped = errors.New("No escaped character") -) - -// Tokenizer is the interface that classifies a token according to -// words, whitespaces, quotations, escapes and escaped quotations. -type Tokenizer interface { - IsWord(rune) bool - IsWhitespace(rune) bool - IsQuote(rune) bool - IsEscape(rune) bool - IsEscapedQuote(rune) bool -} - -// DefaultTokenizer implements a simple tokenizer like Unix shell. -type DefaultTokenizer struct{} - -func (t *DefaultTokenizer) IsWord(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r) -} -func (t *DefaultTokenizer) IsQuote(r rune) bool { - switch r { - case '\'', '"': - return true - default: - return false - } -} -func (t *DefaultTokenizer) IsWhitespace(r rune) bool { - return unicode.IsSpace(r) -} -func (t *DefaultTokenizer) IsEscape(r rune) bool { - return r == '\\' -} -func (t *DefaultTokenizer) IsEscapedQuote(r rune) bool { - return r == '"' -} - -// Lexer represents a lexical analyzer. -type Lexer struct { - reader *bufio.Reader - tokenizer Tokenizer - posix bool - whitespacesplit bool -} - -// NewLexer creates a new Lexer reading from io.Reader. This Lexer -// has a DefaultTokenizer according to posix and whitespacesplit -// rules. -func NewLexer(r io.Reader, posix, whitespacesplit bool) *Lexer { - return &Lexer{ - reader: bufio.NewReader(r), - tokenizer: &DefaultTokenizer{}, - posix: posix, - whitespacesplit: whitespacesplit, - } -} - -// NewLexerString creates a new Lexer reading from a string. This -// Lexer has a DefaultTokenizer according to posix and whitespacesplit -// rules. -func NewLexerString(s string, posix, whitespacesplit bool) *Lexer { - return NewLexer(strings.NewReader(s), posix, whitespacesplit) -} - -// Split splits a string according to posix or non-posix rules. -func Split(s string, posix bool) ([]string, error) { - return NewLexerString(s, posix, true).Split() -} - -// SetTokenizer sets a Tokenizer. -func (l *Lexer) SetTokenizer(t Tokenizer) { - l.tokenizer = t -} - -func (l *Lexer) Split() ([]string, error) { - result := make([]string, 0) - for { - token, err := l.readToken() - if token != "" { - result = append(result, token) - } - - if err == io.EOF { - break - } else if err != nil { - return result, err - } - } - return result, nil -} - -func (l *Lexer) readToken() (string, error) { - t := l.tokenizer - token := "" - quoted := false - state := ' ' - escapedstate := ' ' -scanning: - for { - next, _, err := l.reader.ReadRune() - if err != nil { - if t.IsQuote(state) { - return token, ErrNoClosing - } else if t.IsEscape(state) { - return token, ErrNoEscaped - } - return token, err - } - - switch { - case t.IsWhitespace(state): - switch { - case t.IsWhitespace(next): - break scanning - case l.posix && t.IsEscape(next): - escapedstate = 'a' - state = next - case t.IsWord(next): - token += string(next) - state = 'a' - case t.IsQuote(next): - if !l.posix { - token += string(next) - } - state = next - default: - token = string(next) - if l.whitespacesplit { - state = 'a' - } else if token != "" || (l.posix && quoted) { - break scanning - } - } - case t.IsQuote(state): - quoted = true - switch { - case next == state: - if !l.posix { - token += string(next) - break scanning - } else { - state = 'a' - } - case l.posix && t.IsEscape(next) && t.IsEscapedQuote(state): - escapedstate = state - state = next - default: - token += string(next) - } - case t.IsEscape(state): - if t.IsQuote(escapedstate) && next != state && next != escapedstate { - token += string(state) - } - token += string(next) - state = escapedstate - case t.IsWord(state): - switch { - case t.IsWhitespace(next): - if token != "" || (l.posix && quoted) { - break scanning - } - case l.posix && t.IsQuote(next): - state = next - case l.posix && t.IsEscape(next): - escapedstate = 'a' - state = next - case t.IsWord(next) || t.IsQuote(next): - token += string(next) - default: - if l.whitespacesplit { - token += string(next) - } else if token != "" { - l.reader.UnreadRune() - break scanning - } - } - } - } - return token, nil -} diff --git a/vendor/github.com/creack/pty/.gitignore b/vendor/github.com/creack/pty/.gitignore deleted file mode 100644 index 1f0a99f2..00000000 --- a/vendor/github.com/creack/pty/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -[568].out -_go* -_test* -_obj diff --git a/vendor/github.com/creack/pty/Dockerfile.riscv b/vendor/github.com/creack/pty/Dockerfile.riscv deleted file mode 100644 index 476d8f11..00000000 --- a/vendor/github.com/creack/pty/Dockerfile.riscv +++ /dev/null @@ -1,14 +0,0 @@ -FROM golang:1.12 - -# Clone and complie a riscv compatible version of the go compiler. -RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go -# riscvdev branch HEAD as of 2019-06-29. -RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf -ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH -RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash -ENV GOROOT=/riscv-go - -# Make sure we compile. -WORKDIR pty -ADD . . -RUN GOOS=linux GOARCH=riscv go build diff --git a/vendor/github.com/creack/pty/LICENSE b/vendor/github.com/creack/pty/LICENSE deleted file mode 100644 index 6b7558b6..00000000 --- a/vendor/github.com/creack/pty/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2011 Keith Rarick - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall -be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS -OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/creack/pty/README.md b/vendor/github.com/creack/pty/README.md deleted file mode 100644 index 5275014a..00000000 --- a/vendor/github.com/creack/pty/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# pty - -Pty is a Go package for using unix pseudo-terminals. - -## Install - - go get github.com/creack/pty - -## Example - -### Command - -```go -package main - -import ( - "github.com/creack/pty" - "io" - "os" - "os/exec" -) - -func main() { - c := exec.Command("grep", "--color=auto", "bar") - f, err := pty.Start(c) - if err != nil { - panic(err) - } - - go func() { - f.Write([]byte("foo\n")) - f.Write([]byte("bar\n")) - f.Write([]byte("baz\n")) - f.Write([]byte{4}) // EOT - }() - io.Copy(os.Stdout, f) -} -``` - -### Shell - -```go -package main - -import ( - "io" - "log" - "os" - "os/exec" - "os/signal" - "syscall" - - "github.com/creack/pty" - "golang.org/x/crypto/ssh/terminal" -) - -func test() error { - // Create arbitrary command. - c := exec.Command("bash") - - // Start the command with a pty. - ptmx, err := pty.Start(c) - if err != nil { - return err - } - // Make sure to close the pty at the end. - defer func() { _ = ptmx.Close() }() // Best effort. - - // Handle pty size. - ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGWINCH) - go func() { - for range ch { - if err := pty.InheritSize(os.Stdin, ptmx); err != nil { - log.Printf("error resizing pty: %s", err) - } - } - }() - ch <- syscall.SIGWINCH // Initial resize. - - // Set stdin in raw mode. - oldState, err := terminal.MakeRaw(int(os.Stdin.Fd())) - if err != nil { - panic(err) - } - defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort. - - // Copy stdin to the pty and the pty to stdout. - go func() { _, _ = io.Copy(ptmx, os.Stdin) }() - _, _ = io.Copy(os.Stdout, ptmx) - - return nil -} - -func main() { - if err := test(); err != nil { - log.Fatal(err) - } -} -``` diff --git a/vendor/github.com/creack/pty/doc.go b/vendor/github.com/creack/pty/doc.go deleted file mode 100644 index 190cfbea..00000000 --- a/vendor/github.com/creack/pty/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// Package pty provides functions for working with Unix terminals. -package pty - -import ( - "errors" - "os" -) - -// ErrUnsupported is returned if a function is not -// available on the current platform. -var ErrUnsupported = errors.New("unsupported") - -// Opens a pty and its corresponding tty. -func Open() (pty, tty *os.File, err error) { - return open() -} diff --git a/vendor/github.com/creack/pty/ioctl.go b/vendor/github.com/creack/pty/ioctl.go deleted file mode 100644 index c85cdcd1..00000000 --- a/vendor/github.com/creack/pty/ioctl.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !windows,!solaris - -package pty - -import "syscall" - -func ioctl(fd, cmd, ptr uintptr) error { - _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr) - if e != 0 { - return e - } - return nil -} diff --git a/vendor/github.com/creack/pty/ioctl_bsd.go b/vendor/github.com/creack/pty/ioctl_bsd.go deleted file mode 100644 index 73b12c53..00000000 --- a/vendor/github.com/creack/pty/ioctl_bsd.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build darwin dragonfly freebsd netbsd openbsd - -package pty - -// from -const ( - _IOC_VOID uintptr = 0x20000000 - _IOC_OUT uintptr = 0x40000000 - _IOC_IN uintptr = 0x80000000 - _IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN - _IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN - - _IOC_PARAM_SHIFT = 13 - _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 -) - -func _IOC_PARM_LEN(ioctl uintptr) uintptr { - return (ioctl >> 16) & _IOC_PARAM_MASK -} - -func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num -} - -func _IO(group byte, ioctl_num uintptr) uintptr { - return _IOC(_IOC_VOID, group, ioctl_num, 0) -} - -func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_OUT, group, ioctl_num, param_len) -} - -func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_IN, group, ioctl_num, param_len) -} - -func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { - return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len) -} diff --git a/vendor/github.com/creack/pty/ioctl_solaris.go b/vendor/github.com/creack/pty/ioctl_solaris.go deleted file mode 100644 index f63985f3..00000000 --- a/vendor/github.com/creack/pty/ioctl_solaris.go +++ /dev/null @@ -1,30 +0,0 @@ -package pty - -import ( - "golang.org/x/sys/unix" - "unsafe" -) - -const ( - // see /usr/include/sys/stropts.h - I_PUSH = uintptr((int32('S')<<8 | 002)) - I_STR = uintptr((int32('S')<<8 | 010)) - I_FIND = uintptr((int32('S')<<8 | 013)) - // see /usr/include/sys/ptms.h - ISPTM = (int32('P') << 8) | 1 - UNLKPT = (int32('P') << 8) | 2 - PTSSTTY = (int32('P') << 8) | 3 - ZONEPT = (int32('P') << 8) | 4 - OWNERPT = (int32('P') << 8) | 5 -) - -type strioctl struct { - ic_cmd int32 - ic_timout int32 - ic_len int32 - ic_dp unsafe.Pointer -} - -func ioctl(fd, cmd, ptr uintptr) error { - return unix.IoctlSetInt(int(fd), uint(cmd), int(ptr)) -} diff --git a/vendor/github.com/creack/pty/mktypes.bash b/vendor/github.com/creack/pty/mktypes.bash deleted file mode 100755 index 82ee1672..00000000 --- a/vendor/github.com/creack/pty/mktypes.bash +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -GOOSARCH="${GOOS}_${GOARCH}" -case "$GOOSARCH" in -_* | *_ | _) - echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2 - exit 1 - ;; -esac - -GODEFS="go tool cgo -godefs" - -$GODEFS types.go |gofmt > ztypes_$GOARCH.go - -case $GOOS in -freebsd|dragonfly|openbsd) - $GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go - ;; -esac diff --git a/vendor/github.com/creack/pty/pty_darwin.go b/vendor/github.com/creack/pty/pty_darwin.go deleted file mode 100644 index 6344b6b0..00000000 --- a/vendor/github.com/creack/pty/pty_darwin.go +++ /dev/null @@ -1,65 +0,0 @@ -package pty - -import ( - "errors" - "os" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, nil, err - } - p := os.NewFile(uintptr(pFD), "/dev/ptmx") - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := grantpt(p); err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func ptsname(f *os.File) (string, error) { - n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME)) - - err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0]))) - if err != nil { - return "", err - } - - for i, c := range n { - if c == 0 { - return string(n[:i]), nil - } - } - return "", errors.New("TIOCPTYGNAME string not NUL-terminated") -} - -func grantpt(f *os.File) error { - return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0) -} - -func unlockpt(f *os.File) error { - return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0) -} diff --git a/vendor/github.com/creack/pty/pty_dragonfly.go b/vendor/github.com/creack/pty/pty_dragonfly.go deleted file mode 100644 index b7d1f20f..00000000 --- a/vendor/github.com/creack/pty/pty_dragonfly.go +++ /dev/null @@ -1,80 +0,0 @@ -package pty - -import ( - "errors" - "os" - "strings" - "syscall" - "unsafe" -) - -// same code as pty_darwin.go -func open() (pty, tty *os.File, err error) { - p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := grantpt(p); err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func grantpt(f *os.File) error { - _, err := isptmaster(f.Fd()) - return err -} - -func unlockpt(f *os.File) error { - _, err := isptmaster(f.Fd()) - return err -} - -func isptmaster(fd uintptr) (bool, error) { - err := ioctl(fd, syscall.TIOCISPTMASTER, 0) - return err == nil, err -} - -var ( - emptyFiodgnameArg fiodgnameArg - ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) -) - -func ptsname(f *os.File) (string, error) { - name := make([]byte, _C_SPECNAMELEN) - fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}} - - err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa))) - if err != nil { - return "", err - } - - for i, c := range name { - if c == 0 { - s := "/dev/" + string(name[:i]) - return strings.Replace(s, "ptm", "pts", -1), nil - } - } - return "", errors.New("TIOCPTYGNAME string not NUL-terminated") -} diff --git a/vendor/github.com/creack/pty/pty_freebsd.go b/vendor/github.com/creack/pty/pty_freebsd.go deleted file mode 100644 index 63b6d913..00000000 --- a/vendor/github.com/creack/pty/pty_freebsd.go +++ /dev/null @@ -1,78 +0,0 @@ -package pty - -import ( - "errors" - "os" - "syscall" - "unsafe" -) - -func posixOpenpt(oflag int) (fd int, err error) { - r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0) - fd = int(r0) - if e1 != 0 { - err = e1 - } - return fd, err -} - -func open() (pty, tty *os.File, err error) { - fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC) - if err != nil { - return nil, nil, err - } - p := os.NewFile(uintptr(fd), "/dev/pts") - // In case of error after this point, make sure we close the pts fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func isptmaster(fd uintptr) (bool, error) { - err := ioctl(fd, syscall.TIOCPTMASTER, 0) - return err == nil, err -} - -var ( - emptyFiodgnameArg fiodgnameArg - ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) -) - -func ptsname(f *os.File) (string, error) { - master, err := isptmaster(f.Fd()) - if err != nil { - return "", err - } - if !master { - return "", syscall.EINVAL - } - - const n = _C_SPECNAMELEN + 1 - var ( - buf = make([]byte, n) - arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))} - ) - if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil { - return "", err - } - - for i, c := range buf { - if c == 0 { - return string(buf[:i]), nil - } - } - return "", errors.New("FIODGNAME string not NUL-terminated") -} diff --git a/vendor/github.com/creack/pty/pty_linux.go b/vendor/github.com/creack/pty/pty_linux.go deleted file mode 100644 index 4a833de1..00000000 --- a/vendor/github.com/creack/pty/pty_linux.go +++ /dev/null @@ -1,51 +0,0 @@ -package pty - -import ( - "os" - "strconv" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) - if err != nil { - return nil, nil, err - } - // In case of error after this point, make sure we close the ptmx fd. - defer func() { - if err != nil { - _ = p.Close() // Best effort. - } - }() - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - if err := unlockpt(p); err != nil { - return nil, nil, err - } - - t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) - if err != nil { - return nil, nil, err - } - return p, t, nil -} - -func ptsname(f *os.File) (string, error) { - var n _C_uint - err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) - if err != nil { - return "", err - } - return "/dev/pts/" + strconv.Itoa(int(n)), nil -} - -func unlockpt(f *os.File) error { - var u _C_int - // use TIOCSPTLCK with a pointer to zero to clear the lock - return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) -} diff --git a/vendor/github.com/creack/pty/pty_openbsd.go b/vendor/github.com/creack/pty/pty_openbsd.go deleted file mode 100644 index a6a35d1e..00000000 --- a/vendor/github.com/creack/pty/pty_openbsd.go +++ /dev/null @@ -1,33 +0,0 @@ -package pty - -import ( - "os" - "syscall" - "unsafe" -) - -func open() (pty, tty *os.File, err error) { - /* - * from ptm(4): - * The PTMGET command allocates a free pseudo terminal, changes its - * ownership to the caller, revokes the access privileges for all previous - * users, opens the file descriptors for the pty and tty devices and - * returns them to the caller in struct ptmget. - */ - - p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, nil, err - } - defer p.Close() - - var ptm ptmget - if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil { - return nil, nil, err - } - - pty = os.NewFile(uintptr(ptm.Cfd), "/dev/ptm") - tty = os.NewFile(uintptr(ptm.Sfd), "/dev/ptm") - - return pty, tty, nil -} diff --git a/vendor/github.com/creack/pty/pty_solaris.go b/vendor/github.com/creack/pty/pty_solaris.go deleted file mode 100644 index 09ec1b79..00000000 --- a/vendor/github.com/creack/pty/pty_solaris.go +++ /dev/null @@ -1,139 +0,0 @@ -package pty - -/* based on: -http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/pt.c -*/ - -import ( - "errors" - "golang.org/x/sys/unix" - "os" - "strconv" - "syscall" - "unsafe" -) - -const NODEV = ^uint64(0) - -func open() (pty, tty *os.File, err error) { - masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|unix.O_NOCTTY, 0) - //masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC|unix.O_NOCTTY, 0) - if err != nil { - return nil, nil, err - } - p := os.NewFile(uintptr(masterfd), "/dev/ptmx") - - sname, err := ptsname(p) - if err != nil { - return nil, nil, err - } - - err = grantpt(p) - if err != nil { - return nil, nil, err - } - - err = unlockpt(p) - if err != nil { - return nil, nil, err - } - - slavefd, err := syscall.Open(sname, os.O_RDWR|unix.O_NOCTTY, 0) - if err != nil { - return nil, nil, err - } - t := os.NewFile(uintptr(slavefd), sname) - - // pushing terminal driver STREAMS modules as per pts(7) - for _, mod := range([]string{"ptem", "ldterm", "ttcompat"}) { - err = streams_push(t, mod) - if err != nil { - return nil, nil, err - } - } - - return p, t, nil -} - -func minor(x uint64) uint64 { - return x & 0377 -} - -func ptsdev(fd uintptr) uint64 { - istr := strioctl{ISPTM, 0, 0, nil} - err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr))) - if err != nil { - return NODEV - } - var status unix.Stat_t - err = unix.Fstat(int(fd), &status) - if err != nil { - return NODEV - } - return uint64(minor(status.Rdev)) -} - -func ptsname(f *os.File) (string, error) { - dev := ptsdev(f.Fd()) - if dev == NODEV { - return "", errors.New("not a master pty") - } - fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10) - // access(2) creates the slave device (if the pty exists) - // F_OK == 0 (unistd.h) - err := unix.Access(fn, 0) - if err != nil { - return "", err - } - return fn, nil -} - -type pt_own struct { - pto_ruid int32 - pto_rgid int32 -} - -func grantpt(f *os.File) error { - if ptsdev(f.Fd()) == NODEV { - return errors.New("not a master pty") - } - var pto pt_own - pto.pto_ruid = int32(os.Getuid()) - // XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty" - pto.pto_rgid = int32(os.Getgid()) - var istr strioctl - istr.ic_cmd = OWNERPT - istr.ic_timout = 0 - istr.ic_len = int32(unsafe.Sizeof(istr)) - istr.ic_dp = unsafe.Pointer(&pto) - err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) - if err != nil { - return errors.New("access denied") - } - return nil -} - -func unlockpt(f *os.File) error { - istr := strioctl{UNLKPT, 0, 0, nil} - return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) -} - -// push STREAMS modules if not already done so -func streams_push(f *os.File, mod string) error { - var err error - buf := []byte(mod) - // XXX I_FIND is not returning an error when the module - // is already pushed even though truss reports a return - // value of 1. A bug in the Go Solaris syscall interface? - // XXX without this we are at risk of the issue - // https://www.illumos.org/issues/9042 - // but since we are not using libc or XPG4.2, we should not be - // double-pushing modules - - err = ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0]))) - if err != nil { - return nil - } - err = ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0]))) - return err -} diff --git a/vendor/github.com/creack/pty/pty_unsupported.go b/vendor/github.com/creack/pty/pty_unsupported.go deleted file mode 100644 index ceb425b1..00000000 --- a/vendor/github.com/creack/pty/pty_unsupported.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux,!darwin,!freebsd,!dragonfly,!openbsd,!solaris - -package pty - -import ( - "os" -) - -func open() (pty, tty *os.File, err error) { - return nil, nil, ErrUnsupported -} diff --git a/vendor/github.com/creack/pty/run.go b/vendor/github.com/creack/pty/run.go deleted file mode 100644 index 959be26b..00000000 --- a/vendor/github.com/creack/pty/run.go +++ /dev/null @@ -1,57 +0,0 @@ -// +build !windows - -package pty - -import ( - "os" - "os/exec" - "syscall" -) - -// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, -// and c.Stderr, calls c.Start, and returns the File of the tty's -// corresponding pty. -func Start(c *exec.Cmd) (pty *os.File, err error) { - return StartWithSize(c, nil) -} - -// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, -// and c.Stderr, calls c.Start, and returns the File of the tty's -// corresponding pty. -// -// This will resize the pty to the specified size before starting the command -func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) { - pty, tty, err := Open() - if err != nil { - return nil, err - } - defer tty.Close() - if sz != nil { - err = Setsize(pty, sz) - if err != nil { - pty.Close() - return nil, err - } - } - if c.Stdout == nil { - c.Stdout = tty - } - if c.Stderr == nil { - c.Stderr = tty - } - if c.Stdin == nil { - c.Stdin = tty - } - if c.SysProcAttr == nil { - c.SysProcAttr = &syscall.SysProcAttr{} - } - c.SysProcAttr.Setctty = true - c.SysProcAttr.Setsid = true - c.SysProcAttr.Ctty = int(tty.Fd()) - err = c.Start() - if err != nil { - pty.Close() - return nil, err - } - return pty, err -} diff --git a/vendor/github.com/creack/pty/test_crosscompile.sh b/vendor/github.com/creack/pty/test_crosscompile.sh deleted file mode 100755 index f0b1dcac..00000000 --- a/vendor/github.com/creack/pty/test_crosscompile.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env sh - -# Test script checking that all expected os/arch compile properly. -# Does not actually test the logic, just the compilation so we make sure we don't break code depending on the lib. - -echo2() { - echo $@ >&2 -} - -trap end 0 -end() { - [ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1) -} - -cross() { - os=$1 - shift - echo2 "Build for $os." - for arch in $@; do - echo2 " - $os/$arch" - GOOS=$os GOARCH=$arch go build - done - echo2 -} - -set -e - -cross linux amd64 386 arm arm64 ppc64 ppc64le s390x mips mipsle mips64 mips64le -cross darwin amd64 386 arm arm64 -cross freebsd amd64 386 arm -cross netbsd amd64 386 arm -cross openbsd amd64 386 -cross dragonfly amd64 -cross solaris amd64 - -# Not expected to work but should still compile. -cross windows amd64 386 arm - -# TODO: Fix compilation error on openbsd/arm. -# TODO: Merge the solaris PR. - -# Some os/arch require a different compiler. Run in docker. -if ! hash docker; then - # If docker is not present, stop here. - return -fi - -echo2 "Build for linux." -echo2 " - linux/riscv" -docker build -t test -f Dockerfile.riscv . diff --git a/vendor/github.com/creack/pty/types.go b/vendor/github.com/creack/pty/types.go deleted file mode 100644 index 5aecb6bc..00000000 --- a/vendor/github.com/creack/pty/types.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build ignore - -package pty - -import "C" - -type ( - _C_int C.int - _C_uint C.uint -) diff --git a/vendor/github.com/creack/pty/types_dragonfly.go b/vendor/github.com/creack/pty/types_dragonfly.go deleted file mode 100644 index 5c0493b8..00000000 --- a/vendor/github.com/creack/pty/types_dragonfly.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build ignore - -package pty - -/* -#define _KERNEL -#include -#include -#include -*/ -import "C" - -const ( - _C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */ -) - -type fiodgnameArg C.struct_fiodname_args diff --git a/vendor/github.com/creack/pty/types_freebsd.go b/vendor/github.com/creack/pty/types_freebsd.go deleted file mode 100644 index ce3eb951..00000000 --- a/vendor/github.com/creack/pty/types_freebsd.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build ignore - -package pty - -/* -#include -#include -*/ -import "C" - -const ( - _C_SPECNAMELEN = C.SPECNAMELEN /* max length of devicename */ -) - -type fiodgnameArg C.struct_fiodgname_arg diff --git a/vendor/github.com/creack/pty/types_openbsd.go b/vendor/github.com/creack/pty/types_openbsd.go deleted file mode 100644 index 47701b5f..00000000 --- a/vendor/github.com/creack/pty/types_openbsd.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build ignore - -package pty - -/* -#include -#include -#include -*/ -import "C" - -type ptmget C.struct_ptmget - -var ioctl_PTMGET = C.PTMGET diff --git a/vendor/github.com/creack/pty/util.go b/vendor/github.com/creack/pty/util.go deleted file mode 100644 index 8fdde0ba..00000000 --- a/vendor/github.com/creack/pty/util.go +++ /dev/null @@ -1,64 +0,0 @@ -// +build !windows,!solaris - -package pty - -import ( - "os" - "syscall" - "unsafe" -) - -// InheritSize applies the terminal size of pty to tty. This should be run -// in a signal handler for syscall.SIGWINCH to automatically resize the tty when -// the pty receives a window size change notification. -func InheritSize(pty, tty *os.File) error { - size, err := GetsizeFull(pty) - if err != nil { - return err - } - err = Setsize(tty, size) - if err != nil { - return err - } - return nil -} - -// Setsize resizes t to s. -func Setsize(t *os.File, ws *Winsize) error { - return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ) -} - -// GetsizeFull returns the full terminal size description. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - var ws Winsize - err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ) - return &ws, err -} - -// Getsize returns the number of rows (lines) and cols (positions -// in each line) in terminal t. -func Getsize(t *os.File) (rows, cols int, err error) { - ws, err := GetsizeFull(t) - return int(ws.Rows), int(ws.Cols), err -} - -// Winsize describes the terminal size. -type Winsize struct { - Rows uint16 // ws_row: Number of rows (in cells) - Cols uint16 // ws_col: Number of columns (in cells) - X uint16 // ws_xpixel: Width in pixels - Y uint16 // ws_ypixel: Height in pixels -} - -func windowRectCall(ws *Winsize, fd, a2 uintptr) error { - _, _, errno := syscall.Syscall( - syscall.SYS_IOCTL, - fd, - a2, - uintptr(unsafe.Pointer(ws)), - ) - if errno != 0 { - return syscall.Errno(errno) - } - return nil -} diff --git a/vendor/github.com/creack/pty/util_solaris.go b/vendor/github.com/creack/pty/util_solaris.go deleted file mode 100644 index e8896924..00000000 --- a/vendor/github.com/creack/pty/util_solaris.go +++ /dev/null @@ -1,51 +0,0 @@ -// - -package pty - -import ( - "os" - "golang.org/x/sys/unix" -) - -const ( - TIOCGWINSZ = 21608 // 'T' << 8 | 104 - TIOCSWINSZ = 21607 // 'T' << 8 | 103 -) - -// Winsize describes the terminal size. -type Winsize struct { - Rows uint16 // ws_row: Number of rows (in cells) - Cols uint16 // ws_col: Number of columns (in cells) - X uint16 // ws_xpixel: Width in pixels - Y uint16 // ws_ypixel: Height in pixels -} - -// GetsizeFull returns the full terminal size description. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - var wsz *unix.Winsize - wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ) - - if err != nil { - return nil, err - } else { - return &Winsize{wsz.Row, wsz.Col, wsz.Xpixel, wsz.Ypixel}, nil - } -} - -// Get Windows Size -func Getsize(t *os.File) (rows, cols int, err error) { - var wsz *unix.Winsize - wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ) - - if err != nil { - return 80, 25, err - } else { - return int(wsz.Row), int(wsz.Col), nil - } -} - -// Setsize resizes t to s. -func Setsize(t *os.File, ws *Winsize) error { - wsz := unix.Winsize{ws.Rows, ws.Cols, ws.X, ws.Y} - return unix.IoctlSetWinsize(int(t.Fd()), TIOCSWINSZ, &wsz) -} diff --git a/vendor/github.com/creack/pty/ztypes_386.go b/vendor/github.com/creack/pty/ztypes_386.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/creack/pty/ztypes_386.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_amd64.go b/vendor/github.com/creack/pty/ztypes_amd64.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/creack/pty/ztypes_amd64.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_arm.go b/vendor/github.com/creack/pty/ztypes_arm.go deleted file mode 100644 index ff0b8fd8..00000000 --- a/vendor/github.com/creack/pty/ztypes_arm.go +++ /dev/null @@ -1,9 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_arm64.go b/vendor/github.com/creack/pty/ztypes_arm64.go deleted file mode 100644 index 6c29a4b9..00000000 --- a/vendor/github.com/creack/pty/ztypes_arm64.go +++ /dev/null @@ -1,11 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -// +build arm64 - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go deleted file mode 100644 index 6b0ba037..00000000 --- a/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go +++ /dev/null @@ -1,14 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_dragonfly.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Name *byte - Len uint32 - Pad_cgo_0 [4]byte -} diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_386.go b/vendor/github.com/creack/pty/ztypes_freebsd_386.go deleted file mode 100644 index d9975374..00000000 --- a/vendor/github.com/creack/pty/ztypes_freebsd_386.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Buf *byte -} diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go deleted file mode 100644 index 5fa102fc..00000000 --- a/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go +++ /dev/null @@ -1,14 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Pad_cgo_0 [4]byte - Buf *byte -} diff --git a/vendor/github.com/creack/pty/ztypes_freebsd_arm.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go deleted file mode 100644 index d9975374..00000000 --- a/vendor/github.com/creack/pty/ztypes_freebsd_arm.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package pty - -const ( - _C_SPECNAMELEN = 0x3f -) - -type fiodgnameArg struct { - Len int32 - Buf *byte -} diff --git a/vendor/github.com/creack/pty/ztypes_mipsx.go b/vendor/github.com/creack/pty/ztypes_mipsx.go deleted file mode 100644 index f0ce7408..00000000 --- a/vendor/github.com/creack/pty/ztypes_mipsx.go +++ /dev/null @@ -1,12 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -// +build linux -// +build mips mipsle mips64 mips64le - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_openbsd_386.go b/vendor/github.com/creack/pty/ztypes_openbsd_386.go deleted file mode 100644 index ccb3aab9..00000000 --- a/vendor/github.com/creack/pty/ztypes_openbsd_386.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package pty - -type ptmget struct { - Cfd int32 - Sfd int32 - Cn [16]int8 - Sn [16]int8 -} - -var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/creack/pty/ztypes_openbsd_amd64.go b/vendor/github.com/creack/pty/ztypes_openbsd_amd64.go deleted file mode 100644 index e6705168..00000000 --- a/vendor/github.com/creack/pty/ztypes_openbsd_amd64.go +++ /dev/null @@ -1,13 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package pty - -type ptmget struct { - Cfd int32 - Sfd int32 - Cn [16]int8 - Sn [16]int8 -} - -var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/creack/pty/ztypes_ppc64.go b/vendor/github.com/creack/pty/ztypes_ppc64.go deleted file mode 100644 index 4e1af843..00000000 --- a/vendor/github.com/creack/pty/ztypes_ppc64.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build ppc64 - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_ppc64le.go b/vendor/github.com/creack/pty/ztypes_ppc64le.go deleted file mode 100644 index e6780f4e..00000000 --- a/vendor/github.com/creack/pty/ztypes_ppc64le.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build ppc64le - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_riscvx.go b/vendor/github.com/creack/pty/ztypes_riscvx.go deleted file mode 100644 index 99eec8ec..00000000 --- a/vendor/github.com/creack/pty/ztypes_riscvx.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types.go - -// +build riscv riscv64 - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/creack/pty/ztypes_s390x.go b/vendor/github.com/creack/pty/ztypes_s390x.go deleted file mode 100644 index a7452b61..00000000 --- a/vendor/github.com/creack/pty/ztypes_s390x.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build s390x - -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types.go - -package pty - -type ( - _C_int int32 - _C_uint uint32 -) diff --git a/vendor/github.com/gliderlabs/ssh/LICENSE b/vendor/github.com/gliderlabs/ssh/LICENSE deleted file mode 100644 index 4a03f02a..00000000 --- a/vendor/github.com/gliderlabs/ssh/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2016 Glider Labs. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Glider Labs nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gliderlabs/ssh/README.md b/vendor/github.com/gliderlabs/ssh/README.md deleted file mode 100644 index 0e976e34..00000000 --- a/vendor/github.com/gliderlabs/ssh/README.md +++ /dev/null @@ -1,96 +0,0 @@ -# gliderlabs/ssh - -[![GoDoc](https://godoc.org/github.com/gliderlabs/ssh?status.svg)](https://godoc.org/github.com/gliderlabs/ssh) -[![CircleCI](https://img.shields.io/circleci/project/github/gliderlabs/ssh.svg)](https://circleci.com/gh/gliderlabs/ssh) -[![Go Report Card](https://goreportcard.com/badge/github.com/gliderlabs/ssh)](https://goreportcard.com/report/github.com/gliderlabs/ssh) -[![OpenCollective](https://opencollective.com/ssh/sponsors/badge.svg)](#sponsors) -[![Slack](http://slack.gliderlabs.com/badge.svg)](http://slack.gliderlabs.com) -[![Email Updates](https://img.shields.io/badge/updates-subscribe-yellow.svg)](https://app.convertkit.com/landing_pages/243312) - -> The Glider Labs SSH server package is dope. —[@bradfitz](https://twitter.com/bradfitz), Go team member - -This Go package wraps the [crypto/ssh -package](https://godoc.org/golang.org/x/crypto/ssh) with a higher-level API for -building SSH servers. The goal of the API was to make it as simple as using -[net/http](https://golang.org/pkg/net/http/), so the API is very similar: - -```go - package main - - import ( - "github.com/gliderlabs/ssh" - "io" - "log" - ) - - func main() { - ssh.Handle(func(s ssh.Session) { - io.WriteString(s, "Hello world\n") - }) - - log.Fatal(ssh.ListenAndServe(":2222", nil)) - } - -``` -This package was built by [@progrium](https://twitter.com/progrium) after working on nearly a dozen projects at Glider Labs using SSH and collaborating with [@shazow](https://twitter.com/shazow) (known for [ssh-chat](https://github.com/shazow/ssh-chat)). - -## Examples - -A bunch of great examples are in the `_examples` directory. - -## Usage - -[See GoDoc reference.](https://godoc.org/github.com/gliderlabs/ssh) - -## Contributing - -Pull requests are welcome! However, since this project is very much about API -design, please submit API changes as issues to discuss before submitting PRs. - -Also, you can [join our Slack](http://slack.gliderlabs.com) to discuss as well. - -## Roadmap - -* Non-session channel handlers -* Cleanup callback API -* 1.0 release -* High-level client? - -## Sponsors - -Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/ssh#sponsor)] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## License - -BSD diff --git a/vendor/github.com/gliderlabs/ssh/agent.go b/vendor/github.com/gliderlabs/ssh/agent.go deleted file mode 100644 index d8dcb9a0..00000000 --- a/vendor/github.com/gliderlabs/ssh/agent.go +++ /dev/null @@ -1,83 +0,0 @@ -package ssh - -import ( - "io" - "io/ioutil" - "net" - "path" - "sync" - - gossh "golang.org/x/crypto/ssh" -) - -const ( - agentRequestType = "auth-agent-req@openssh.com" - agentChannelType = "auth-agent@openssh.com" - - agentTempDir = "auth-agent" - agentListenFile = "listener.sock" -) - -// contextKeyAgentRequest is an internal context key for storing if the -// client requested agent forwarding -var contextKeyAgentRequest = &contextKey{"auth-agent-req"} - -// SetAgentRequested sets up the session context so that AgentRequested -// returns true. -func SetAgentRequested(ctx Context) { - ctx.SetValue(contextKeyAgentRequest, true) -} - -// AgentRequested returns true if the client requested agent forwarding. -func AgentRequested(sess Session) bool { - return sess.Context().Value(contextKeyAgentRequest) == true -} - -// NewAgentListener sets up a temporary Unix socket that can be communicated -// to the session environment and used for forwarding connections. -func NewAgentListener() (net.Listener, error) { - dir, err := ioutil.TempDir("", agentTempDir) - if err != nil { - return nil, err - } - l, err := net.Listen("unix", path.Join(dir, agentListenFile)) - if err != nil { - return nil, err - } - return l, nil -} - -// ForwardAgentConnections takes connections from a listener to proxy into the -// session on the OpenSSH channel for agent connections. It blocks and services -// connections until the listener stop accepting. -func ForwardAgentConnections(l net.Listener, s Session) { - sshConn := s.Context().Value(ContextKeyConn).(gossh.Conn) - for { - conn, err := l.Accept() - if err != nil { - return - } - go func(conn net.Conn) { - defer conn.Close() - channel, reqs, err := sshConn.OpenChannel(agentChannelType, nil) - if err != nil { - return - } - defer channel.Close() - go gossh.DiscardRequests(reqs) - var wg sync.WaitGroup - wg.Add(2) - go func() { - io.Copy(conn, channel) - conn.(*net.UnixConn).CloseWrite() - wg.Done() - }() - go func() { - io.Copy(channel, conn) - channel.CloseWrite() - wg.Done() - }() - wg.Wait() - }(conn) - } -} diff --git a/vendor/github.com/gliderlabs/ssh/circle.yml b/vendor/github.com/gliderlabs/ssh/circle.yml deleted file mode 100644 index 08616b01..00000000 --- a/vendor/github.com/gliderlabs/ssh/circle.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: 2 -jobs: - build-go-latest: - docker: - - image: golang:latest - working_directory: /go/src/github.com/gliderlabs/ssh - steps: - - checkout - - run: go get - - run: go test -v -race - - build-go-1.9: - docker: - - image: golang:1.9 - working_directory: /go/src/github.com/gliderlabs/ssh - steps: - - checkout - - run: go get - - run: go test -v -race - -workflows: - version: 2 - build: - jobs: - - build-go-latest - - build-go-1.9 diff --git a/vendor/github.com/gliderlabs/ssh/conn.go b/vendor/github.com/gliderlabs/ssh/conn.go deleted file mode 100644 index ebef8845..00000000 --- a/vendor/github.com/gliderlabs/ssh/conn.go +++ /dev/null @@ -1,55 +0,0 @@ -package ssh - -import ( - "context" - "net" - "time" -) - -type serverConn struct { - net.Conn - - idleTimeout time.Duration - maxDeadline time.Time - closeCanceler context.CancelFunc -} - -func (c *serverConn) Write(p []byte) (n int, err error) { - c.updateDeadline() - n, err = c.Conn.Write(p) - if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil { - c.closeCanceler() - } - return -} - -func (c *serverConn) Read(b []byte) (n int, err error) { - c.updateDeadline() - n, err = c.Conn.Read(b) - if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil { - c.closeCanceler() - } - return -} - -func (c *serverConn) Close() (err error) { - err = c.Conn.Close() - if c.closeCanceler != nil { - c.closeCanceler() - } - return -} - -func (c *serverConn) updateDeadline() { - switch { - case c.idleTimeout > 0: - idleDeadline := time.Now().Add(c.idleTimeout) - if idleDeadline.Unix() < c.maxDeadline.Unix() || c.maxDeadline.IsZero() { - c.Conn.SetDeadline(idleDeadline) - return - } - fallthrough - default: - c.Conn.SetDeadline(c.maxDeadline) - } -} diff --git a/vendor/github.com/gliderlabs/ssh/context.go b/vendor/github.com/gliderlabs/ssh/context.go deleted file mode 100644 index 2f61a40d..00000000 --- a/vendor/github.com/gliderlabs/ssh/context.go +++ /dev/null @@ -1,152 +0,0 @@ -package ssh - -import ( - "context" - "encoding/hex" - "net" - "sync" - - gossh "golang.org/x/crypto/ssh" -) - -// contextKey is a value for use with context.WithValue. It's used as -// a pointer so it fits in an interface{} without allocation. -type contextKey struct { - name string -} - -var ( - // ContextKeyUser is a context key for use with Contexts in this package. - // The associated value will be of type string. - ContextKeyUser = &contextKey{"user"} - - // ContextKeySessionID is a context key for use with Contexts in this package. - // The associated value will be of type string. - ContextKeySessionID = &contextKey{"session-id"} - - // ContextKeyPermissions is a context key for use with Contexts in this package. - // The associated value will be of type *Permissions. - ContextKeyPermissions = &contextKey{"permissions"} - - // ContextKeyClientVersion is a context key for use with Contexts in this package. - // The associated value will be of type string. - ContextKeyClientVersion = &contextKey{"client-version"} - - // ContextKeyServerVersion is a context key for use with Contexts in this package. - // The associated value will be of type string. - ContextKeyServerVersion = &contextKey{"server-version"} - - // ContextKeyLocalAddr is a context key for use with Contexts in this package. - // The associated value will be of type net.Addr. - ContextKeyLocalAddr = &contextKey{"local-addr"} - - // ContextKeyRemoteAddr is a context key for use with Contexts in this package. - // The associated value will be of type net.Addr. - ContextKeyRemoteAddr = &contextKey{"remote-addr"} - - // ContextKeyServer is a context key for use with Contexts in this package. - // The associated value will be of type *Server. - ContextKeyServer = &contextKey{"ssh-server"} - - // ContextKeyConn is a context key for use with Contexts in this package. - // The associated value will be of type gossh.ServerConn. - ContextKeyConn = &contextKey{"ssh-conn"} - - // ContextKeyPublicKey is a context key for use with Contexts in this package. - // The associated value will be of type PublicKey. - ContextKeyPublicKey = &contextKey{"public-key"} -) - -// Context is a package specific context interface. It exposes connection -// metadata and allows new values to be easily written to it. It's used in -// authentication handlers and callbacks, and its underlying context.Context is -// exposed on Session in the session Handler. A connection-scoped lock is also -// embedded in the context to make it easier to limit operations per-connection. -type Context interface { - context.Context - sync.Locker - - // User returns the username used when establishing the SSH connection. - User() string - - // SessionID returns the session hash. - SessionID() string - - // ClientVersion returns the version reported by the client. - ClientVersion() string - - // ServerVersion returns the version reported by the server. - ServerVersion() string - - // RemoteAddr returns the remote address for this connection. - RemoteAddr() net.Addr - - // LocalAddr returns the local address for this connection. - LocalAddr() net.Addr - - // Permissions returns the Permissions object used for this connection. - Permissions() *Permissions - - // SetValue allows you to easily write new values into the underlying context. - SetValue(key, value interface{}) -} - -type sshContext struct { - context.Context - *sync.Mutex -} - -func newContext(srv *Server) (*sshContext, context.CancelFunc) { - innerCtx, cancel := context.WithCancel(context.Background()) - ctx := &sshContext{innerCtx, &sync.Mutex{}} - ctx.SetValue(ContextKeyServer, srv) - perms := &Permissions{&gossh.Permissions{}} - ctx.SetValue(ContextKeyPermissions, perms) - return ctx, cancel -} - -// this is separate from newContext because we will get ConnMetadata -// at different points so it needs to be applied separately -func applyConnMetadata(ctx Context, conn gossh.ConnMetadata) { - if ctx.Value(ContextKeySessionID) != nil { - return - } - ctx.SetValue(ContextKeySessionID, hex.EncodeToString(conn.SessionID())) - ctx.SetValue(ContextKeyClientVersion, string(conn.ClientVersion())) - ctx.SetValue(ContextKeyServerVersion, string(conn.ServerVersion())) - ctx.SetValue(ContextKeyUser, conn.User()) - ctx.SetValue(ContextKeyLocalAddr, conn.LocalAddr()) - ctx.SetValue(ContextKeyRemoteAddr, conn.RemoteAddr()) -} - -func (ctx *sshContext) SetValue(key, value interface{}) { - ctx.Context = context.WithValue(ctx.Context, key, value) -} - -func (ctx *sshContext) User() string { - return ctx.Value(ContextKeyUser).(string) -} - -func (ctx *sshContext) SessionID() string { - return ctx.Value(ContextKeySessionID).(string) -} - -func (ctx *sshContext) ClientVersion() string { - return ctx.Value(ContextKeyClientVersion).(string) -} - -func (ctx *sshContext) ServerVersion() string { - return ctx.Value(ContextKeyServerVersion).(string) -} - -func (ctx *sshContext) RemoteAddr() net.Addr { - return ctx.Value(ContextKeyRemoteAddr).(net.Addr) -} - -func (ctx *sshContext) LocalAddr() net.Addr { - return ctx.Value(ContextKeyLocalAddr).(net.Addr) -} - -func (ctx *sshContext) Permissions() *Permissions { - return ctx.Value(ContextKeyPermissions).(*Permissions) -} diff --git a/vendor/github.com/gliderlabs/ssh/doc.go b/vendor/github.com/gliderlabs/ssh/doc.go deleted file mode 100644 index 5a10393c..00000000 --- a/vendor/github.com/gliderlabs/ssh/doc.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Package ssh wraps the crypto/ssh package with a higher-level API for building -SSH servers. The goal of the API was to make it as simple as using net/http, so -the API is very similar. - -You should be able to build any SSH server using only this package, which wraps -relevant types and some functions from crypto/ssh. However, you still need to -use crypto/ssh for building SSH clients. - -ListenAndServe starts an SSH server with a given address, handler, and options. The -handler is usually nil, which means to use DefaultHandler. Handle sets DefaultHandler: - - ssh.Handle(func(s ssh.Session) { - io.WriteString(s, "Hello world\n") - }) - - log.Fatal(ssh.ListenAndServe(":2222", nil)) - -If you don't specify a host key, it will generate one every time. This is convenient -except you'll have to deal with clients being confused that the host key is different. -It's a better idea to generate or point to an existing key on your system: - - log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/Users/progrium/.ssh/id_rsa"))) - -Although all options have functional option helpers, another way to control the -server's behavior is by creating a custom Server: - - s := &ssh.Server{ - Addr: ":2222", - Handler: sessionHandler, - PublicKeyHandler: authHandler, - } - s.AddHostKey(hostKeySigner) - - log.Fatal(s.ListenAndServe()) - -This package automatically handles basic SSH requests like setting environment -variables, requesting PTY, and changing window size. These requests are -processed, responded to, and any relevant state is updated. This state is then -exposed to you via the Session interface. - -The one big feature missing from the Session abstraction is signals. This was -started, but not completed. Pull Requests welcome! -*/ -package ssh diff --git a/vendor/github.com/gliderlabs/ssh/options.go b/vendor/github.com/gliderlabs/ssh/options.go deleted file mode 100644 index af748985..00000000 --- a/vendor/github.com/gliderlabs/ssh/options.go +++ /dev/null @@ -1,77 +0,0 @@ -package ssh - -import ( - "io/ioutil" - - gossh "golang.org/x/crypto/ssh" -) - -// PasswordAuth returns a functional option that sets PasswordHandler on the server. -func PasswordAuth(fn PasswordHandler) Option { - return func(srv *Server) error { - srv.PasswordHandler = fn - return nil - } -} - -// PublicKeyAuth returns a functional option that sets PublicKeyHandler on the server. -func PublicKeyAuth(fn PublicKeyHandler) Option { - return func(srv *Server) error { - srv.PublicKeyHandler = fn - return nil - } -} - -// HostKeyFile returns a functional option that adds HostSigners to the server -// from a PEM file at filepath. -func HostKeyFile(filepath string) Option { - return func(srv *Server) error { - pemBytes, err := ioutil.ReadFile(filepath) - if err != nil { - return err - } - - signer, err := gossh.ParsePrivateKey(pemBytes) - if err != nil { - return err - } - - srv.AddHostKey(signer) - - return nil - } -} - -// HostKeyPEM returns a functional option that adds HostSigners to the server -// from a PEM file as bytes. -func HostKeyPEM(bytes []byte) Option { - return func(srv *Server) error { - signer, err := gossh.ParsePrivateKey(bytes) - if err != nil { - return err - } - - srv.AddHostKey(signer) - - return nil - } -} - -// NoPty returns a functional option that sets PtyCallback to return false, -// denying PTY requests. -func NoPty() Option { - return func(srv *Server) error { - srv.PtyCallback = func(ctx Context, pty Pty) bool { - return false - } - return nil - } -} - -// WrapConn returns a functional option that sets ConnCallback on the server. -func WrapConn(fn ConnCallback) Option { - return func(srv *Server) error { - srv.ConnCallback = fn - return nil - } -} diff --git a/vendor/github.com/gliderlabs/ssh/server.go b/vendor/github.com/gliderlabs/ssh/server.go deleted file mode 100644 index 9ff09169..00000000 --- a/vendor/github.com/gliderlabs/ssh/server.go +++ /dev/null @@ -1,394 +0,0 @@ -package ssh - -import ( - "context" - "errors" - "fmt" - "net" - "sync" - "time" - - gossh "golang.org/x/crypto/ssh" -) - -// ErrServerClosed is returned by the Server's Serve, ListenAndServe, -// and ListenAndServeTLS methods after a call to Shutdown or Close. -var ErrServerClosed = errors.New("ssh: Server closed") - -type RequestHandler func(ctx Context, srv *Server, req *gossh.Request) (ok bool, payload []byte) - -var DefaultRequestHandlers = map[string]RequestHandler{} - -type ChannelHandler func(srv *Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx Context) - -var DefaultChannelHandlers = map[string]ChannelHandler{ - "session": DefaultSessionHandler, -} - -// Server defines parameters for running an SSH server. The zero value for -// Server is a valid configuration. When both PasswordHandler and -// PublicKeyHandler are nil, no client authentication is performed. -type Server struct { - Addr string // TCP address to listen on, ":22" if empty - Handler Handler // handler to invoke, ssh.DefaultHandler if nil - HostSigners []Signer // private keys for the host key, must have at least one - Version string // server version to be sent before the initial handshake - - KeyboardInteractiveHandler KeyboardInteractiveHandler // keyboard-interactive authentication handler - PasswordHandler PasswordHandler // password authentication handler - PublicKeyHandler PublicKeyHandler // public key authentication handler - PtyCallback PtyCallback // callback for allowing PTY sessions, allows all if nil - ConnCallback ConnCallback // optional callback for wrapping net.Conn before handling - LocalPortForwardingCallback LocalPortForwardingCallback // callback for allowing local port forwarding, denies all if nil - ReversePortForwardingCallback ReversePortForwardingCallback // callback for allowing reverse port forwarding, denies all if nil - ServerConfigCallback ServerConfigCallback // callback for configuring detailed SSH options - SessionRequestCallback SessionRequestCallback // callback for allowing or denying SSH sessions - - IdleTimeout time.Duration // connection timeout when no activity, none if empty - MaxTimeout time.Duration // absolute connection timeout, none if empty - - // ChannelHandlers allow overriding the built-in session handlers or provide - // extensions to the protocol, such as tcpip forwarding. By default only the - // "session" handler is enabled. - ChannelHandlers map[string]ChannelHandler - - // RequestHandlers allow overriding the server-level request handlers or - // provide extensions to the protocol, such as tcpip forwarding. By default - // no handlers are enabled. - RequestHandlers map[string]RequestHandler - - listenerWg sync.WaitGroup - mu sync.Mutex - listeners map[net.Listener]struct{} - conns map[*gossh.ServerConn]struct{} - connWg sync.WaitGroup - doneChan chan struct{} -} - -func (srv *Server) ensureHostSigner() error { - if len(srv.HostSigners) == 0 { - signer, err := generateSigner() - if err != nil { - return err - } - srv.HostSigners = append(srv.HostSigners, signer) - } - return nil -} - -func (srv *Server) ensureHandlers() { - srv.mu.Lock() - defer srv.mu.Unlock() - if srv.RequestHandlers == nil { - srv.RequestHandlers = map[string]RequestHandler{} - for k, v := range DefaultRequestHandlers { - srv.RequestHandlers[k] = v - } - } - if srv.ChannelHandlers == nil { - srv.ChannelHandlers = map[string]ChannelHandler{} - for k, v := range DefaultChannelHandlers { - srv.ChannelHandlers[k] = v - } - } -} - -func (srv *Server) config(ctx Context) *gossh.ServerConfig { - var config *gossh.ServerConfig - if srv.ServerConfigCallback == nil { - config = &gossh.ServerConfig{} - } else { - config = srv.ServerConfigCallback(ctx) - } - for _, signer := range srv.HostSigners { - config.AddHostKey(signer) - } - if srv.PasswordHandler == nil && srv.PublicKeyHandler == nil { - config.NoClientAuth = true - } - if srv.Version != "" { - config.ServerVersion = "SSH-2.0-" + srv.Version - } - if srv.PasswordHandler != nil { - config.PasswordCallback = func(conn gossh.ConnMetadata, password []byte) (*gossh.Permissions, error) { - applyConnMetadata(ctx, conn) - if ok := srv.PasswordHandler(ctx, string(password)); !ok { - return ctx.Permissions().Permissions, fmt.Errorf("permission denied") - } - return ctx.Permissions().Permissions, nil - } - } - if srv.PublicKeyHandler != nil { - config.PublicKeyCallback = func(conn gossh.ConnMetadata, key gossh.PublicKey) (*gossh.Permissions, error) { - applyConnMetadata(ctx, conn) - if ok := srv.PublicKeyHandler(ctx, key); !ok { - return ctx.Permissions().Permissions, fmt.Errorf("permission denied") - } - ctx.SetValue(ContextKeyPublicKey, key) - return ctx.Permissions().Permissions, nil - } - } - if srv.KeyboardInteractiveHandler != nil { - config.KeyboardInteractiveCallback = func(conn gossh.ConnMetadata, challenger gossh.KeyboardInteractiveChallenge) (*gossh.Permissions, error) { - if ok := srv.KeyboardInteractiveHandler(ctx, challenger); !ok { - return ctx.Permissions().Permissions, fmt.Errorf("permission denied") - } - return ctx.Permissions().Permissions, nil - } - } - return config -} - -// Handle sets the Handler for the server. -func (srv *Server) Handle(fn Handler) { - srv.Handler = fn -} - -// Close immediately closes all active listeners and all active -// connections. -// -// Close returns any error returned from closing the Server's -// underlying Listener(s). -func (srv *Server) Close() error { - srv.mu.Lock() - defer srv.mu.Unlock() - srv.closeDoneChanLocked() - err := srv.closeListenersLocked() - for c := range srv.conns { - c.Close() - delete(srv.conns, c) - } - return err -} - -// Shutdown gracefully shuts down the server without interrupting any -// active connections. Shutdown works by first closing all open -// listeners, and then waiting indefinitely for connections to close. -// If the provided context expires before the shutdown is complete, -// then the context's error is returned. -func (srv *Server) Shutdown(ctx context.Context) error { - srv.mu.Lock() - lnerr := srv.closeListenersLocked() - srv.closeDoneChanLocked() - srv.mu.Unlock() - - finished := make(chan struct{}, 1) - go func() { - srv.listenerWg.Wait() - srv.connWg.Wait() - finished <- struct{}{} - }() - - select { - case <-ctx.Done(): - return ctx.Err() - case <-finished: - return lnerr - } -} - -// Serve accepts incoming connections on the Listener l, creating a new -// connection goroutine for each. The connection goroutines read requests and then -// calls srv.Handler to handle sessions. -// -// Serve always returns a non-nil error. -func (srv *Server) Serve(l net.Listener) error { - srv.ensureHandlers() - defer l.Close() - if err := srv.ensureHostSigner(); err != nil { - return err - } - if srv.Handler == nil { - srv.Handler = DefaultHandler - } - var tempDelay time.Duration - - srv.trackListener(l, true) - defer srv.trackListener(l, false) - for { - conn, e := l.Accept() - if e != nil { - select { - case <-srv.getDoneChan(): - return ErrServerClosed - default: - } - if ne, ok := e.(net.Error); ok && ne.Temporary() { - if tempDelay == 0 { - tempDelay = 5 * time.Millisecond - } else { - tempDelay *= 2 - } - if max := 1 * time.Second; tempDelay > max { - tempDelay = max - } - time.Sleep(tempDelay) - continue - } - return e - } - go srv.handleConn(conn) - } -} - -func (srv *Server) handleConn(newConn net.Conn) { - if srv.ConnCallback != nil { - cbConn := srv.ConnCallback(newConn) - if cbConn == nil { - newConn.Close() - return - } - newConn = cbConn - } - ctx, cancel := newContext(srv) - conn := &serverConn{ - Conn: newConn, - idleTimeout: srv.IdleTimeout, - closeCanceler: cancel, - } - if srv.MaxTimeout > 0 { - conn.maxDeadline = time.Now().Add(srv.MaxTimeout) - } - defer conn.Close() - sshConn, chans, reqs, err := gossh.NewServerConn(conn, srv.config(ctx)) - if err != nil { - // TODO: trigger event callback - return - } - - srv.trackConn(sshConn, true) - defer srv.trackConn(sshConn, false) - - ctx.SetValue(ContextKeyConn, sshConn) - applyConnMetadata(ctx, sshConn) - //go gossh.DiscardRequests(reqs) - go srv.handleRequests(ctx, reqs) - for ch := range chans { - handler := srv.ChannelHandlers[ch.ChannelType()] - if handler == nil { - handler = srv.ChannelHandlers["default"] - } - if handler == nil { - ch.Reject(gossh.UnknownChannelType, "unsupported channel type") - continue - } - go handler(srv, sshConn, ch, ctx) - } -} - -func (srv *Server) handleRequests(ctx Context, in <-chan *gossh.Request) { - for req := range in { - handler := srv.RequestHandlers[req.Type] - if handler == nil { - handler = srv.RequestHandlers["default"] - } - if handler == nil { - req.Reply(false, nil) - continue - } - /*reqCtx, cancel := context.WithCancel(ctx) - defer cancel() */ - ret, payload := handler(ctx, srv, req) - req.Reply(ret, payload) - } -} - -// ListenAndServe listens on the TCP network address srv.Addr and then calls -// Serve to handle incoming connections. If srv.Addr is blank, ":22" is used. -// ListenAndServe always returns a non-nil error. -func (srv *Server) ListenAndServe() error { - addr := srv.Addr - if addr == "" { - addr = ":22" - } - ln, err := net.Listen("tcp", addr) - if err != nil { - return err - } - return srv.Serve(ln) -} - -// AddHostKey adds a private key as a host key. If an existing host key exists -// with the same algorithm, it is overwritten. Each server config must have at -// least one host key. -func (srv *Server) AddHostKey(key Signer) { - // these are later added via AddHostKey on ServerConfig, which performs the - // check for one of every algorithm. - srv.HostSigners = append(srv.HostSigners, key) -} - -// SetOption runs a functional option against the server. -func (srv *Server) SetOption(option Option) error { - return option(srv) -} - -func (srv *Server) getDoneChan() <-chan struct{} { - srv.mu.Lock() - defer srv.mu.Unlock() - return srv.getDoneChanLocked() -} - -func (srv *Server) getDoneChanLocked() chan struct{} { - if srv.doneChan == nil { - srv.doneChan = make(chan struct{}) - } - return srv.doneChan -} - -func (srv *Server) closeDoneChanLocked() { - ch := srv.getDoneChanLocked() - select { - case <-ch: - // Already closed. Don't close again. - default: - // Safe to close here. We're the only closer, guarded - // by srv.mu. - close(ch) - } -} - -func (srv *Server) closeListenersLocked() error { - var err error - for ln := range srv.listeners { - if cerr := ln.Close(); cerr != nil && err == nil { - err = cerr - } - delete(srv.listeners, ln) - } - return err -} - -func (srv *Server) trackListener(ln net.Listener, add bool) { - srv.mu.Lock() - defer srv.mu.Unlock() - if srv.listeners == nil { - srv.listeners = make(map[net.Listener]struct{}) - } - if add { - // If the *Server is being reused after a previous - // Close or Shutdown, reset its doneChan: - if len(srv.listeners) == 0 && len(srv.conns) == 0 { - srv.doneChan = nil - } - srv.listeners[ln] = struct{}{} - srv.listenerWg.Add(1) - } else { - delete(srv.listeners, ln) - srv.listenerWg.Done() - } -} - -func (srv *Server) trackConn(c *gossh.ServerConn, add bool) { - srv.mu.Lock() - defer srv.mu.Unlock() - if srv.conns == nil { - srv.conns = make(map[*gossh.ServerConn]struct{}) - } - if add { - srv.conns[c] = struct{}{} - srv.connWg.Add(1) - } else { - delete(srv.conns, c) - srv.connWg.Done() - } -} diff --git a/vendor/github.com/gliderlabs/ssh/session.go b/vendor/github.com/gliderlabs/ssh/session.go deleted file mode 100644 index 6c77d6c8..00000000 --- a/vendor/github.com/gliderlabs/ssh/session.go +++ /dev/null @@ -1,308 +0,0 @@ -package ssh - -import ( - "bytes" - "context" - "errors" - "fmt" - "net" - "sync" - - "github.com/anmitsu/go-shlex" - gossh "golang.org/x/crypto/ssh" -) - -// Session provides access to information about an SSH session and methods -// to read and write to the SSH channel with an embedded Channel interface from -// cypto/ssh. -// -// When Command() returns an empty slice, the user requested a shell. Otherwise -// the user is performing an exec with those command arguments. -// -// TODO: Signals -type Session interface { - gossh.Channel - - // User returns the username used when establishing the SSH connection. - User() string - - // RemoteAddr returns the net.Addr of the client side of the connection. - RemoteAddr() net.Addr - - // LocalAddr returns the net.Addr of the server side of the connection. - LocalAddr() net.Addr - - // Environ returns a copy of strings representing the environment set by the - // user for this session, in the form "key=value". - Environ() []string - - // Exit sends an exit status and then closes the session. - Exit(code int) error - - // Command returns a shell parsed slice of arguments that were provided by the - // user. Shell parsing splits the command string according to POSIX shell rules, - // which considers quoting not just whitespace. - Command() []string - - // RawCommand returns the exact command that was provided by the user. - RawCommand() string - - // PublicKey returns the PublicKey used to authenticate. If a public key was not - // used it will return nil. - PublicKey() PublicKey - - // Context returns the connection's context. The returned context is always - // non-nil and holds the same data as the Context passed into auth - // handlers and callbacks. - // - // The context is canceled when the client's connection closes or I/O - // operation fails. - Context() context.Context - - // Permissions returns a copy of the Permissions object that was available for - // setup in the auth handlers via the Context. - Permissions() Permissions - - // Pty returns PTY information, a channel of window size changes, and a boolean - // of whether or not a PTY was accepted for this session. - Pty() (Pty, <-chan Window, bool) - - // Signals registers a channel to receive signals sent from the client. The - // channel must handle signal sends or it will block the SSH request loop. - // Registering nil will unregister the channel from signal sends. During the - // time no channel is registered signals are buffered up to a reasonable amount. - // If there are buffered signals when a channel is registered, they will be - // sent in order on the channel immediately after registering. - Signals(c chan<- Signal) -} - -// maxSigBufSize is how many signals will be buffered -// when there is no signal channel specified -const maxSigBufSize = 128 - -func DefaultSessionHandler(srv *Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx Context) { - ch, reqs, err := newChan.Accept() - if err != nil { - // TODO: trigger event callback - return - } - sess := &session{ - Channel: ch, - conn: conn, - handler: srv.Handler, - ptyCb: srv.PtyCallback, - sessReqCb: srv.SessionRequestCallback, - ctx: ctx, - } - sess.handleRequests(reqs) -} - -type session struct { - sync.Mutex - gossh.Channel - conn *gossh.ServerConn - handler Handler - handled bool - exited bool - pty *Pty - winch chan Window - env []string - ptyCb PtyCallback - sessReqCb SessionRequestCallback - rawCmd string - ctx Context - sigCh chan<- Signal - sigBuf []Signal -} - -func (sess *session) Write(p []byte) (n int, err error) { - if sess.pty != nil { - m := len(p) - // normalize \n to \r\n when pty is accepted. - // this is a hardcoded shortcut since we don't support terminal modes. - p = bytes.Replace(p, []byte{'\n'}, []byte{'\r', '\n'}, -1) - p = bytes.Replace(p, []byte{'\r', '\r', '\n'}, []byte{'\r', '\n'}, -1) - n, err = sess.Channel.Write(p) - if n > m { - n = m - } - return - } - return sess.Channel.Write(p) -} - -func (sess *session) PublicKey() PublicKey { - sessionkey := sess.ctx.Value(ContextKeyPublicKey) - if sessionkey == nil { - return nil - } - return sessionkey.(PublicKey) -} - -func (sess *session) Permissions() Permissions { - // use context permissions because its properly - // wrapped and easier to dereference - perms := sess.ctx.Value(ContextKeyPermissions).(*Permissions) - return *perms -} - -func (sess *session) Context() context.Context { - return sess.ctx -} - -func (sess *session) Exit(code int) error { - sess.Lock() - defer sess.Unlock() - if sess.exited { - return errors.New("Session.Exit called multiple times") - } - sess.exited = true - - status := struct{ Status uint32 }{uint32(code)} - _, err := sess.SendRequest("exit-status", false, gossh.Marshal(&status)) - if err != nil { - return err - } - return sess.Close() -} - -func (sess *session) User() string { - return sess.conn.User() -} - -func (sess *session) RemoteAddr() net.Addr { - return sess.conn.RemoteAddr() -} - -func (sess *session) LocalAddr() net.Addr { - return sess.conn.LocalAddr() -} - -func (sess *session) Environ() []string { - return append([]string(nil), sess.env...) -} - -func (sess *session) RawCommand() string { - return sess.rawCmd -} - -func (sess *session) Command() []string { - cmd, _ := shlex.Split(sess.rawCmd, true) - return append([]string(nil), cmd...) -} - -func (sess *session) Pty() (Pty, <-chan Window, bool) { - if sess.pty != nil { - return *sess.pty, sess.winch, true - } - return Pty{}, sess.winch, false -} - -func (sess *session) Signals(c chan<- Signal) { - sess.Lock() - defer sess.Unlock() - sess.sigCh = c - if len(sess.sigBuf) > 0 { - go func() { - for _, sig := range sess.sigBuf { - sess.sigCh <- sig - } - }() - } -} - -func (sess *session) handleRequests(reqs <-chan *gossh.Request) { - for req := range reqs { - switch req.Type { - case "shell", "exec": - if sess.handled { - req.Reply(false, nil) - continue - } - - var payload = struct{ Value string }{} - gossh.Unmarshal(req.Payload, &payload) - sess.rawCmd = payload.Value - - // If there's a session policy callback, we need to confirm before - // accepting the session. - if sess.sessReqCb != nil && !sess.sessReqCb(sess, req.Type) { - sess.rawCmd = "" - req.Reply(false, nil) - continue - } - - sess.handled = true - req.Reply(true, nil) - - go func() { - sess.handler(sess) - sess.Exit(0) - }() - case "env": - if sess.handled { - req.Reply(false, nil) - continue - } - var kv struct{ Key, Value string } - gossh.Unmarshal(req.Payload, &kv) - sess.env = append(sess.env, fmt.Sprintf("%s=%s", kv.Key, kv.Value)) - req.Reply(true, nil) - case "signal": - var payload struct{ Signal string } - gossh.Unmarshal(req.Payload, &payload) - sess.Lock() - if sess.sigCh != nil { - sess.sigCh <- Signal(payload.Signal) - } else { - if len(sess.sigBuf) < maxSigBufSize { - sess.sigBuf = append(sess.sigBuf, Signal(payload.Signal)) - } - } - sess.Unlock() - case "pty-req": - if sess.handled || sess.pty != nil { - req.Reply(false, nil) - continue - } - ptyReq, ok := parsePtyRequest(req.Payload) - if !ok { - req.Reply(false, nil) - continue - } - if sess.ptyCb != nil { - ok := sess.ptyCb(sess.ctx, ptyReq) - if !ok { - req.Reply(false, nil) - continue - } - } - sess.pty = &ptyReq - sess.winch = make(chan Window, 1) - sess.winch <- ptyReq.Window - defer func() { - // when reqs is closed - close(sess.winch) - }() - req.Reply(ok, nil) - case "window-change": - if sess.pty == nil { - req.Reply(false, nil) - continue - } - win, ok := parseWinchRequest(req.Payload) - if ok { - sess.pty.Window = win - sess.winch <- win - } - req.Reply(ok, nil) - case agentRequestType: - // TODO: option/callback to allow agent forwarding - SetAgentRequested(sess.ctx) - req.Reply(true, nil) - default: - // TODO: debug log - req.Reply(false, nil) - } - } -} diff --git a/vendor/github.com/gliderlabs/ssh/ssh.go b/vendor/github.com/gliderlabs/ssh/ssh.go deleted file mode 100644 index f5a935a9..00000000 --- a/vendor/github.com/gliderlabs/ssh/ssh.go +++ /dev/null @@ -1,123 +0,0 @@ -package ssh - -import ( - "crypto/subtle" - "net" - - gossh "golang.org/x/crypto/ssh" -) - -type Signal string - -// POSIX signals as listed in RFC 4254 Section 6.10. -const ( - SIGABRT Signal = "ABRT" - SIGALRM Signal = "ALRM" - SIGFPE Signal = "FPE" - SIGHUP Signal = "HUP" - SIGILL Signal = "ILL" - SIGINT Signal = "INT" - SIGKILL Signal = "KILL" - SIGPIPE Signal = "PIPE" - SIGQUIT Signal = "QUIT" - SIGSEGV Signal = "SEGV" - SIGTERM Signal = "TERM" - SIGUSR1 Signal = "USR1" - SIGUSR2 Signal = "USR2" -) - -// DefaultHandler is the default Handler used by Serve. -var DefaultHandler Handler - -// Option is a functional option handler for Server. -type Option func(*Server) error - -// Handler is a callback for handling established SSH sessions. -type Handler func(Session) - -// PublicKeyHandler is a callback for performing public key authentication. -type PublicKeyHandler func(ctx Context, key PublicKey) bool - -// PasswordHandler is a callback for performing password authentication. -type PasswordHandler func(ctx Context, password string) bool - -// KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication. -type KeyboardInteractiveHandler func(ctx Context, challenger gossh.KeyboardInteractiveChallenge) bool - -// PtyCallback is a hook for allowing PTY sessions. -type PtyCallback func(ctx Context, pty Pty) bool - -// SessionRequestCallback is a callback for allowing or denying SSH sessions. -type SessionRequestCallback func(sess Session, requestType string) bool - -// ConnCallback is a hook for new connections before handling. -// It allows wrapping for timeouts and limiting by returning -// the net.Conn that will be used as the underlying connection. -type ConnCallback func(conn net.Conn) net.Conn - -// LocalPortForwardingCallback is a hook for allowing port forwarding -type LocalPortForwardingCallback func(ctx Context, destinationHost string, destinationPort uint32) bool - -// ReversePortForwardingCallback is a hook for allowing reverse port forwarding -type ReversePortForwardingCallback func(ctx Context, bindHost string, bindPort uint32) bool - -// ServerConfigCallback is a hook for creating custom default server configs -type ServerConfigCallback func(ctx Context) *gossh.ServerConfig - -// Window represents the size of a PTY window. -type Window struct { - Width int - Height int -} - -// Pty represents a PTY request and configuration. -type Pty struct { - Term string - Window Window - // HELP WANTED: terminal modes! -} - -// Serve accepts incoming SSH connections on the listener l, creating a new -// connection goroutine for each. The connection goroutines read requests and -// then calls handler to handle sessions. Handler is typically nil, in which -// case the DefaultHandler is used. -func Serve(l net.Listener, handler Handler, options ...Option) error { - srv := &Server{Handler: handler} - for _, option := range options { - if err := srv.SetOption(option); err != nil { - return err - } - } - return srv.Serve(l) -} - -// ListenAndServe listens on the TCP network address addr and then calls Serve -// with handler to handle sessions on incoming connections. Handler is typically -// nil, in which case the DefaultHandler is used. -func ListenAndServe(addr string, handler Handler, options ...Option) error { - srv := &Server{Addr: addr, Handler: handler} - for _, option := range options { - if err := srv.SetOption(option); err != nil { - return err - } - } - return srv.ListenAndServe() -} - -// Handle registers the handler as the DefaultHandler. -func Handle(handler Handler) { - DefaultHandler = handler -} - -// KeysEqual is constant time compare of the keys to avoid timing attacks. -func KeysEqual(ak, bk PublicKey) bool { - - //avoid panic if one of the keys is nil, return false instead - if ak == nil || bk == nil { - return false - } - - a := ak.Marshal() - b := bk.Marshal() - return (len(a) == len(b) && subtle.ConstantTimeCompare(a, b) == 1) -} diff --git a/vendor/github.com/gliderlabs/ssh/tcpip.go b/vendor/github.com/gliderlabs/ssh/tcpip.go deleted file mode 100644 index 335fda65..00000000 --- a/vendor/github.com/gliderlabs/ssh/tcpip.go +++ /dev/null @@ -1,193 +0,0 @@ -package ssh - -import ( - "io" - "log" - "net" - "strconv" - "sync" - - gossh "golang.org/x/crypto/ssh" -) - -const ( - forwardedTCPChannelType = "forwarded-tcpip" -) - -// direct-tcpip data struct as specified in RFC4254, Section 7.2 -type localForwardChannelData struct { - DestAddr string - DestPort uint32 - - OriginAddr string - OriginPort uint32 -} - -// DirectTCPIPHandler can be enabled by adding it to the server's -// ChannelHandlers under direct-tcpip. -func DirectTCPIPHandler(srv *Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx Context) { - d := localForwardChannelData{} - if err := gossh.Unmarshal(newChan.ExtraData(), &d); err != nil { - newChan.Reject(gossh.ConnectionFailed, "error parsing forward data: "+err.Error()) - return - } - - if srv.LocalPortForwardingCallback == nil || !srv.LocalPortForwardingCallback(ctx, d.DestAddr, d.DestPort) { - newChan.Reject(gossh.Prohibited, "port forwarding is disabled") - return - } - - dest := net.JoinHostPort(d.DestAddr, strconv.FormatInt(int64(d.DestPort), 10)) - - var dialer net.Dialer - dconn, err := dialer.DialContext(ctx, "tcp", dest) - if err != nil { - newChan.Reject(gossh.ConnectionFailed, err.Error()) - return - } - - ch, reqs, err := newChan.Accept() - if err != nil { - dconn.Close() - return - } - go gossh.DiscardRequests(reqs) - - go func() { - defer ch.Close() - defer dconn.Close() - io.Copy(ch, dconn) - }() - go func() { - defer ch.Close() - defer dconn.Close() - io.Copy(dconn, ch) - }() -} - -type remoteForwardRequest struct { - BindAddr string - BindPort uint32 -} - -type remoteForwardSuccess struct { - BindPort uint32 -} - -type remoteForwardCancelRequest struct { - BindAddr string - BindPort uint32 -} - -type remoteForwardChannelData struct { - DestAddr string - DestPort uint32 - OriginAddr string - OriginPort uint32 -} - -// ForwardedTCPHandler can be enabled by creating a ForwardedTCPHandler and -// adding the HandleSSHRequest callback to the server's RequestHandlers under -// tcpip-forward and cancel-tcpip-forward. -type ForwardedTCPHandler struct { - forwards map[string]net.Listener - sync.Mutex -} - -func (h *ForwardedTCPHandler) HandleSSHRequest(ctx Context, srv *Server, req *gossh.Request) (bool, []byte) { - h.Lock() - if h.forwards == nil { - h.forwards = make(map[string]net.Listener) - } - h.Unlock() - conn := ctx.Value(ContextKeyConn).(*gossh.ServerConn) - switch req.Type { - case "tcpip-forward": - var reqPayload remoteForwardRequest - if err := gossh.Unmarshal(req.Payload, &reqPayload); err != nil { - // TODO: log parse failure - return false, []byte{} - } - if srv.ReversePortForwardingCallback == nil || !srv.ReversePortForwardingCallback(ctx, reqPayload.BindAddr, reqPayload.BindPort) { - return false, []byte("port forwarding is disabled") - } - addr := net.JoinHostPort(reqPayload.BindAddr, strconv.Itoa(int(reqPayload.BindPort))) - ln, err := net.Listen("tcp", addr) - if err != nil { - // TODO: log listen failure - return false, []byte{} - } - _, destPortStr, _ := net.SplitHostPort(ln.Addr().String()) - destPort, _ := strconv.Atoi(destPortStr) - h.Lock() - h.forwards[addr] = ln - h.Unlock() - go func() { - <-ctx.Done() - h.Lock() - ln, ok := h.forwards[addr] - h.Unlock() - if ok { - ln.Close() - } - }() - go func() { - for { - c, err := ln.Accept() - if err != nil { - // TODO: log accept failure - break - } - originAddr, orignPortStr, _ := net.SplitHostPort(c.RemoteAddr().String()) - originPort, _ := strconv.Atoi(orignPortStr) - payload := gossh.Marshal(&remoteForwardChannelData{ - DestAddr: reqPayload.BindAddr, - DestPort: uint32(destPort), - OriginAddr: originAddr, - OriginPort: uint32(originPort), - }) - go func() { - ch, reqs, err := conn.OpenChannel(forwardedTCPChannelType, payload) - if err != nil { - // TODO: log failure to open channel - log.Println(err) - c.Close() - return - } - go gossh.DiscardRequests(reqs) - go func() { - defer ch.Close() - defer c.Close() - io.Copy(ch, c) - }() - go func() { - defer ch.Close() - defer c.Close() - io.Copy(c, ch) - }() - }() - } - h.Lock() - delete(h.forwards, addr) - h.Unlock() - }() - return true, gossh.Marshal(&remoteForwardSuccess{uint32(destPort)}) - - case "cancel-tcpip-forward": - var reqPayload remoteForwardCancelRequest - if err := gossh.Unmarshal(req.Payload, &reqPayload); err != nil { - // TODO: log parse failure - return false, []byte{} - } - addr := net.JoinHostPort(reqPayload.BindAddr, strconv.Itoa(int(reqPayload.BindPort))) - h.Lock() - ln, ok := h.forwards[addr] - h.Unlock() - if ok { - ln.Close() - } - return true, nil - default: - return false, nil - } -} diff --git a/vendor/github.com/gliderlabs/ssh/util.go b/vendor/github.com/gliderlabs/ssh/util.go deleted file mode 100644 index 015a44ec..00000000 --- a/vendor/github.com/gliderlabs/ssh/util.go +++ /dev/null @@ -1,83 +0,0 @@ -package ssh - -import ( - "crypto/rand" - "crypto/rsa" - "encoding/binary" - - "golang.org/x/crypto/ssh" -) - -func generateSigner() (ssh.Signer, error) { - key, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - return nil, err - } - return ssh.NewSignerFromKey(key) -} - -func parsePtyRequest(s []byte) (pty Pty, ok bool) { - term, s, ok := parseString(s) - if !ok { - return - } - width32, s, ok := parseUint32(s) - if !ok { - return - } - height32, _, ok := parseUint32(s) - if !ok { - return - } - pty = Pty{ - Term: term, - Window: Window{ - Width: int(width32), - Height: int(height32), - }, - } - return -} - -func parseWinchRequest(s []byte) (win Window, ok bool) { - width32, s, ok := parseUint32(s) - if width32 < 1 { - ok = false - } - if !ok { - return - } - height32, _, ok := parseUint32(s) - if height32 < 1 { - ok = false - } - if !ok { - return - } - win = Window{ - Width: int(width32), - Height: int(height32), - } - return -} - -func parseString(in []byte) (out string, rest []byte, ok bool) { - if len(in) < 4 { - return - } - length := binary.BigEndian.Uint32(in) - if uint32(len(in)) < 4+length { - return - } - out = string(in[4 : 4+length]) - rest = in[4+length:] - ok = true - return -} - -func parseUint32(in []byte) (uint32, []byte, bool) { - if len(in) < 4 { - return 0, nil, false - } - return binary.BigEndian.Uint32(in), in[4:], true -} diff --git a/vendor/github.com/gliderlabs/ssh/wrap.go b/vendor/github.com/gliderlabs/ssh/wrap.go deleted file mode 100644 index d1f2b161..00000000 --- a/vendor/github.com/gliderlabs/ssh/wrap.go +++ /dev/null @@ -1,33 +0,0 @@ -package ssh - -import gossh "golang.org/x/crypto/ssh" - -// PublicKey is an abstraction of different types of public keys. -type PublicKey interface { - gossh.PublicKey -} - -// The Permissions type holds fine-grained permissions that are specific to a -// user or a specific authentication method for a user. Permissions, except for -// "source-address", must be enforced in the server application layer, after -// successful authentication. -type Permissions struct { - *gossh.Permissions -} - -// A Signer can create signatures that verify against a public key. -type Signer interface { - gossh.Signer -} - -// ParseAuthorizedKey parses a public key from an authorized_keys file used in -// OpenSSH according to the sshd(8) manual page. -func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { - return gossh.ParseAuthorizedKey(in) -} - -// ParsePublicKey parses an SSH public key formatted for use in -// the SSH wire protocol according to RFC 4253, section 6.6. -func ParsePublicKey(in []byte) (out PublicKey, err error) { - return gossh.ParsePublicKey(in) -}