diff --git a/sshpiperd/cmd.go b/sshpiperd/cmd.go index 245297d1..386a32e7 100644 --- a/sshpiperd/cmd.go +++ b/sshpiperd/cmd.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "io/ioutil" + "log" "os" "github.com/gokyle/sshkey" @@ -173,7 +175,13 @@ func main() { return nil, fmt.Errorf("must provider upstream driver") } - return upstream.Get(config.UpstreamDriver).(upstream.Provider), nil + provider := upstream.Get(config.UpstreamDriver).(upstream.Provider) + err := provider.Init(log.New(ioutil.Discard, "", 0)) + if err != nil { + return nil, err + } + + return provider, nil })) addOpt(c.Group, "sshpiperd", config) diff --git a/sshpiperd/pipemgr.go b/sshpiperd/pipemgr.go index 862aa8c9..8e57fce1 100644 --- a/sshpiperd/pipemgr.go +++ b/sshpiperd/pipemgr.go @@ -21,7 +21,7 @@ func createPipeMgr(load func() (upstream.Provider, error)) interface{} { UpstreamUserName string `long:"upstream-username" description:"mapped user name" no-ini:"true"` UpstreamHost string `short:"u" long:"host" description:"upstream sshd host" required:"true" no-ini:"true"` - UpstreamPort uint `short:"p" long:"port" description:"upstream sshd port" default:"22" no-ini:"true"` + UpstreamPort int `short:"p" long:"port" description:"upstream sshd port" default:"22" no-ini:"true"` // UpstreamKeyFile flags.Filename // UpstreamHostKey diff --git a/sshpiperd/upstream/database/plugin.go b/sshpiperd/upstream/database/plugin.go index 9aef8009..94eb480e 100644 --- a/sshpiperd/upstream/database/plugin.go +++ b/sshpiperd/upstream/database/plugin.go @@ -1,6 +1,7 @@ package database import ( + "fmt" "log" "github.com/jinzhu/gorm" @@ -21,15 +22,69 @@ type plugin struct { } func (p *plugin) ListPipe() ([]upstreamprovider.Pipe, error) { - panic("implement me") + db := p.db + + downstreams := make([]downstream, 0) + err := db.Set("gorm:auto_preload", true).Find(&downstreams).Error + if err != nil { + return nil, err + } + + pipes := make([]upstreamprovider.Pipe, 0, len(downstreams)) + for _, d := range downstreams { + + host, port, err := upstreamprovider.SplitHostPortForSSH(d.Upstream.Server.Address) + + if err != nil { + continue + } + + upuser := d.Upstream.Username + + if upuser == "" { + upuser = d.Username + } + + pipes = append(pipes, upstreamprovider.Pipe{ + Host: host, + Port: port, + Username: d.Username, + UpstreamUsername: upuser, + }) + } + + return pipes, nil } func (p *plugin) CreatePipe(opt upstreamprovider.CreatePipeOption) error { - panic("implement me") + db := p.db + + return db.Create(&downstream{ + Username: opt.Username, + Upstream: upstream{ + Username: opt.UpstreamUsername, + AuthMapType: authMapTypeNone, + Server: server{ + Address: fmt.Sprintf("%v:%v", opt.Host, opt.Port), + IgnoreHostKey: true, + }, + }, + }).Error } func (p *plugin) RemovePipe(name string) error { - panic("implement me") + db := p.db + + d, err := lookupDownstream(db, name) + if err != nil { + + if gorm.IsRecordNotFoundError(err) { + return nil + } + + return err + } + return db.Unscoped().Delete(d).Error } func (p *plugin) GetHandler() upstreamprovider.Handler { diff --git a/sshpiperd/upstream/provider.go b/sshpiperd/upstream/provider.go index 89ef2708..ef9b69d5 100644 --- a/sshpiperd/upstream/provider.go +++ b/sshpiperd/upstream/provider.go @@ -1,7 +1,9 @@ package upstream import ( + "fmt" "net" + "strconv" "golang.org/x/crypto/ssh" @@ -18,14 +20,14 @@ type CreatePipeOption struct { Username string UpstreamUsername string Host string - Port uint + Port int } type Pipe struct { Username string UpstreamUsername string Host string - Port uint + Port int } // Provider is a factory for Upstream Provider @@ -64,3 +66,27 @@ func Get(name string) Provider { return nil } + +func SplitHostPortForSSH(addr string) (host string, port int, err error) { + host = addr + h, p, err := net.SplitHostPort(host) + if err == nil { + host = h + port, err = strconv.Atoi(p) + + if err != nil { + return + } + } else if host != "" { + // test valid after concat :22 + if _, _, err := net.SplitHostPort(host + ":22"); err == nil { + port = 22 + } + } + + if host == "" { + err = fmt.Errorf("empty addr") + } + + return +} diff --git a/sshpiperd/upstream/workingdir/plugin.go b/sshpiperd/upstream/workingdir/plugin.go index 72dc6b0b..7728b97b 100644 --- a/sshpiperd/upstream/workingdir/plugin.go +++ b/sshpiperd/upstream/workingdir/plugin.go @@ -35,7 +35,7 @@ func (p *plugin) ListPipe() ([]upstream.Pipe, error) { pipes = append(pipes, upstream.Pipe{ Host: host, - Port: uint(port), + Port: port, Username: file.Name(), UpstreamUsername: mappedUser, }) diff --git a/sshpiperd/upstream/workingdir/workingdir.go b/sshpiperd/upstream/workingdir/workingdir.go index 40aaa075..b5da56b9 100644 --- a/sshpiperd/upstream/workingdir/workingdir.go +++ b/sshpiperd/upstream/workingdir/workingdir.go @@ -9,12 +9,12 @@ import ( "bufio" "bytes" "fmt" + "github.com/tg123/sshpiper/sshpiperd/upstream" "io/ioutil" "net" "os" "path" "regexp" - "strconv" "strings" "golang.org/x/crypto/ssh" @@ -106,25 +106,7 @@ func parseUpstreamFile(data string) (host string, port int, user string, err err host = t[1] } - h, p, err := net.SplitHostPort(host) - if err == nil { - host = h - port, err = strconv.Atoi(p) - - if err != nil { - return - } - } else if host != "" { - // test valid after concat :22 - if _, _, err := net.SplitHostPort(host + ":22"); err == nil { - port = 22 - } - } - - if host == "" { - err = fmt.Errorf("empty addr") - } - + host, port, err = upstream.SplitHostPortForSSH(host) return }