From 8e1b86d5547effb351504cbcd8dcc73bf47763d4 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sat, 11 May 2019 17:16:05 +0800 Subject: [PATCH] opt ssh --- etc/common.shy | 2 - etc/exit.shy | 4 +- etc/init.shy | 4 +- src/contexts/aaa/aaa.go | 28 +- src/contexts/ctx/{ctx_cgi.go => cgi.go} | 0 src/contexts/ctx/{ctx_type.go => ctx.go} | 43 +- src/contexts/ctx/ctx_test.go | 115 ---- src/contexts/ctx/{ctx_init.go => init.go} | 0 src/contexts/gdb/gdb_test.go | 28 - src/contexts/lex/lex_test.go | 152 ----- src/contexts/log/log_test.go | 19 - src/contexts/mdb/mdb_test.go | 61 -- src/contexts/ssh/ssh.go | 764 +++++++++------------- src/contexts/tcp/tcp_test.go | 29 - src/toolkit/kit.go | 4 + usr/wiki/自然/编程/终端工具链/context.md | 6 + 16 files changed, 375 insertions(+), 884 deletions(-) rename src/contexts/ctx/{ctx_cgi.go => cgi.go} (100%) rename src/contexts/ctx/{ctx_type.go => ctx.go} (96%) delete mode 100644 src/contexts/ctx/ctx_test.go rename src/contexts/ctx/{ctx_init.go => init.go} (100%) delete mode 100644 src/contexts/gdb/gdb_test.go delete mode 100644 src/contexts/lex/lex_test.go delete mode 100644 src/contexts/log/log_test.go delete mode 100644 src/contexts/mdb/mdb_test.go delete mode 100644 src/contexts/tcp/tcp_test.go diff --git a/etc/common.shy b/etc/common.shy index 4149fc45..08b7766d 100644 --- a/etc/common.shy +++ b/etc/common.shy @@ -1,5 +1,3 @@ -~ssh - config trust up true ~mdb note model favor spirit spirit relate relate note model money expend expend amount amount diff --git a/etc/exit.shy b/etc/exit.shy index 5755da1f..8babb8aa 100644 --- a/etc/exit.shy +++ b/etc/exit.shy @@ -1,5 +1,5 @@ -~code - config save tmp/flash.json flash +~ssh + config save tmp/cert.json cert trust ~aaa config save tmp/auth.json auth ~cli diff --git a/etc/init.shy b/etc/init.shy index d01c8442..bd83d65e 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -2,8 +2,8 @@ config load tmp/runtime.json runtime ~aaa config load tmp/auth.json auth -~code - config load tmp/flash.json flash +~ssh + config load tmp/cert.json cert trust source etc/common.shy ~ssh diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 56758756..8ed2a642 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -461,7 +461,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", for i := 1; i < len(arg); i++ { // 添加用户 if m.Cmd("aaa.auth", "ship", "username", arg[i], "userrole", role); i < len(arg)-2 { switch arg[i+1] { - case "password", "uuid": + case "password", "uuid", "cert": m.Cmd("aaa.auth", "ship", "username", arg[i], arg[i+1], arg[i+2]) i += 2 } @@ -628,26 +628,30 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", // 检查权限 m.Cmd("aaa.auth", "ship", "username", m.Option("username"), "userrole").Table(func(node map[string]string) { - if node["meta"] == "root" { // 超级用户 - m.Log("info", "role: root") - m.Echo("true") + if m.Options("userrole") && node["meta"] != m.Option("userrole") { + return // 失败 + } else if node["meta"] == "root" { // 超级用户 + } else if len(arg) > 2 { // 接口权限 if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[2]) { - m.Echo("true") + } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "componet", arg[1], "check", arg[2]); kit.Right(cid) { - m.Log("info", "role: %s", node["meta"]) m.Cmd("aaa.auth", m.Option("bench"), cid) - m.Echo("true") + } else { + return // 失败 } } else if len(arg) > 1 { // 组件权限 if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[1]) { - m.Echo("true") + } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", node["meta"], "check", arg[1]); kit.Right(cid) { - m.Log("info", "role: %s", node["meta"]) m.Cmd("aaa.auth", m.Option("bench"), cid) - m.Echo("true") + } else { + return // 失败 } } + + m.Log("info", "role: %s %v", node["meta"], arg[1:]) + m.Echo(node["meta"]) }) m.Log("right", "bench: %s sessid: %s user: %s com: %v result: %v", @@ -746,8 +750,8 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", // 生成证书 template := x509.Certificate{ - SerialNumber: big.NewInt(1), - IsCA: true, + SerialNumber: big.NewInt(1), + IsCA: true, BasicConstraintsValid: true, KeyUsage: x509.KeyUsageCertSign, Subject: pkix.Name{CommonName: kit.Format(common)}, diff --git a/src/contexts/ctx/ctx_cgi.go b/src/contexts/ctx/cgi.go similarity index 100% rename from src/contexts/ctx/ctx_cgi.go rename to src/contexts/ctx/cgi.go diff --git a/src/contexts/ctx/ctx_type.go b/src/contexts/ctx/ctx.go similarity index 96% rename from src/contexts/ctx/ctx_type.go rename to src/contexts/ctx/ctx.go index 4334671b..8d20612e 100644 --- a/src/contexts/ctx/ctx_type.go +++ b/src/contexts/ctx/ctx.go @@ -466,32 +466,41 @@ func (m *Message) Format(arg ...interface{}) string { } } + meta = append(meta, "\n") for i := len(ms) - 1; i >= 0; i-- { msg := ms[i] - meta = append(meta, fmt.Sprintf("\n%s\n", msg.Format("time", "ship"))) - meta = append(meta, fmt.Sprintf(" detail: %d %v\n", len(msg.Meta["detail"]), msg.Meta["detail"])) - meta = append(meta, fmt.Sprintf(" option: %d %v\n", len(msg.Meta["option"]), msg.Meta["option"])) - for _, k := range msg.Meta["option"] { - if v, ok := msg.Data[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v))) - } else if v, ok := msg.Meta[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) + meta = append(meta, fmt.Sprintf("%s\n", msg.Format("time", "ship"))) + if len(msg.Meta["detail"]) > 0 { + meta = append(meta, fmt.Sprintf(" detail: %d %v\n", len(msg.Meta["detail"]), msg.Meta["detail"])) + } + if len(msg.Meta["option"]) > 0 { + meta = append(meta, fmt.Sprintf(" option: %d %v\n", len(msg.Meta["option"]), msg.Meta["option"])) + for _, k := range msg.Meta["option"] { + if v, ok := msg.Data[k]; ok { + meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v))) + } else if v, ok := msg.Meta[k]; ok { + meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) + } } } - meta = append(meta, fmt.Sprintf(" append: %d %v\n", len(msg.Meta["append"]), msg.Meta["append"])) - for _, k := range msg.Meta["append"] { - if v, ok := msg.Data[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v))) - } else if v, ok := msg.Meta[k]; ok { - meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) + if len(msg.Meta["append"]) > 0 { + meta = append(meta, fmt.Sprintf(" append: %d %v\n", len(msg.Meta["append"]), msg.Meta["append"])) + for _, k := range msg.Meta["append"] { + if v, ok := msg.Data[k]; ok { + meta = append(meta, fmt.Sprintf(" %s: %v\n", k, kit.Format(v))) + } else if v, ok := msg.Meta[k]; ok { + meta = append(meta, fmt.Sprintf(" %s: %d %v\n", k, len(v), v)) + } } } - meta = append(meta, fmt.Sprintf(" result: %d %v\n", len(msg.Meta["result"]), msg.Meta["result"])) + if len(msg.Meta["result"]) > 0 { + meta = append(meta, fmt.Sprintf(" result: %d %v\n", len(msg.Meta["result"]), msg.Meta["result"])) + } } case "stack": pc := make([]uintptr, 100) - pc = pc[:runtime.Callers(2, pc)] + pc = pc[:runtime.Callers(6, pc)] frames := runtime.CallersFrames(pc) for { @@ -1570,7 +1579,7 @@ func (m *Message) Cmd(args ...interface{}) *Message { msg := m if strings.Contains(key, ":") { ps := strings.Split(key, ":") - msg, key, arg = msg.Sess("ssh"), "sh", append([]string{"node", ps[0], "sync", ps[1]}, arg...) + msg, key, arg = msg.Sess("ssh"), "remote", append([]string{"sync", ps[0], ps[1]}, arg...) defer func() { m.Copy(msg, "append").Copy(msg, "result") }() m.Hand = true diff --git a/src/contexts/ctx/ctx_test.go b/src/contexts/ctx/ctx_test.go deleted file mode 100644 index 06d60305..00000000 --- a/src/contexts/ctx/ctx_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package ctx - -import ( - "fmt" - "testing" -) - -func TestCtx(t *testing.T) { - context := Context{Name: "root", Help: "默认", - Caches: map[string]*Cache{ - "nclient": &Cache{"nclient", "10", "连接数量", func(c *Context) string { - return "10" - }}, - }, - Configs: map[string]*Config{ - "limit": &Config{"limit", "10", "最大连接数", func(c *Context, arg string) { - }}, - }, - Commands: map[string]*Command{ - "session": &Command{"session", "会话管理", func(c *Context, arg ...string) string { - return "ok" - }}, - }, - } - context.Index = map[string]*Context{"root": &context} - - ctx := context.Index["root"] - ctx.Add("context", "hi", "hi", "nice") - if _, ok := context.Contexts["hi"]; !ok { - t.Fatal("root.ctxs add error") - } - if c, ok := context.Index["hi"]; ok { - ctx.Add("command", "hi", "session") - if _, ok := c.Commands["session"]; ok { - if c.Cmd("session") != "ok" { - t.Fatal("hi.cmds.session: run error") - } - } else { - t.Fatal("hi.cmds: add error") - } - - ctx.Add("config", "hi", "limit") - ctx.Add("cache", "hi", "nclient") - - } else { - t.Fatal("root.index add error") - } - return - - if true { - ctx := context.Index["hi"] - if ctx.Cmd("session", "nice") == "ok" { - t.Log("hi.cmds.session: run") - } else { - t.Fatal("hi.cmds.session: run error") - } - t.Log() - - ctx.Add("context", "he", "he", "nice") - for k, v := range ctx.Contexts { - t.Log("hi.ctxs", k, v.Name, v.Help) - } - if len(ctx.Contexts) != 1 { - t.Fatal("hi.ctxs: add error") - } - for k, v := range ctx.Index { - t.Log("hi.index:", k, v.Name, v.Help) - } - if len(ctx.Index) != 3 { - t.Fatal("hi.index: add error") - } - t.Log() - - ctx.Add("command", "he", "session") - for k, v := range ctx.Contexts["he"].Commands { - t.Log("he.cmds:", k, v.Name, v.Help) - } - if len(ctx.Contexts["he"].Commands) != 1 { - t.Fatal("he.cmds: add error") - } - - } - - for k, v := range ctx.Index { - t.Log("root.index:", k, v.Name, v.Help) - } - if len(ctx.Index) != 3 { - t.Fatal("root.index add error") - } - t.Log() - - for k, v := range ctx.Index { - t.Log(fmt.Sprintf("root.index.%s.cmds: %d", k, len(v.Commands))) - } - t.Log() - ctx.Del("command", "hi", "session") - for k, v := range ctx.Index { - t.Log(fmt.Sprintf("root.index.%s.cmds: %d", k, len(v.Commands))) - } - t.Log() - - ctx.Del("context", "hi") - for k, v := range ctx.Contexts { - t.Log("root.ctxs:", k, v.Name, v.Help) - } - if len(ctx.Contexts) != 0 { - t.Fatal("root.ctxs: del error") - } - for k, v := range ctx.Index { - t.Log("root.index:", k, v.Name, v.Help) - } - if len(ctx.Index) != 1 { - t.Fatal("root.index del error") - } -} diff --git a/src/contexts/ctx/ctx_init.go b/src/contexts/ctx/init.go similarity index 100% rename from src/contexts/ctx/ctx_init.go rename to src/contexts/ctx/init.go diff --git a/src/contexts/gdb/gdb_test.go b/src/contexts/gdb/gdb_test.go deleted file mode 100644 index c6837a76..00000000 --- a/src/contexts/gdb/gdb_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package gdb - -import ( - "contexts/ctx" - "testing" - "time" -) - -func TestLog(t *testing.T) { - m := ctx.Pulse.Spawn(Index) - m.Sess("gdb", m) - m.Target().Begin(m).Start(m) - - go func() { - t.Logf("%s", m.Cmd("wait", "config", "demo").Result(0)) - - // t.Logf("%s", m.Cmd("demo", "what").Result(0)) - }() - - time.Sleep(time.Second * 3) - - m.Spawn().Cmd("goon", "nice") - - // gdb := m.Target().Server.(*GDB) - // gdb.Goon("yes", "command", "demo") - // - time.Sleep(time.Second * 3) -} diff --git a/src/contexts/lex/lex_test.go b/src/contexts/lex/lex_test.go deleted file mode 100644 index 70aca707..00000000 --- a/src/contexts/lex/lex_test.go +++ /dev/null @@ -1,152 +0,0 @@ -package lex - -import ( - "context" - "testing" -) - -func TestLEX(t *testing.T) { - - m := ctx.Pulse.Spawn(Index) - seed := map[string]map[string]string{ - // "shy?": map[string]string{ - // "s": "", - // "sh": "sh", - // "she": "sh", - // "shy": "shy", - // "shyyy": "shy", - // }, - // "shy*": map[string]string{ - // "s": "", - // "sh": "sh", - // "she": "sh", - // "shy": "shy", - // "shyyy": "shyyy", - // }, - // "shy+": map[string]string{ - // "s": "", - // "sh": "", - // "she": "", - // "shy": "shy", - // "shyyy": "shyyy", - // }, - // "s?hy": map[string]string{ - // "s": "", - // "sh": "", - // "she": "", - // "shy": "shy", - // "hy": "hy", - // }, - // "s*hy": map[string]string{ - // "s": "", - // "sh": "", - // "she": "", - // "shy": "shy", - // "ssshy": "ssshy", - // "hy": "hy", - // }, - // "s+hy": map[string]string{ - // "s": "", - // "sh": "", - // "she": "", - // "shy": "shy", - // "ssshy": "ssshy", - // "hy": "", - // }, - // "sh[xyz]?": map[string]string{ - // "s": "", - // "sh": "sh", - // "she": "sh", - // "shy": "shy", - // "shyyy": "shy", - // }, - // "sh[xyz]*": map[string]string{ - // "s": "", - // "sh": "sh", - // "she": "sh", - // "shy": "shy", - // "shyyy": "shyyy", - // "shyxz": "shyxz", - // }, - // "sh[xyz]+": map[string]string{ - // "s": "", - // "sh": "", - // "she": "", - // "shy": "shy", - // "shyyy": "shyyy", - // "shyxzy": "shyxzy", - // }, - // "[xyz]?sh": map[string]string{ - // "s": "", - // "sh": "sh", - // "zsh": "zsh", - // "zxyshy": "", - // }, - // "[xyz]*sh": map[string]string{ - // "s": "", - // "sh": "sh", - // "zsh": "zsh", - // "zxyshy": "zxysh", - // }, - // "[xyz]+sh": map[string]string{ - // "s": "", - // "sh": "", - // "zsh": "zsh", - // "zxyshy": "zxysh", - // }, - // "[0-9]+": map[string]string{ - // "hello": "", - // "hi123": "", - // "123": "123", - // "123hi": "123", - // }, - // "0x[0-9a-fA-F]+": map[string]string{ - // "hello": "", - // "0xhi123": "", - // "0x123": "0x123", - // "0xab123ab": "0xab123ab", - // "0x123ab": "0x123ab", - // }, - "[a-zA-Z][a-zA-Z0-9]*": map[string]string{ - "hello": "hello", - "hi123": "hi123", - "123": "", - }, - "\"[^\"]*\"": map[string]string{ - "hello": "", - "0xhi123": "", - "\"hi\"": "\"hi\"", - "\"\\\"hi\"": "\"\\\"hi\"", - }, - } - m.Conf("debug", "on") - Index.Begin(m) - for k, s := range seed { - Index.Start(m) - m.Cmd("train", k) - for i, v := range s { - if m.Cmd("parse", i) != v { - t.Error("train&parse error:", k, i, v) - } - } - } - - Index.Start(m) - m.Cmd("train", "[ \n\t]+", "1") - m.Cmd("train", "[a-zA-Z][a-zA-Z0-9]*", "2", "2") - m.Cmd("train", "0x[0-9]+", "3", "2") - m.Cmd("train", "[0-9]+", "3", "2") - m.Cmd("train", "\"[^\"]*\"", "4", "2") - m.Cmd("train", "'[^']*'", "4", "2") - - lex := Index.Server.(*LEX) - for _, v := range lex.seed { - t.Log(v.page, v.hash, v.word) - } - - m.Cmd("split", "hello 0x2134 \"hi he\" meet\\ you") - // m.Cmd("parse", "0x54 nice to meet") - // m.Cmd("parse", "737 nice to meet") - // m.Cmd("parse", "\"73 u\" nice to meet") - // m.Cmd("parse", "'hh h' nice to meet") -} diff --git a/src/contexts/log/log_test.go b/src/contexts/log/log_test.go deleted file mode 100644 index fd0e8c11..00000000 --- a/src/contexts/log/log_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package log - -import ( - "contexts/ctx" - "testing" -) - -func TestLog(t *testing.T) { - m := ctx.Pulse.Spawn(Index) - m.Target().Begin(m) - m.Sess("log", m) - m.Log("error", "what %v", 123) - m.Log("debug", "what %v", 123) - m.Log("info", "what %v", 123) - m.Log("cmd", "what %v", 123) - m.Log("begin", "what %v", 123) - m.Log("search", "what %v", 123) - m.Cmd("log", "search", "what %v", 123) -} diff --git a/src/contexts/mdb/mdb_test.go b/src/contexts/mdb/mdb_test.go deleted file mode 100644 index 4029ff2f..00000000 --- a/src/contexts/mdb/mdb_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package mdb - -import ( - "context" - "flag" - "log" - "os" - "testing" -) - -func TestOpen(t *testing.T) { - flag.Parse() - args := flag.Args() - if len(args) < 2 { - t.Fatal("usages: -args source driver [table]") - } - - source := "user:word@/book" - driver := "mysql" - source = args[0] - driver = args[1] - - //mysql -u root -p; - //create database book; - //grant all on book.* to user identified by 'word' - - ctx.Start() - ctx.Index.Conf("debug", "off") - log.SetOutput(os.Stdout) - m := ctx.Pulse.Spawn(Index) - - m.Meta = nil - m.Cmd("open", source, driver) - - m.Meta = nil - m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "1", "2", "3") - - m.Meta = nil - m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "1", "2", "3") - - m.Meta = nil - m.Cmd("exec", "insert into program(time, hash, name) values(?, ?, ?)", "2", "3", "4") - - m.Meta = nil - m.Cmd("query", "select time, hash, name from program") - - t.Log() - for i, rows := 0, len(m.Meta[m.Meta["append"][0]]); i < rows; i++ { - for _, k := range m.Meta["append"] { - t.Log(k, m.Meta[k][i]) - } - t.Log() - } - - if len(m.Meta["append"]) != 3 || len(m.Meta[m.Meta["append"][0]]) != 2 { - t.Error() - } - - m.Meta = nil - // Index.Exit(m) -} diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index cb621d36..04e24ee6 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -2,10 +2,6 @@ package ssh import ( "contexts/ctx" - "encoding/base64" - "fmt" - "os" - "path" "strings" "toolkit" ) @@ -29,7 +25,7 @@ func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { return true } func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { - return true + return false } var Index = &ctx.Context{Name: "ssh", Help: "集群中心", @@ -37,12 +33,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", "nnode": &ctx.Cache{Name: "nnode", Value: "0", Help: "节点数量"}, }, Configs: map[string]*ctx.Config{ - "current": &ctx.Config{Name: "current", Value: "", Help: "当前主机"}, - "trust": &ctx.Config{Name: "trust", Value: map[string]interface{}{}, Help: "可信主机"}, - "node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "主机信息"}, - "timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{"interval": "10s", "timer": ""}, Help: "断线重连"}, - - "cert": &ctx.Config{Name: "cert", Value: map[string]interface{}{}, Help: "用户证书"}, + "node": &ctx.Config{Name: "node", Value: map[string]interface{}{}, Help: "节点信息"}, + "cert": &ctx.Config{Name: "cert", Value: map[string]interface{}{}, Help: "用户信息"}, + "trust": &ctx.Config{Name: "trust", Value: map[string]interface{}{"fresh": true, "user": true, "up": true}, Help: "可信节点"}, + "timer": &ctx.Config{Name: "timer", Value: map[string]interface{}{"interval": "10s", "timer": ""}, Help: "断线重连"}, }, Commands: map[string]*ctx.Command{ "init": &ctx.Command{Name: "init", Help: "启动", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { @@ -55,60 +49,273 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", } m.Conf("runtime", "node.route", m.Conf("runtime", "node.name")) m.Conf("runtime", "user.name", m.Conf("runtime", "boot.USER")) + m.Conf("runtime", "work.name", m.Conf("runtime", "boot.USER")) return }}, - "cert": &ctx.Command{Name: "cert [node|user|work [create [args...]]]", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "node": &ctx.Command{Name: "node [create|delete [name [type module]]]", Help: "节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) == 0 { + m.Cmdy("ctx.config", "node", "format", "table", "fields", "type", "module", "create_time") + return + } + + switch arg[0] { + case "create": // 添加节点 + m.Log("info", "create node %s %s", arg[1], arg[2]) + m.Confv("node", arg[1], map[string]interface{}{ + "name": arg[1], "type": arg[2], "module": arg[3], + "create_time": m.Time(), + }) + + case "delete": // 删除节点 + m.Log("info", "delete node %s %s", arg[1], kit.Formats(m.Conf("node", arg[1]))) + delete(m.Confm("node"), arg[1]) + } + return + }}, + "cert": &ctx.Command{Name: "cert [node|user|work]", Help: []string{"认证", + "node [create|check text|trust node]", + "user [create|check text|share role node...|proxy node|trust node]", + "work [create node name|check node name]", + }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if len(arg) == 0 { m.Add("append", "key", "node.cert") + m.Add("append", "route", m.Conf("runtime", "node.route")) m.Add("append", "value", m.Conf("runtime", "node.cert")) m.Add("append", "key", "user.cert") + m.Add("append", "route", m.Conf("runtime", "user.route")) m.Add("append", "value", m.Conf("runtime", "user.cert")) + m.Add("append", "key", "work.name") + m.Add("append", "route", m.Conf("runtime", "work.route")) + m.Add("append", "value", m.Conf("runtime", "work.name")) m.Table() return } switch arg[0] { - case "node": // 节点证书 - if len(arg) > 1 && arg[1] == "create" { + case "node": // 节点认证 + if len(arg) == 1 { + m.Echo(m.Conf("runtime", "node.cert")) + break + } + + switch arg[1] { + case "create": // 创建证书 msg := m.Cmd("aaa.rsa", "gen") m.Conf("runtime", "node.cert", msg.Append("certificate")) m.Conf("runtime", "node.key", msg.Append("private")) - } - m.Echo(m.Conf("runtime", "node.cert")) + m.Echo(m.Conf("runtime", "node.cert")) - case "user": // 用户证书 - if len(arg) > 1 && arg[1] == "create" { + case "check": // 数字验签 + if m.Option("node.cert", m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert").Append("meta")); !m.Options("node.cert") { + m.Option("node.cert", m.Cmdx("ssh.remote", m.Option("node.route"), "check", "node")) + m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert")) + } + + if !m.Cmds("aaa.rsa", "verify", m.Option("node.cert"), m.Option("node.sign"), arg[2]) { + m.Log("warn", "node error") + m.Echo("false") + } else { + m.Echo("true") + } + + case "trust": // 可信节点 + if m.Confs("trust", arg[2]) { + m.Echo("true") + + } else if m.Confs("trust", "user") && m.Conf("runtime", "user.route") == arg[2] { + m.Echo("true") + + } else if m.Confs("trust", "up") && strings.HasPrefix(m.Conf("runtime", "node.route"), arg[2]) { + m.Echo("true") + } + } + + case "user": // 用户认证 + if len(arg) == 1 { + m.Echo(m.Conf("runtime", "user.cert")) + break + } + + switch arg[1] { + case "create": // 创建证书 msg := m.Cmd("aaa.rsa", "gen") m.Conf("runtime", "user.route", m.Conf("runtime", "node.route")) m.Conf("runtime", "user.cert", msg.Append("certificate")) m.Conf("runtime", "user.key", msg.Append("private")) - } - m.Echo(m.Conf("runtime", "user.cert")) + m.Echo(m.Conf("runtime", "user.cert")) - case "work": // 工作证书 - if len(arg) > 1 && arg[1] == "create" { - if name := m.Cmdx("ssh.sh", "node", arg[2], "check", "work", m.Conf("runtime", "user.route"), m.Conf("runtime", "user.cert"), arg[3]); name != "" { + case "check": // 数字验签 + if m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta")); !m.Options("user.cert") { + m.Option("user.cert", m.Cmd("ssh.remote", m.Option("user.route"), "check", "user").Append("user.cert")) + m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert")) + m.Cmd("aaa.auth", "username", m.Option("username"), "userrole", "void") + } + + if !m.Options("user.cert") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), arg[2]) { + m.Log("warn", "user error") + m.Echo("false") + } else { + m.Echo("true") + } + + case "share": // 共享用户 + for _, route := range arg[3:] { + user := m.Cmd("ssh.remote", route, "check", "user") + if m.Cmd("aaa.role", arg[2], "user", user.Append("user.name"), "cert", user.Append("user.cert")); arg[2] == "root" && route != m.Conf("runtime", "node.route") { + m.Conf("runtime", "user.route", user.Append("user.route")) + m.Conf("runtime", "user.name", user.Append("user.name")) + m.Conf("runtime", "user.cert", user.Append("user.cert")) + m.Conf("runtime", "user.key", "") + } + } + + case "proxy": // 代理用户 + if len(arg) == 2 { + m.Cmdy("aaa.auth", "proxy") + break + } + if !m.Cmds("aaa.auth", "proxy", arg[2], "session") { + m.Cmdy("aaa.sess", "proxy", "proxy", arg[2]) + } + + case "trust": // 可信代理 + hash := kit.Hashs("rand", m.Option("text.time", m.Time("stamp")), arg[2]) + m.Option("user.sign", m.Cmdx("ssh.remote", m.Option("user.route"), "check", "user", arg[2], hash)) + m.Echo("%s", m.Options("user.sign") && m.Cmds("ssh.check", hash)) + } + + case "work": // 公有认证 + if len(arg) == 1 { + m.Echo(m.Conf("runtime", "work.name")) + break + } + + switch arg[1] { + case "create": // 创建证书 + if name := m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3], m.Conf("runtime", "user.route"), m.Conf("runtime", "user.cert")); name != "" { m.Conf("runtime", "work.route", arg[2]) m.Conf("runtime", "work.name", name) + m.Echo(name) + } + + case "check": // 数字验签 + if m.Option("user.route") != m.Cmdx("ssh.remote", arg[2], "check", "work", arg[3]) { + m.Log("warn", "work error") + m.Echo("false") + } else { + m.Echo("true") } } - m.Echo(m.Conf("runtime", "work.name")) } - return }}, - "remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "远程连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("ctx.config", "node", "format", "table") - m.Meta["append"] = []string{"key", "type", "create_time"} + "check": &ctx.Command{Name: "check node|user|work", Help: []string{"验签", + "node", "user [node text]", "work name [node cert]", + }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch arg[0] { + case "node": // 节点验签 + m.Echo(m.Conf("runtime", "node.cert")) + + case "user": // 用户验签 + if len(arg) == 1 { + m.Append("user.cert", m.Conf("runtime", "user.cert")) + m.Append("user.name", m.Conf("runtime", "user.name")) + m.Append("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route"))) + } else { // 代理签证 + if arg[1] == m.Conf("runtime", "node.route") || m.Cmds("aaa.auth", "proxy", arg[1], "session") { + m.Echo(m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), arg[2])) + } + } + case "work": // 工作验签 + if cert := m.Confm("cert", arg[1]); len(arg) == 2 { + if cert != nil { + m.Echo("%s", cert["user"]) + } + } else { // 工作签证 + if cert == nil { + m.Conf("cert", arg[1], map[string]interface{}{"create_time": m.Time(), "user": arg[2]}) + } else if cert["user"] != arg[2] { + return // 签证失败 + } + m.Echo(arg[1]) + } + } + return + }}, + "action": &ctx.Command{Name: "action", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + hash := kit.Hashs( + m.Option("text.rand"), + m.Option("text.time"), + m.Option("text.cmd"), + m.Option("text.route"), + m.Option("node.route"), + m.Option("user.route"), + m.Option("user.name"), + m.Option("work.name"), + m.Option("work.route"), + ) + + // 文本验签 + if m.Option("text.hash") != hash { + m.Echo("text error %s != %s", m.Option("text.hash"), hash) + m.Log("warn", "text error") return } + // 设备验签 + if !m.Cmds("ssh.cert", "node", "check", hash) { + m.Echo("node error of %s", m.Option("node.route")) + return + } + + // 用户验签 + m.Option("username", m.Option("user.name")) + if !m.Confs("runtime", "user.route") && m.Confs("trust", "fresh") { + m.Log("warn", "trust fresh %s", m.Option("node.route")) + m.Option("trust", "fresh") + + } else if m.Cmds("ssh.cert", "node", "trust", m.Option("node.route")) { + m.Log("warn", "trust node %s", m.Option("node.route")) + m.Option("trust", "node") + + } else if m.Options("user.route") && m.Cmds("ssh.cert", "node", "trust", m.Option("user.route")) && m.Cmds("ssh.cert", "user", "trust", m.Option("node.route")) { + m.Log("warn", "trust user %s", m.Option("user.route")) + m.Option("trust", "user") + + } else if m.Option("username", m.Option("work.name")); m.Options("work.route") && m.Cmds("ssh.cert", "node", "trust", m.Option("work.route")) && m.Cmds("ssh.cert", "work", "check", m.Option("work.route"), m.Option("username")) { + m.Log("warn", "trust work %s", m.Option("work.route")) + m.Option("trust", "work") + + } else if m.Option("userrole", "void"); m.Confs("trust", "none") { + m.Log("warn", "trust none") + m.Option("trust", "none") + + } else { + m.Log("warn", "user error of %s", m.Option("user.route")) + return + } + m.Log("info", "username: %s", m.Option("username")) + + // 创建会话 + m.Option("sessid", m.Cmdx("aaa.user", "session", "select")) + + // 创建空间 + m.Option("bench", m.Cmdx("aaa.sess", "bench", "select")) + + // 权限检查 + if !m.Cmds("aaa.work", "right", "remote", arg[0]) { + m.Echo("no right %s %s", "remote", arg[0]) + return + } + + // 执行命令 + m.Cmdm(arg) + return + }}, + "remote": &ctx.Command{Name: "remote auto|dial|listen args...", Help: "连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { // 设备证书 if !m.Confs("runtime", "node.cert") || !m.Confs("runtime", "node.key") { - msg := m.Cmd("aaa.rsa", "gen", "common", m.Confv("runtime", "node")) - m.Conf("runtime", "node.cert", msg.Append("certificate")) - m.Conf("runtime", "node.key", msg.Append("private")) + m.Cmd("ssh.cert", "node", "create") } switch arg[0] { @@ -134,7 +341,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", case "dial": // 连接主机 m.Call(func(nfs *ctx.Message) *ctx.Message { - // 断线重连 + // 删除重连 if m.Confs("timer", "timer") { m.Conf("timer", "timer", m.Cmdx("cli.timer", "delete", m.Conf("timer", "timer"))) } @@ -142,101 +349,82 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", // 注册设备 m.Spawn(nfs.Target()).Call(func(node *ctx.Message) *ctx.Message { // 添加网关 - m.Confv("node", node.Append("node.name"), map[string]interface{}{ - "module": m.Cap("stream", nfs.Format("target")), - "create_time": m.Time(), - "type": "master", - "name": node.Append("node.name"), + m.Cmd("ssh.node", "create", node.Append("node.name"), "master", m.Cap("stream", nfs.Format("target"))) + + // 清理回调 + nfs.Free(func(nfs *ctx.Message) bool { + m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", node.Append("node.name")), "delete", "node") + m.Cmd("ssh.node", "delete", node.Append("node.name")) + m.Cap("stream", "") + + // 断线重连 + m.Conf("timer", "timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer", "interval"), "context", "ssh", "remote", "redial", arg[1:])) + return true }) // 本机路由 m.Conf("runtime", "node.route", node.Append("node.route")+"."+node.Result(0)) - // 本机用户 - if !m.Confs("runtime", "user.route") { - if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") { - m.Cmd("ssh.share", "root", m.Conf("runtime", "node.route")) - } else if node.Appends("user.route") { - m.Cmd("ssh.share", "root", node.Append("user.route")) - } - } + // 用户路由 + if m.Confs("runtime", "user.cert") && m.Confs("runtime", "user.key") { + m.Conf("runtime", "user.route", m.Conf("runtime", "node.route")) - // 网关用户 - if !node.Appends("user.route") { - m.Cmd("ssh.share", node.Append("node.route"), "root", m.Conf("runtime", "node.route")) + } else if node.Appends("user.route") && !m.Confs("runtime", "user.route") { + m.Cmd("ssh.node", "share", "root", node.Append("user.route")) } - - // 清理主机 - nfs.Free(func(nfs *ctx.Message) bool { - m.Conf("timer", "timer", m.Cmdx("cli.timer", "repeat", m.Conf("timer", "interval"), "context", "ssh", "remote", "redial", arg[1:])) - m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", node.Append("node.name")), "delete", "node") - m.Log("info", "delete node %s", node.Append("node.name")) - delete(m.Confm("node"), node.Append("node.name")) - m.Cap("stream", "") - return true - }) return nil - }, "send", "recv", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "node.cert")) + }, "send", "add", m.Conf("runtime", "node.name"), m.Conf("runtime", "node.type"), m.Conf("runtime", "node.cert")) return nil }, "nfs.remote", arg) - case "recv": - switch arg[1] { - case "add": - // 节点命名 - name := arg[2] - for node := m.Confm("node", name); node != nil; node = m.Confm("node", name) { - name = fmt.Sprintf("%s_%d", arg[2], m.Capi("nnode", 1)) - } - - // 添加节点 - m.Confv("node", name, map[string]interface{}{ - "module": m.Format("source"), - "create_time": m.Time(), - "type": arg[3], - "name": name, - }) - - // 节点路由 - m.Append("user.name", m.Conf("runtime", "user.name")) - m.Append("user.route", m.Conf("runtime", "user.route")) - m.Append("node.route", m.Conf("runtime", "node.route")) - m.Append("node.name", m.Conf("runtime", "node.name")) - m.Echo(name).Back(m) - - // 清理节点 - m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { - m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", name), "delete", "node") - m.Log("info", "delete node %s", name) - delete(m.Confm("node"), name) - return true - }) + case "add": + // 命名节点 + name := arg[1] + for node := m.Confm("node", name); node != nil; node = m.Confm("node", name) { + name = kit.Format("%s_%s", arg[1], m.Capi("nnode", 1)) } + // 添加节点 + m.Cmd("ssh.node", "create", name, arg[2], m.Format("source")) + + // 清理回调 + m.Sess("ms_source", false).Free(func(msg *ctx.Message) bool { + m.Cmd("aaa.auth", m.Cmdx("aaa.auth", "nodes", name), "delete", "node") + m.Cmd("ssh.node", "delete", name) + return true + }) + + // 同步信息 + m.Append("node.name", m.Conf("runtime", "node.name")) + m.Append("node.route", m.Conf("runtime", "node.route")) + m.Append("user.route", m.Conf("runtime", "user.route")) + m.Append("user.name", m.Conf("runtime", "user.name")) + m.Echo(name).Back(m) + default: - // 拆分路由 - if arg[0] == m.Conf("runtime", "node.name") || arg[0] == m.Conf("runtime", "node.route") { - arg[0] = "" - } - arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.route")+".") - arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.name")+".") - route, names, arg := arg[0], strings.SplitN(arg[0], ".", 2), arg[1:] - if len(names) > 1 && names[0] == "" && names[1] != "" { - names[0], names[1] = names[1], names[0] - } - // 同步异步 - sync := !m.Options("remote_code") + sync := true switch arg[0] { case "async", "sync": sync, arg = arg[0] == "sync", arg[1:] } - // 路由转发 + // 局域路由 + if arg[0] == m.Conf("runtime", "node.name") || arg[0] == m.Conf("runtime", "node.route") { + arg[0] = "" + } + arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.route")+".") + arg[0] = strings.TrimPrefix(arg[0], m.Conf("runtime", "node.name")+".") + + // 拆分路由 + route, names, arg := arg[0], strings.SplitN(arg[0], ".", 2), arg[1:] + if len(names) > 1 && names[0] == "" && names[1] != "" { + names[0], names[1] = names[1], names[0] + } + if rest := kit.Select("", names, 1); names[0] != "" { // 数字签名 if !m.Options("remote_code") && arg[0] != "check" { - // 数据哈希 hash, meta := kit.Hash("rand", m.Option("text.time", m.Time("stamp")), m.Option("text.cmd", strings.Join(arg, " ")), @@ -245,369 +433,55 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Option("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route"))), m.Option("user.name", m.Option("username")), m.Option("work.name", m.Conf("runtime", "work.name")), + m.Option("work.route", m.Conf("runtime", "work.route")), ) m.Option("text.rand", meta[0]) - - // 设备签名 m.Option("node.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "node.key"), m.Option("text.hash", hash))) - - // 用户签名 - if m.Options("user.sign") && m.Confs("runtime", "user.key") { - m.Option("user.sign", m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), m.Option("text.hash", hash))) - } } + // 查找路由 + ps := []string{} if names[0] == "%" || names[0] == "*" { // 广播命令 m.Confm("node", names[0], func(name string, node map[string]interface{}) { if kit.Format(node["type"]) != "master" { - m.Find(kit.Format(node["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { - return m.CopyFuck(sub, "append").CopyFuck(sub, "result").Echo("\n\n") - }, "send", rest, arg) + ps = append(ps, kit.Format(node["module"])) } }) } else if m.Confm("node", names[0], func(node map[string]interface{}) { // 单播命令 - m.Find(kit.Format(node["module"]), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { - return m.Copy(sub, "append").Copy(sub, "result") - }, "send", rest, arg) + ps = append(ps, kit.Format(node["module"])) - }) == nil { // 上报命令 - m.Find(m.Cap("stream"), true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { - return m.Copy(sub, "append").Copy(sub, "result") - }, "send", strings.Join(names, "."), arg) + }) == nil && m.Caps("stream") { // 上报命令 + rest = strings.Join(names, ".") + ps = append(ps, m.Cap("stream")) + } + if len(ps) == 0 { + m.Echo("error: not found %s", names[0]).Back(m) + return + } + + // 路由转发 + for _, p := range ps { + m.Find(p, true).Copy(m, "option").CallBack(sync, func(sub *ctx.Message) *ctx.Message { + return m.CopyFuck(sub, "append").CopyFuck(sub, "result").Echo("\n") + }, "send", rest, arg) } return } - // 返回结果 + // 远程回调 defer func() { m.Back(m) }() - // 查看证书 - switch arg[0] { - case "check": - switch arg[1] { - case "node": // 设备证书 - m.Echo(m.Conf("runtime", "node.cert")) - case "user": - if len(arg) == 2 { // 用户证书 - m.Append("user.cert", m.Conf("runtime", "user.cert")) - m.Append("user.name", m.Conf("runtime", "user.name")) - m.Append("user.route", kit.Select(m.Conf("runtime", "node.route"), m.Conf("runtime", "user.route"))) - } else { // 代理验证 - if arg[2] == m.Conf("runtime", "node.route") || m.Cmds("aaa.auth", "proxy", arg[2], "session") { - m.Echo(m.Cmdx("aaa.rsa", "sign", m.Conf("runtime", "user.key"), arg[3])) - } - } - case "work": - if len(arg) == 2 { // 查看 - if cert := m.Confm("cert", arg[2]); cert != nil { - m.Echo("%s", cert["user"]) - return - } - - } else { // 申请 - if cert := m.Confm("cert", arg[4]); cert != nil { - if cert["user"] != arg[2] { - return - } - m.Echo(arg[4]) - return - } - - m.Conf("cert", arg[4], map[string]interface{}{ - "create_time": m.Time(), - "user": arg[2], - }) - m.Echo(arg[4]) - } - } - return - } - - if m.Options("remote_code") { - // 检查数据 - hash, _ := kit.Hash( - m.Option("text.rand"), - m.Option("text.time"), - m.Option("text.cmd"), - m.Option("text.route"), - m.Option("node.route"), - m.Option("user.route"), - m.Option("user.name"), - m.Option("work.name"), - ) - if m.Option("text.hash") != hash { - m.Log("warning", "text error") - return - } - - // 设备证书 - if m.Option("node.cert", m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert").Append("meta")); !m.Options("node.cert") { - m.Option("node.cert", m.Spawn().Cmdx("ssh.remote", m.Option("node.route"), "sync", "check", "node")) - m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert")) - } - // 设备验签 - if !m.Cmds("aaa.rsa", "verify", m.Option("node.cert"), m.Option("node.sign"), m.Option("text.hash", hash)) { - m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "cert", m.Option("node.cert")) - m.Log("warning", "node error") - m.Cmd("aaa.auth", "nodes", m.Option("node.route"), "node", "delete") - return - } - } else { - m.Option("user.name", m.Conf("runtime", "user.name")) - } - - switch arg[0] { - case "share": // 设备权限 - // 默认用户 - if !m.Confs("runtime", "user.route") { - user := m.Spawn().Cmd("ssh.remote", m.Option("user.route"), "sync", "check", "user") - m.Conf("runtime", "user.route", user.Append("user.route")) - m.Conf("runtime", "user.name", user.Append("user.name")) - m.Conf("runtime", "user.cert", user.Append("user.cert")) - m.Cmd("aaa.role", "root", "user", user.Append("user.name")) - m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert")) - return - } - - // 共享用户 - if !m.Options("remote_code") || (m.Options("user.sign") && m.Conf("runtime", "user.name") == m.Option("user.name")) { - if !m.Options("remote_code") || m.Cmds("aaa.rsa", "verify", m.Conf("runtime", "user.cert"), m.Option("user.sign"), m.Option("text.hash")) { - for _, v := range arg[2:] { - user := m.Spawn().Cmd("ssh.remote", v, "sync", "check", "user") - m.Cmd("aaa.user", arg[1], "user", user.Append("user.name")) - m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert")) - } - return - } - } - - // 申请权限 - m.Spawn().Set("option", "remote_code", "").Cmds("ssh.remote", m.Conf("runtime", "user.route"), "sync", "apply", arg[1:]) - return - - case "apply": // 权限申请 - for _, v := range arg[2:] { - user := m.Spawn().Cmd("ssh.remote", v, "sync", "check", "user") - m.Cmd("aaa.auth", "username", user.Append("user.name"), "cert", user.Append("user.cert")) - - sess := m.Cmd("aaa.auth", "username", user.Append("user.name"), "session", "apply").Append("key") - if sess == "" { - sess = m.Cmdx("aaa.sess", "apply", "username", arg[2]) - } - m.Cmd("aaa.auth", sess, "apply", m.Option("node.route")) - m.Cmd("aaa.auth", sess, "share", user.Append("user.route")) - } - return - - case "login": // 用户代理 - if !m.Cmds("aaa.auth", "proxy", m.Option("node.route")) { - return - } - - sess := m.Cmd("aaa.auth", "username", m.Option("user.name"), "session", "proxy").Append("key") - if sess == "" { - sess = m.Cmdx("aaa.sess", "proxy", "username", m.Option("user.name")) - } - - m.Cmd("aaa.auth", sess, "proxy", m.Option("node.route")) - m.Echo(sess) - return - } - - if m.Options("remote_code") { - m.Log("info", "username %s", m.Option("work.name")) - if m.Option("username", m.Option("work.name")); m.Confs("trust", m.Option("node.route")) { - m.Log("info", "skip verify user of node %s", m.Option("node.route")) - } else if m.Confs("trust", "up") && strings.HasPrefix(m.Conf("runtime", "node.route"), m.Option("node.route")) { - m.Log("info", "skip verify user of up node %s", m.Option("node.route")) - } else { - // 用户签名 - hash, _ := kit.Hash("rand", m.Option("text.time", m.Time("stamp")), m.Option("node.route")) - if m.Option("user.cert", m.Cmd("aaa.auth", "username", m.Option("username"), "cert").Append("meta")); !m.Options("user.cert") { - m.Option("user.cert", m.Cmd("ssh.remote", m.Option("user.route"), "sync", "check", "user").Append("user.cert")) - m.Log("fuck", "user.eert %v", m.Option("user.cert")) - m.Log("fuck", "wat %v", m.Cmd("aaa.auth", "username", m.Option("username"), "cert", m.Option("user.cert"))) - } - m.Option("user.sign", m.Spawn().Cmdx("ssh.remote", m.Option("user.route"), "sync", "check", "user", m.Option("node.route"), hash)) - - // 代理验签 - if !m.Options("user.cert") || !m.Options("user.sign") || !m.Cmds("aaa.rsa", "verify", m.Option("user.cert"), m.Option("user.sign"), hash) { - m.Log("warn", "user error") - m.Echo("no right of %s", m.Option("text.route")) - return - } - } - - // 创建会话 - m.Option("sessid", m.Cmdx("aaa.user", "session", "select")) - - // 创建空间 - m.Option("bench", m.Cmdx("aaa.sess", "bench", "select")) - - // 权限检查 - if !m.Cmds("aaa.work", "right", "remote", arg[0]) { - m.Echo("no right %s %s", "remote", arg[0]) - return - } - } - // 执行命令 - m.Cmdm(arg) - } - return - }}, + if arg[0] == "check" { // 数字验签 + m.Cmd(arg) - "share": &ctx.Command{Name: "share [serve.route] role client.route...", Help: "共享权限", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmd("aaa.auth", "apply").Table(func(node map[string]string) { - m.Cmd("aaa.auth", node["key"], "session", "apply").Table(func(sess map[string]string) { - m.Cmd("aaa.auth", sess["key"], "username").Table(func(user map[string]string) { - m.Add("append", "time", sess["create_time"]) - m.Add("append", "user", user["meta"]) - m.Add("append", "node", node["meta"]) - }) - }) - }) - m.Table() - return - } + } else if m.Options("remote_code") { // 远程调用 + m.Cmd("action", arg) - // 本地用户 - if len(arg) == 2 { - m.Option("user.route", arg[1]) - m.Cmd("ssh.remote", "", "share", arg[1:]) - return - } - - // 远程用户 - m.Option("user.sign", "yes") - m.Cmd("ssh.remote", arg[0], "sync", "share", arg[1:]) - return - }}, - "proxy": &ctx.Command{Name: "proxy [proxy.route]", Help: "代理节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("aaa.auth", "proxy") - return - } - if !m.Cmds("aaa.auth", "proxy", arg[0], "session") { - m.Cmdy("aaa.sess", "proxy", "proxy", arg[0]) - } - return - }}, - "login": &ctx.Command{Name: "login client.route", Help: "用户节点", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmd("aaa.auth", "login") - return - } - - if !m.Cmds("ssh.remote", arg[0], "login") { - m.Echo("error: ").Echo("login failure") - return - } - - sess := m.Cmd("aaa.auth", "username", m.Option("username"), "session", "login").Append("key") - if sess == "" { - sess = m.Cmdx("aaa.sess", "login", "username", m.Option("username")) - } - - m.Cmd("aaa.auth", sess, "login", arg[0]) - m.Echo(sess) - return - }}, - - "sh": &ctx.Command{Name: "sh [[node] name] cmd...", Help: "发送命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmdy("ssh.remote") - return - } - - if arg[0] == "sub" { - m.Confm("node", func(name string, node map[string]interface{}) { - if node["type"] == "master" { - return - } - msg := m.Cmd("ssh.remote", name, arg[1:]) - if len(msg.Meta["append"]) > 0 && !msg.Has("node") { - line := len(msg.Meta[msg.Meta["append"][0]]) - for i := 0; i < line; i++ { - msg.Add("append", "node", m.Conf("runtime", "node.route")+"."+name) - } - msg.Set("result").Table() - } - m.CopyFuck(msg, "append") - m.CopyFuck(msg, "result") - return - }) - return - } - - if arg[0] == "node" { - m.Conf("current", arg[1]) - arg = arg[2:] - } else if m.Confm("node", arg[0]) != nil { - m.Conf("current", arg[0]) - arg = arg[1:] - } else { - m.Confm("node", func(name string, node map[string]interface{}) bool { - if strings.Contains(name, arg[0]) { - m.Conf("current", name) - arg = arg[1:] - return true - } - return false - }) - } - - msg := m.Cmd("ssh.remote", m.Conf("current"), arg) - m.Copy(msg, "append") - m.Copy(msg, "result") - return - }}, - "cp": &ctx.Command{Name: "cp [[node] name] filename", Help: "发送文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Echo(m.Conf("current")) - return - } - - if arg[0] == "node" { - m.Conf("current", arg[1]) - arg = arg[2:] - } else if m.Confm("node", arg[0]) != nil { - m.Conf("current", arg[0]) - arg = arg[1:] - } - - if arg[0] == "save" { - buf, e := base64.StdEncoding.DecodeString(m.Option("filebuf")) - m.Assert(e) - - f, e := os.OpenFile(path.Join("tmp", m.Option("filename")), os.O_RDWR|os.O_CREATE, 0666) - f.WriteAt(buf, int64(m.Optioni("filepos"))) - return e - } - - p := m.Cmdx("nfs.path", arg[0]) - f, e := os.Open(p) - m.Assert(e) - s, e := f.Stat() - m.Assert(e) - - buf := make([]byte, 1024) - - for i := int64(0); i < s.Size(); i += 1024 { - n, _ := f.ReadAt(buf, i) - if n == 0 { - break + } else { // 本地调用 + m.Cmdm(arg) } - - buf = buf[:n] - msg := m.Spawn() - msg.Option("filename", arg[0]) - msg.Option("filesize", s.Size()) - msg.Option("filepos", i) - msg.Option("filebuf", base64.StdEncoding.EncodeToString(buf)) - msg.Cmd("remote", m.Conf("current"), "cp", "save", arg[0]) } return }}, diff --git a/src/contexts/tcp/tcp_test.go b/src/contexts/tcp/tcp_test.go deleted file mode 100644 index 3695d9e3..00000000 --- a/src/contexts/tcp/tcp_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package tcp - -import ( - "context" - "flag" - "testing" - "time" -) - -func TestOpen(t *testing.T) { - flag.Parse() - args := flag.Args() - if len(args) < 1 { - t.Fatal("usages: -args address") - } - - address := ":9393" - address = args[0] - - //mysql -u root -p; - //create database book; - //grant all on book.* to user identified by 'word' - - ctx.Start() - m := ctx.Pulse.Spawn(Index) - - m.Meta = nil - Index.Cmd(m, "listen", address) -} diff --git a/src/toolkit/kit.go b/src/toolkit/kit.go index e03c7c7f..b1866230 100644 --- a/src/toolkit/kit.go +++ b/src/toolkit/kit.go @@ -643,6 +643,10 @@ func Hash(arg ...interface{}) (string, []string) { h := md5.Sum([]byte(strings.Join(args, ""))) return hex.EncodeToString(h[:]), args } +func Hashs(arg ...interface{}) string { + h, _ := Hash(arg...) + return h +} func Block(root interface{}, args ...interface{}) interface{} { diff --git a/usr/wiki/自然/编程/终端工具链/context.md b/usr/wiki/自然/编程/终端工具链/context.md index 0d3972e4..a2e22482 100644 --- a/usr/wiki/自然/编程/终端工具链/context.md +++ b/usr/wiki/自然/编程/终端工具链/context.md @@ -373,6 +373,12 @@ chat模块提供了信息管理。 ### 通信框架 #### 节点路由 #### 节点认证 + +- text.hash +- node.sign +- user.sign +- work.name + #### 节点服务 ### 存储引擎 #### 配置