diff --git a/sshpiperd/cmd.go b/sshpiperd/cmd.go index b78640dc..4a6763e4 100644 --- a/sshpiperd/cmd.go +++ b/sshpiperd/cmd.go @@ -19,8 +19,8 @@ func (s *subCommand) Execute(args []string) error { return s.callback(args) } -func addSubCommand(parser *flags.Parser, name, desc string, callback func(args []string) error) { - _, err := parser.AddCommand(name, desc, "", &subCommand{callback}) +func addSubCommand(parser *flags.Parser, name, desc string, callback interface{}) { + _, err := parser.AddCommand(name, desc, "", callback) if err != nil { panic(err) @@ -80,30 +80,26 @@ func main() { parser.LongDescription = "SSH Piper works as a proxy-like ware, and route connections by username, src ip , etc. Please see for more information" // version - addSubCommand(parser, "version", "show version", func(args []string) error { + addSubCommand(parser, "version", "show version", &subCommand{func(args []string) error { showVersion() return nil - }) - - dumpConfig := func() { - ini := flags.NewIniParser(parser) - ini.Write(os.Stdout, flags.IniIncludeDefaults) - } + }}) // dumpini - addSubCommand(parser, "dumpconfig", "dump current config ini to stdout", func(args []string) error { - dumpConfig() + addSubCommand(parser, "dumpconfig", "dump current config ini to stdout", &subCommand{func(args []string) error { + ini := flags.NewIniParser(parser) + ini.Write(os.Stdout, flags.IniIncludeDefaults) return nil - }) + }}) // manpage - addSubCommand(parser, "manpage", "write man page to stdout", func(args []string) error { + addSubCommand(parser, "manpage", "write man page to stdout", &subCommand{func(args []string) error { parser.WriteManPage(os.Stdout) return nil - }) + }}) // plugins - addSubCommand(parser, "plugins", "list support plugins, e.g. sshpiperd plugis upstream", func(args []string) error { + addSubCommand(parser, "plugins", "list support plugins, e.g. sshpiperd plugis upstream", &subCommand{func(args []string) error { output := func(all []string) { for _, p := range all { @@ -128,10 +124,10 @@ func main() { } return nil - }) + }}) // options, for snap only at the moment - addSubCommand(parser, "options", "list all options", func(args []string) error { + addSubCommand(parser, "options", "list all options", &subCommand{func(args []string) error { for _, g := range parser.Groups() { for _, o := range g.Options() { fmt.Println(o.LongName) @@ -139,10 +135,10 @@ func main() { } return nil - }) + }}) // generate key tools - addSubCommand(parser, "genkey", "generate a 2048 rsa key to stdout", func(args []string) error { + addSubCommand(parser, "genkey", "generate a 2048 rsa key to stdout", &subCommand{func(args []string) error { key, err := sshkey.GenerateKey(sshkey.KEY_RSA, 2048) if err != nil { return err @@ -156,7 +152,7 @@ func main() { _, err = fmt.Fprint(os.Stdout, string(out)) return err - }) + }}) config := &struct { piperdConfig @@ -167,6 +163,8 @@ func main() { ConfigFile flags.Filename `long:"config" description:"Config file path. Will be overwriten by arg options and environment variables" default:"/etc/sshpiperd.ini" env:"SSHPIPERD_CONFIG_FILE" no-ini:"true"` }{} + addSubCommand(parser, "pipe", "manage pipe on current upstream driver", createPipeMgr(&config.UpstreamDriver)) + addOpt(parser, "sshpiperd", config) addPlugins(parser, "upstream", upstream.All(), func(n string) registry.Plugin { return upstream.Get(n) }) diff --git a/sshpiperd/pipemgr.go b/sshpiperd/pipemgr.go new file mode 100644 index 00000000..5810da7a --- /dev/null +++ b/sshpiperd/pipemgr.go @@ -0,0 +1,56 @@ +package main + +import ( + "fmt" + "github.com/tg123/sshpiper/sshpiperd/upstream" +) + +func createPipeMgr(driver *string) interface{} { + + load := func() (upstream.Provider, error) { + if *driver == "" { + return nil, fmt.Errorf("must provider upstream driver") + } + + return upstream.Get(*driver).(upstream.Provider), nil + } + + // pipe management + pipeMgrCmd := struct { + List struct { + subCommand + } `command:"list" description:"list all pipes"` + Add struct { + subCommand + } `command:"add" description:"add a pipe to current upstream"` + Remove struct { + subCommand + Name string `long:"name" required:"true"` + } `command:"remove" description:"remove a pipe from current upstream"` + }{} + + pipeMgrCmd.List.callback = func(args []string) error { + return nil + } + + pipeMgrCmd.Add.callback = func(args []string) error { + return nil + } + + pipeMgrCmd.Remove.callback = func(args []string) error { + + p, err := load() + + name := pipeMgrCmd.Remove.Name + + if err != nil { + return err + + } + + return p.RemovePipe(name) + + } + + return &pipeMgrCmd +} diff --git a/sshpiperd/upstream/database/plugin.go b/sshpiperd/upstream/database/plugin.go index b1055165..bda4b885 100644 --- a/sshpiperd/upstream/database/plugin.go +++ b/sshpiperd/upstream/database/plugin.go @@ -20,6 +20,14 @@ type plugin struct { db *gorm.DB } +func (p *plugin) CreatePipe(opt upstreamprovider.CreatePipeOption) error { + panic("implement me") +} + +func (p *plugin) RemovePipe(name string) error { + panic("implement me") +} + func (p *plugin) GetHandler() upstreamprovider.Handler { return p.findUpstream } diff --git a/sshpiperd/upstream/provider.go b/sshpiperd/upstream/provider.go index f07945e4..04ffb89c 100644 --- a/sshpiperd/upstream/provider.go +++ b/sshpiperd/upstream/provider.go @@ -14,11 +14,19 @@ import ( // e.g. map downstream public key to another upstream private key type Handler func(conn ssh.ConnMetadata) (net.Conn, *ssh.AuthPipe, error) +type CreatePipeOption struct { + +} + // Provider is a factory for Upstream Provider type Provider interface { registry.Plugin GetHandler() Handler + + CreatePipe(opt CreatePipeOption) error + + RemovePipe(name string) error } var ( diff --git a/sshpiperd/upstream/workingdir/plugin.go b/sshpiperd/upstream/workingdir/plugin.go index 3c472981..a3bc4c06 100644 --- a/sshpiperd/upstream/workingdir/plugin.go +++ b/sshpiperd/upstream/workingdir/plugin.go @@ -11,6 +11,14 @@ var logger *log.Logger type plugin struct { } +func (p *plugin) CreatePipe(opt upstream.CreatePipeOption) error { + panic("implement me") +} + +func (p *plugin) RemovePipe(name string) error { + panic("implement me") +} + func (p *plugin) GetName() string { return "workingdir" }