From c0c9f26fe2afbf32814aa5983ada7644291a89ed Mon Sep 17 00:00:00 2001 From: shaoying Date: Sat, 27 Jul 2019 09:26:38 +0800 Subject: [PATCH] opt aaa --- bin/boot.sh | 2 + src/contexts/aaa/aaa.go | 1059 ++++++++++++++++------------------- src/contexts/cli/version.go | 2 +- src/contexts/ssh/ssh.go | 26 +- src/toolkit/core.go | 11 - 5 files changed, 502 insertions(+), 598 deletions(-) diff --git a/bin/boot.sh b/bin/boot.sh index 1ff28757..35409212 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -9,6 +9,8 @@ ctx_bin=${ctx_app} && [ -f bin/${ctx_app} ] && ctx_bin=$(pwd)/bin/${ctx_app} ctx_dev=${ctx_dev:="https://shylinux.com"} ctx_root=${ctx_root:=/usr/local/context} ctx_home=${ctx_home:=~/context} +# node_cert= +# node_key= # web_port= # ssh_port= # HOSTNAME= diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index e4255f48..8f844a6e 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -1,7 +1,11 @@ package aaa import ( + "gopkg.in/gomail.v2" + "contexts/ctx" + "toolkit" + "crypto" "crypto/aes" "crypto/cipher" @@ -15,14 +19,12 @@ import ( "encoding/json" "encoding/pem" "fmt" - "gopkg.in/gomail.v2" "io/ioutil" "math/big" "math/rand" "os" "strings" "time" - "toolkit" ) type AAA struct { @@ -35,46 +37,22 @@ type AAA struct { *ctx.Context } -func Auto(m *ctx.Message, arg ...string) { - msg := m.Spawn().Add("option", "bio.cmd", "").Cmd("auth", arg) - msg.Table(func(line int, maps map[string]string) { - m.Add("append", "value", maps["key"]) - m.Add("append", "name", fmt.Sprintf("%s: %s", maps["type"], maps["meta"])) - m.Add("append", "help", fmt.Sprintf("%s", maps["create_time"])) - }) -} - -func Password(pwd string) string { - bs := md5.Sum([]byte(fmt.Sprintln("password:%s", pwd))) - return hex.EncodeToString(bs[:]) -} func Input(stream string) []byte { if b, e := ioutil.ReadFile(stream); e == nil { return b } return []byte(stream) } -func (aaa *AAA) Decode(stream string) []byte { - buf, e := ioutil.ReadFile(stream) - if e != nil { - buf = []byte(stream) - } - block, _ := pem.Decode(buf) +func Decode(stream string) []byte { + block, _ := pem.Decode(Input(stream)) return block.Bytes } +func Password(pwd string) string { + bs := md5.Sum([]byte(fmt.Sprintln("password:%s", pwd))) + return hex.EncodeToString(bs[:]) +} func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { - now := time.Now().Unix() - c.Caches = map[string]*ctx.Cache{ - "method": &ctx.Cache{Name: "method", Value: arg[0], Help: "登录方式"}, - "sessid": &ctx.Cache{Name: "sessid", Value: "", Help: "会话令牌"}, - "login_time": &ctx.Cache{Name: "login_time", Value: fmt.Sprintf("%d", now), Help: "登录时间"}, - "expire_time": &ctx.Cache{Name: "expire_time", Value: fmt.Sprintf("%d", int64(m.Confi("expire"))+now), Help: "会话超时"}, - } - c.Configs = map[string]*ctx.Config{ - "right": &ctx.Config{Name: "right", Value: map[string]interface{}{}, Help: "用户权限"}, - } - return &AAA{Context: c} } func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { @@ -84,20 +62,20 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { stream := arg[1] switch arg[0] { case "cert": - cert, e := x509.ParseCertificate(aaa.Decode(stream)) + cert, e := x509.ParseCertificate(Decode(stream)) m.Assert(e) aaa.certificate = cert aaa.public = cert.PublicKey.(*rsa.PublicKey) stream = Password(stream) case "pub": - public, e := x509.ParsePKIXPublicKey(aaa.Decode(stream)) + public, e := x509.ParsePKIXPublicKey(Decode(stream)) m.Assert(e) aaa.public = public.(*rsa.PublicKey) stream = Password(stream) case "key": - private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(stream)) + private, e := x509.ParsePKCS1PrivateKey(Decode(stream)) m.Assert(e) aaa.private = private @@ -112,29 +90,23 @@ func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { } var Index = &ctx.Context{Name: "aaa", Help: "认证中心", - Caches: map[string]*ctx.Cache{ - "nuser": &ctx.Cache{Name: "nuser", Value: "0", Help: "用户数量"}, - }, + Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "hash": &ctx.Config{Name: "hash", Value: map[string]interface{}{}, Help: "散列"}, - "auth": &ctx.Config{Name: "auth", Value: map[string]interface{}{}, Help: "散列"}, - "auth_expire": &ctx.Config{Name: "auth_expire", Value: "10m", Help: "权限超时"}, + "hash": &ctx.Config{Name: "hash", Value: map[string]interface{}{}, Help: "散列"}, + "auth": &ctx.Config{Name: "auth", Value: map[string]interface{}{}, Help: "散列"}, "auth_type": &ctx.Config{Name: "auth_type", Value: map[string]interface{}{ - "unique": map[string]interface{}{"session": true, "bench": true, "relay": true}, + "unique": map[string]interface{}{"session": true, "relay": true}, "public": map[string]interface{}{"userrole": true, "username": true, "cert": true, "access": true}, "single": map[string]interface{}{"password": true, "token": true, "uuid": true, "ppid": true}, "secrete": map[string]interface{}{"password": true, "token": true, "uuid": true, "ppid": true}, }, Help: "散列"}, - "expire": &ctx.Config{Name: "expire(s)", Value: "72000", Help: "会话超时"}, "email": &ctx.Config{Name: "email", Value: map[string]interface{}{ - "self": "shylinux@163.com", - "smtp": "smtp.163.com", - "port": "25", - }, Help: "会话超时"}, + "self": "shylinux@163.com", "smtp": "smtp.163.com", "port": "25", + }, 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) { + "_init": &ctx.Command{Name: "_init", Help: "初始化", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { m.Conf("runtime", "node.cert", m.Cmdx("nfs.load", os.Getenv("node_cert"))) m.Conf("runtime", "node.key", m.Cmdx("nfs.load", os.Getenv("node_key"))) return @@ -151,9 +123,10 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Echo(hs) return }}, - "auth": &ctx.Command{Name: "auth [id] [delete data|ship|node] [[ship] type [meta]] [[data] key [val]] [[node] key [val]]", + "auth": &ctx.Command{Name: "auth [id|(key val)]... [node|ship|data] [check|delete] key [val]", Help: "权限区块链", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 节点列表 + // 节点列表 + if len(arg) == 0 { m.Confm("auth", func(key string, node map[string]interface{}) { up := false if ship, ok := node["ship"].(map[string]interface{}); ok { @@ -163,88 +136,82 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", case "0": if !up { up = true - m.Add("append", "up_key", k[:6]) - m.Add("append", "up_type", val["type"]) - // m.Add("append", "up_ship", val["ship"]) + m.Push("up_key", k[:8]) + m.Push("up_type", val["type"]) } } } } if !up { - m.Add("append", "up_key", "") - m.Add("append", "up_type", "") - // m.Add("append", "up_ship", "") + m.Push("up_key", "") + m.Push("up_type", "") } - m.Add("append", "key", key) - m.Add("append", "type", node["type"]) - m.Add("append", "meta", node["meta"]) + + m.Push("key", key) + m.Push("type", node["type"]) + m.Push("meta", node["meta"]) }) m.Sort("type").Table() return } - s, t, a := "", "", "" - if v := m.Confm("auth", arg[0]); v != nil { - s, t, a, arg = arg[0], kit.Format(v["type"]), kit.Format(v["meta"]), arg[1:] - } - if len(arg) == 0 { // 查看节点 - m.Echo(t) - return - } - - p, route, block, chain := s, "ship", []map[string]string{}, []map[string]string{} + p, t, a := "", "", "" + s, route, block, chain := "", "ship", []map[string]string{}, []map[string]string{} for i := 0; i < len(arg); i += 2 { + // 查找节点 if node := m.Confm("auth", arg[i]); node != nil { - if i++; p != "" { // 朋友链接 - expire := kit.Int(m.Time(m.Conf("auth_expire"), "stamp")) - m.Confv("auth", []string{arg[i-1], "ship", p}, map[string]interface{}{ - "create_time": m.Time(), "expire_time": expire, - "type": t, "meta": a, "ship": "5", - }) - m.Confv("auth", []string{p, "ship", arg[i-1]}, map[string]interface{}{ - "create_time": m.Time(), "expire_time": expire, - "type": node["type"], "meta": node["meta"], "ship": "4", - }) + // 切换节点 + p, t, a = arg[i], node["type"].(string), node["meta"].(string) + + // 一级节点 + if i++; s == "" { + s = p } - p, t, a = arg[i-1], node["type"].(string), node["meta"].(string) } + // 切换类型 if i < len(arg) { - switch arg[i] { // 切换类型 + switch arg[i] { case "data", "node", "ship": route, i = arg[i], i+1 } } + if p == "" && route != "ship" { return } switch route { - case "ship": // 链接操作 + // 链接操作 + case "ship": + // 节点列表 if i >= len(arg)-1 { - if p == "" { // 节点列表 + if p == "" { + // 所有节点 m.Confm("auth", func(k string, node map[string]interface{}) { if i > len(arg)-1 || node["type"].(string) == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { - m.Add("append", "create_time", node["create_time"]) - m.Add("append", "key", k) - m.Add("append", "type", node["type"]) - m.Add("append", "meta", node["meta"]) + m.Push("create_time", node["create_time"]) + m.Push("key", k) + m.Push("type", node["type"]) + m.Push("meta", node["meta"]) } }) - } else { // 链接列表 + } else { + // 添加关系 if i == len(arg)-1 { m.Confm("auth", []string{arg[i]}, func(node map[string]interface{}) { m.Confv("auth", []string{p, "ship", arg[i]}, node) }) } + // 关联节点 m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { if node := m.Confm("auth", k); i > len(arg)-1 || ship["type"].(string) == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { - m.Add("append", "create_time", node["create_time"]) - m.Add("append", "key", k) - m.Add("append", "ship", ship["ship"]) - m.Add("append", "type", node["type"]) - m.Add("append", "meta", node["meta"]) + m.Push("create_time", node["create_time"]) + m.Push("key", k) + m.Push("ship", ship["ship"]) + m.Push("type", node["type"]) + m.Push("meta", node["meta"]) } }) } @@ -286,8 +253,8 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", return } + // 节点哈希 meta := []string{arg[i]} - // 加密节点 if m.Confs("auth_type", []string{"secrete", arg[i]}) { meta = append(meta, Password(arg[i+1])) @@ -302,38 +269,43 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", meta = append(meta, p) } } + h := kit.Hashs(meta) - // h := m.Cmdx("aaa.hash", meta) - h, _ := kit.Hash(meta) + // 新的节点 if !m.Confs("auth", h) { - m.Set("result") - if m.Confs("auth_type", []string{"single", arg[i]}) && m.Confs("auth", p) && m.Cmds("aaa.auth", p, arg[i]) { + // 单点认证 + if m.Set("result"); m.Confs("auth_type", []string{"single", arg[i]}) && m.Confs("auth", p) && m.Cmds("aaa.auth", p, arg[i]) { m.Log("fuck", "password %s", h) - return // 单点认证失败 + // 认证失败 + return } // 创建节点 block = append(block, map[string]string{"hash": h, "type": arg[i], "meta": meta[1]}) - m.Echo(h) } - if s != "" { // 祖孙链接 + // 祖孙链接 + if s != "" { chain = append(chain, map[string]string{"node": s, "ship": "3", "hash": h, "type": arg[i], "meta": meta[1]}) chain = append(chain, map[string]string{"node": h, "ship": "2", "hash": s, "type": arg[i], "meta": meta[1]}) } - if p != "" { // 父子链接 + // 父子链接 + if p != "" { chain = append(chain, map[string]string{"node": p, "ship": "1", "hash": h, "type": arg[i], "meta": meta[1]}) chain = append(chain, map[string]string{"node": h, "ship": "0", "hash": p, "type": t, "meta": a}) } - + // 切换节点 p, t, a = h, arg[i], meta[1] m.Echo(h) - case "node": // 节点操作 - if i > len(arg)-1 { // 查看节点 - m.Set("result") - m.Cmdy("aaa.config", "auth", p) - return - } else if arg[i] == "delete" { // 删除节点 + + // 节点操作 + case "node": + if i > len(arg)-1 { + // 查看节点 + m.Set("result").Cmdy("aaa.config", "auth", p) + + } else if arg[i] == "delete" { + // 删除节点 m.Confm("auth", []string{p, "ship"}, func(ship map[string]interface{}) { for k, _ := range ship { m.Confm("auth", []string{k, "ship"}, func(peer map[string]interface{}) { @@ -346,9 +318,14 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Log("info", "delete node %s %s", s, kit.Formats(m.Confm("auth", s))) delete(m.Confm("auth"), s) }) - } else if i < len(arg)-1 { // 修改属性 + + } else if i < len(arg)-1 { + // 修改属性 m.Confv("auth", []string{p, arg[i]}, arg[i+1]) - } else { // 搜索属性 + break + + } else { + // 搜索属性 ps := []string{p} for j := 0; j < len(ps); j++ { if value := m.Confv("auth", []string{ps[j], arg[i]}); value != nil { @@ -363,29 +340,38 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } } return - case "data": // 数据操作 - if i > len(arg)-1 { // 查看数据 - m.Set("result").Cmdy("ctx.config", "auth", strings.Join([]string{p, "data"}, ".")) - return - } else if i == len(arg)-1 { // 查看数据 - m.Set("result").Cmdy("ctx.config", "auth", strings.Join([]string{p, "data", arg[i]}, ".")) - return - } else if arg[i] == "delete" { // 删除数据 + + // 数据操作 + case "data": + if i > len(arg)-1 { + // 查看数据 + m.Set("result").Echo(m.Conf("auth", strings.Join([]string{p, "data"}, "."))) + + } else if i == len(arg)-1 { + // 查看数据 + m.Set("result").Echo(m.Conf("auth", strings.Join([]string{p, "data", arg[i]}, "."))) + + } else if arg[i] == "delete" { + // 删除数据 m.Confm("auth", []string{s, "data"}, func(data map[string]interface{}) { for _, k := range arg[i+1:] { m.Log("info", "delete data %s %s %s", s, k, kit.Formats(data[k])) delete(data, k) } }) - } else if i < len(arg)-1 { // 修改数据 - m.Set("result") - if arg[i] == "option" { + + } else if i < len(arg)-1 { + // 修改数据 + if m.Set("result"); arg[i] == "option" { m.Confv("auth", []string{p, "data", arg[i+1]}, m.Optionv(arg[i+1])) } else { m.Confv("auth", []string{p, "data", arg[i]}, arg[i+1]) } m.Echo(arg[i+1]) - } else { // 搜索数据 + break + + } else { + // 搜索数据 ps := []string{p} for j := 0; j < len(ps); j++ { if value := m.Confv("auth", []string{ps[j], "data", arg[i]}); value != nil { @@ -399,32 +385,41 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }) } } - break + return } } - m.Log("debug", "block: %v chain: %v", len(block), len(chain)) - for _, b := range block { // 添加节点 + // 添加节点 + for _, b := range block { m.Confv("auth", b["hash"], map[string]interface{}{"create_time": m.Time(), "type": b["type"], "meta": b["meta"]}) } - for _, c := range chain { // 添加链接 + // 添加链接 + for _, c := range chain { m.Confv("auth", []interface{}{c["node"], "ship", c["hash"]}, map[string]interface{}{"ship": c["ship"], "type": c["type"], "meta": c["meta"]}) } + m.Log("debug", "block: %v chain: %v", len(block), len(chain)) return }}, - "role": &ctx.Command{Name: "role [name [componet [name [command [name]]]]|[user [name [password|uuid code]]]]", - Help: "用户角色, componet: 组件管理, user: 用户管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 角色列表 + "role": &ctx.Command{Name: "role [name [componet [name [command [name]]]]|[check [componet [command]]]|[user [name [password|cert|uuid code]]]]", + Help: []string{"用户角色, name", + "权限管理, componet [name [command name]]", + "权限检查, check [componet [command]]", + "用户管理, user [name [password|cert|uuid code]]", + }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 角色列表 + if len(arg) == 0 { m.Cmdy("aaa.auth", "ship", "userrole") return } - role, arg := arg[0], arg[1:] + role, arg := kit.Select("void", arg[0]), arg[1:] switch arg[0] { + // 权限管理 case "componet", "command": + // 解析参数 componets, commands := []string{}, []string{} - for i := 0; i < len(arg); i++ { // 解析参数 + for i := 0; i < len(arg); i++ { if arg[i] == "command" { for i = i + 1; i < len(arg); i++ { if arg[i] == "componet" { @@ -441,29 +436,55 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } m.Log("info", "componet: %v, command: %v", componets, commands) - if len(componets) == 0 { // 查看组件 + // 组件列表 + if len(componets) == 0 { m.Cmdy("aaa.auth", "ship", "userrole", role, "componet") return } + for i := 0; i < len(componets); i++ { - if len(commands) == 0 { // 查看命令 + // 命令列表 + if len(commands) == 0 { m.Cmdy("aaa.auth", "ship", "userrole", role, "componet", componets[i], "command") continue } - for j := 0; j < len(commands); j++ { // 添加命令 + // 添加命令 + for j := 0; j < len(commands); j++ { m.Cmd("aaa.auth", "ship", "userrole", role, "componet", componets[i], "command", commands[j]) } } + // 检查权限 + case "check": + if role == "root" { + // 超级权限 + m.Echo("true") + } else if len(arg) == 1 { + + } else if m.Cmds("aaa.auth", "userrole", role, "check", "componet", arg[1]) { + // 组件权限 + m.Echo("true") + } else if len(arg) == 2 { + + } else if m.Cmds("aaa.auth", "userrole", role, "componet", arg[1], "check", "command", arg[2]) { + // 命令权限 + m.Echo("true") + } + + // 用户管理 case "user": - if len(arg) == 1 { // 查看用户 + // 用户列表 + if len(arg) == 1 { m.Cmdy("aaa.auth", "ship", "userrole", role, "username") break } - for i := 1; i < len(arg); i++ { // 添加用户 + + // 添加用户 + 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", "cert": + case "password", "cert", "uuid": + // 添加认证 m.Cmd("aaa.auth", "ship", "username", arg[i], arg[i+1], arg[i+2]) i += 2 } @@ -472,275 +493,139 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } return }}, - "user": &ctx.Command{Name: "user cookie [role]|[login [password|uuid [code]]]|[service [name [value]]]|[session [select|create]]", - Help: "用户认证, cookie: cookie管理, session: 会话管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 查看用户 - m.Cmdy("aaa.auth", "ship", "username") + "user": &ctx.Command{Name: "user role|login|cookie|session|key", Help: []string{"用户管理", + "role: 查看角色", + "login [password|cert|uuid [code]]: 用户登录", + "cookie [spide [key [value]]]: 读写缓存", + "session [select|create [meta]]: 会话管理", + "key [value]: 用户数据", + }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 用户列表 + if len(arg) == 0 { + m.Cmdy("aaa.auth", "ship", "username") + return + } + + switch arg[0] { + // 角色列表 + case "role": + m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "userrole") + + // 用户登录 + case "login": + m.Cmdy("aaa.auth", "username", m.Option("username"), arg[1], arg[2]) + + case "cookie": + // 设置缓存 + if len(arg) > 3 { + m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg[:3], "."), arg[3]) + arg = arg[:3] + } + + // 查看缓存 + m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg, ".")) + + case "session": + // 查看会话 + if len(arg) == 1 { + m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session") return } - switch arg[0] { - case "role": // 用户角色 - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "userrole") + switch arg[1] { + case "select": + defer func() { m.Log("info", "sessid: %s", m.Result(0)) }() - case "login": // 用户登录 - m.Cmdy("aaa.auth", "username", m.Option("username"), arg[1], arg[2]) - - case "cookie": - if len(arg) > 3 { // 设置cookie - m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg[:3], "."), arg[3]) - arg = arg[:3] - } - - // 查看cookie - m.Cmdy("aaa.auth", "username", m.Option("username"), "data", strings.Join(arg, ".")) - case "session": - if len(arg) == 1 { // 查看会话 - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session") + // 检查会话 + if m.Options("sessid") && m.Cmds("aaa.auth", "ship", "username", m.Option("username"), "check", m.Option("sessid")) { + m.Echo(m.Option("sessid")) return } - - switch arg[1] { - case "select": // 选择会话 - defer func() { m.Log("info", "sessid: %s", m.Result(0)) }() - - if m.Options("sessid") && m.Cmds("aaa.auth", "ship", "username", m.Option("username"), "check", m.Option("sessid")) { - m.Echo(m.Option("sessid")) - return - } - if m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session"); m.Appends("key") { - m.Set("result").Echo(m.Append("key")) - return - } - fallthrough - case "create": // 创建会话 - m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session", kit.Select("web", arg, 2)) - m.Cmd("aaa.auth", m.Result(0), "data", "current.ctx", "mdb") + // 选择会话 + if m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session"); m.Appends("key") { + m.Set("result").Echo(m.Append("key")) + return } - default: - m.Option("format", "object") - m.Cmdy("aaa.auth", "username", arg[0], "data") + fallthrough + case "create": + // 创建会话 + m.Cmdy("aaa.auth", "ship", "username", m.Option("username"), "session", kit.Select("web", arg, 2)) + m.Cmd("aaa.auth", m.Result(0), "data", "current.ctx", "mdb") } + default: + // 读写数据 + m.Option("format", "object") + m.Cmdy("aaa.auth", "username", m.Option("username"), "data", arg) + } + return + }}, + "sess": &ctx.Command{Name: "sess [sid] [user|access|key [val]]", Help: "会话管理, user: 用户列表, access: 访问管理, key [val]: 读写数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 会话列表 + if len(arg) == 0 { + m.Cmdy("aaa.auth", "ship", "session") return - }}, - "sess": &ctx.Command{Name: "sess [sessid] [current [pod|ctx|dir|env [value]]]|[bench [select|create]]", - Help: "会话管理, current: 指针管理, bench: 空间管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 会话列表 - m.Cmdy("aaa.auth", "ship", "session") - return - } + } - sid := m.Option("sessid") - if m.Conf("auth", []string{arg[0], "type"}) == "session" { - sid, arg = arg[0], arg[1:] - } - if len(arg) == 0 { + // 查找会话 + sid := m.Option("sessid") + if m.Conf("auth", []string{arg[0], "type"}) == "session" { + if sid, arg = arg[0], arg[1:]; len(arg) == 0 { m.Echo(sid) return } - - switch arg[0] { - case "access": // 查看用户 - h := m.Cmdx("aaa.auth", "access", kit.Hashs(m.Option("remote_ip"), m.Option("username"))) - m.Cmd("aaa.auth", h, "data", "remote_ip", m.Option("remote_ip"), "username", m.Option("username")) - m.Echo(h) - return - - case "user": // 查看用户 - m.Cmdy("aaa.auth", sid, "ship", "username") - - case "current": - if len(arg) > 2 { // 设置指针 - m.Cmd("aaa.auth", sid, "data", strings.Join(arg[:2], "."), arg[2]) - arg = arg[:2] - } - - // 查看指针 - m.Cmdy("aaa.auth", sid, "data", strings.Join(arg, ".")) - - case "bench": - if len(arg) == 1 { // 查看空间 - m.Cmdy("aaa.auth", m.Option("sessid"), "ship", "bench") - return - } - - switch arg[1] { - case "select": // 选择空间 - defer func() { m.Log("info", "bench: %s", m.Result(0)) }() - - if m.Options("bench") && m.Cmds("aaa.auth", m.Option("sessid"), "ship", "check", m.Option("bench")) { - m.Echo(m.Option("bench")) - return - } - if m.Cmdy("aaa.auth", m.Option("sessid"), "ship", "bench"); m.Appends("key") { - m.Set("result").Echo(m.Append("key")) - return - } - fallthrough - case "create": // 创建空间 - m.Cmdy("aaa.auth", m.Option("sessid"), "ship", "bench", kit.Select("web", arg, 2)) - m.Cmd("aaa.auth", m.Result(0), "data", "name", "web") - } - } - return - }}, - "work": &ctx.Command{Name: "work [benchid] [sesion]|[delete]|[rename name]|[share public|protect|private][data arg...]|[right [componet [command [argument]]]]", - Help: []string{"工作空间", - "session: 查看会话", - "delete: 删除空间", - "rename [name]: 命名空间", - "share [public|protect|private]: 共享空间", - "data arg...: 读写数据", - "right [componet [command [arguments]]]: 权限检查", - }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 空间列表 - m.Cmdy("aaa.auth", "ship", "bench") - return - } - - bid := m.Option("bench") - if m.Conf("auth", []string{arg[0], "type"}) == "bench" { - bid, arg = arg[0], arg[1:] - } - if len(arg) == 0 { - m.Echo(bid) - return - } - - switch arg[0] { - case "session": // 查看会话 - m.Cmdy("aaa.auth", bid, "ship", "session") - - case "delete": // 删除空间 - m.Cmdy("aaa.auth", bid, "delete", "node") - - case "rename": // 命名空间 - if len(arg) > 1 { - m.Cmd("aaa.auth", bid, "data", "name", arg[1]) - } - m.Cmdy("aaa.auth", bid, "data", "name") - - case "share": // 共享空间 - if len(arg) > 1 { - m.Cmdy("aaa.auth", bid, "data", "share", arg[1]) - } - m.Cmdy("aaa.auth", bid, "data", "share") - - case "data": // 读写数据 - m.Cmdy("aaa.auth", bid, arg) - - case "right": - if len(arg) == 1 { // 查看权限 - m.Cmd("aaa.auth", m.Option("bench"), "ship", "componet").CopyTo(m, "append") - m.Cmd("aaa.auth", m.Option("bench"), "ship", "command").CopyTo(m, "append") - m.Table() - break - } - - // 检查权限 - for _, role := range kit.Trans(m.Option("userrole"), m.Cmd("aaa.auth", "ship", "username", m.Option("username"), "userrole").Appendv("meta")) { - if role == "" { - continue - } - if role == "root" { // 超级用户 - - } else if len(arg) > 2 { // 接口权限 - if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[2]) { - - } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", role, "componet", arg[1], "check", arg[2]); kit.Right(cid) { - m.Cmd("aaa.auth", m.Option("bench"), cid) - } else { - continue // 失败 - } - } else if len(arg) > 1 { // 组件权限 - if m.Cmds("aaa.auth", m.Option("bench"), "ship", "check", arg[1]) { - - } else if cid := m.Cmdx("aaa.auth", "ship", "userrole", role, "check", arg[1]); kit.Right(cid) { - m.Cmd("aaa.auth", m.Option("bench"), cid) - } else { - continue // 失败 - } - } - - m.Log("info", "role: %s %v", role, arg[1:]) - m.Echo(role) - break - } - - m.Log("right", "bench: %s sessid: %s user: %s com: %v result: %v", - m.Option("bench"), m.Option("sessid"), m.Option("username"), arg[2:], m.Result(0)) - } - return - }}, - - "clip": &ctx.Command{Name: "clip", Help: "授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - h := m.Cmdx("aaa.auth", "username", m.Option("username")) - - if len(arg) == 0 { // 会话列表 - m.Cmdy("aaa.config", "auth", h+".data.clip") - return } switch arg[0] { - case "clear": - m.Conf("auth", []string{h, "data", "clip"}, []interface{}{}) + // 查看用户 + case "user": + m.Cmdy("aaa.auth", sid, "ship", "username") + + case "access": + // 查看访问 + if len(arg) == 1 { + m.Cmdy("aaa.auth", sid, "access") + break + } + // 添加访问 + if sid != "" { + m.Cmdy("aaa.auth", sid, "access", arg[1]) + } + // 查看会话 + if len(arg) == 2 { + m.Cmdy("aaa.auth", "access", arg[1], "ship", "session") + break + } + // 读写数据 + m.Cmdy("aaa.auth", "access", arg[1], "data", arg[2:]) + default: - m.Conf("auth", []string{h, "data", "clip", kit.Select("-2", arg, 1)}, arg[0]) - m.Echo("%d", len(m.Confv("auth", []string{h, "data", "clip"}).([]interface{}))-1) - } - return - }}, - "location": &ctx.Command{Name: "clip", Help: "授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - h := m.Cmdx("aaa.auth", "username", m.Option("username")) - - if len(arg) < 2 { // 会话列表 - m.Confm("auth", []string{h, "data", "location"}, func(index int, value map[string]interface{}) { - m.Add("append", "create_time", value["create_time"]) - m.Add("append", "location", value["location"]) - m.Add("append", "latitude", value["latitude"]) - m.Add("append", "longitude", value["longitude"]) - }) - m.Table() - return - } - - switch arg[0] { - default: - m.Conf("auth", []string{h, "data", "location", "-2"}, map[string]interface{}{ - "create_time": m.Time(), - "latitude": arg[0], "longitude": arg[1], - "location": kit.Select("", arg, 2), - }) - m.Echo("%d", len(m.Confv("auth", []string{h, "data", "location"}).([]interface{}))-1) + // 读写数据 + m.Option("format", "object") + m.Cmdy("aaa.auth", sid, "data", arg) } return }}, - "email": &ctx.Command{Name: "email", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - msg := gomail.NewMessage() - msg.SetHeader("From", m.Conf("email", "self")) - msg.SetHeader("To", arg[0]) - msg.SetHeader("Subject", arg[1]) - msg.SetBody("text/html", strings.Join(arg[2:], "")) - d := gomail.NewDialer(m.Conf("email", "smtp"), kit.Int(m.Conf("email", "port")), m.Conf("email", "self"), m.Conf("email", "code")) - if e := d.DialAndSend(msg); e != nil { - m.Echo("%v", e) - } else { - m.Echo("success") - } - return - }}, - - "relay": &ctx.Command{Name: "relay check hash | share role", Help: "授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { // 会话列表 + "relay": &ctx.Command{Name: "relay [rid] [check userrole]|[count num]|[share [type [role [name [count]]]]]", Help: "授权", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 授权列表 + if len(arg) == 0 { m.Cmdy("aaa.auth", "relay") return } + rid := m.Option("relay") + if m.Confm("auth", arg[0]) != nil { + if rid, arg = arg[0], arg[1:]; len(arg) == 0 { + m.Echo(rid) + return + } + } + switch arg[0] { + // 检查授权 case "check": - if relay := m.Confm("auth", []string{arg[1], "data"}); relay != nil { - if kit.Select("", arg, 2) == "userrole" && kit.Int(relay["count"]) > 0 { + if relay := m.Confm("auth", []string{rid, "data"}); relay != nil { + if kit.Select("", arg, 1) == "userrole" && kit.Int(relay["count"]) > 0 { relay["count"] = kit.Int(relay["count"]) - 1 m.Echo("%s", relay["userrole"]) } @@ -748,51 +633,84 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Append(k, v) } } + + // 分享权限 case "share": - m.Echo(m.Cmd("aaa.auth", "relay", "right").Result(0)) - m.Conf("auth", []string{m.Result(0), "data"}, map[string]interface{}{ - "userrole": kit.Select("tech", arg, 1), - "username": kit.Select("", arg, 2), - "count": kit.Select("1", arg, 3), - }) - case "count": if len(arg) == 1 { - m.Cmdy("aaa.auth", "relay") - return + m.Cmdy("aaa.auth", "username", m.Option("username"), "relay") + break } - m.Conf("auth", []string{arg[1], "data", "count"}, kit.Select("1", arg, 2)) - m.Cmdy("ctx.config", "auth", arg[1]) + m.Cmdy("aaa.auth", "username", m.Option("username"), "relay", arg[1], "data", + "userrole", kit.Select("tech", arg, 2), + "username", kit.Select("", arg, 3), + "count", kit.Select("1", arg, 4), + ) + + // 授权计数 + case "count": + m.Cmdy("aaa.auth", rid, "data", "count", kit.Select("1", arg, 1)) + default: - m.Cmdy("ctx.config", "auth", arg[0]) + m.Cmdy("aaa.auth", rid, "data", arg) } return }}, - "login": &ctx.Command{Name: "login nodesess", Help: "登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if len(arg) == 0 { - m.Cmd("aaa.auth", "username", m.Option("username"), "session", "nodes").Table(func(sess map[string]string) { - m.Cmd("aaa.auth", sess["key"], "nodes").Table(func(node map[string]string) { - m.Add("append", "key", node["key"]) - m.Add("append", "meta", node["meta"]) - }) + "email": &ctx.Command{Name: "email name title content", Help: "发送邮件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + msg := gomail.NewMessage() + msg.SetHeader("From", m.Conf("email", "self")) + msg.SetHeader("To", arg[0]) + msg.SetHeader("Subject", arg[1]) + msg.SetBody("text/html", strings.Join(arg[2:], "")) + m.Assert(gomail.NewDialer(m.Conf("email", "smtp"), kit.Int(m.Conf("email", "port")), m.Conf("email", "self"), m.Conf("email", "code")).DialAndSend(msg)) + m.Echo("success") + return + }}, + "location": &ctx.Command{Name: "location [latitude [longitude [location]]]", Help: "地理位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + h := m.Cmdx("aaa.auth", "username", m.Option("username")) + + // 位置列表 + if len(arg) < 2 { + m.Confm("auth", []string{h, "data", "location"}, func(index int, value map[string]interface{}) { + m.Push("create_time", value["create_time"]) + m.Push("index", index) + m.Push("location", value["location"]) + m.Push("latitude", value["latitude"]) + m.Push("longitude", value["longitude"]) }) m.Table() return } - m.Cmd("aaa.auth", arg[0], "username", m.Option("username")) + + switch arg[0] { + // 添加位置 + default: + m.Conf("auth", []string{h, "data", "location", "-2"}, map[string]interface{}{ + "create_time": m.Time(), + "location": kit.Select("", arg, 2), + "latitude": arg[0], "longitude": arg[1], + }) + m.Echo("%d", len(m.Confv("auth", []string{h, "data", "location"}).([]interface{}))-1) + } return }}, - "share": &ctx.Command{Name: "share nodesess", Help: "共享", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "clip": &ctx.Command{Name: "clip", Help: "粘贴板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + // 文本列表 + h := m.Cmdx("aaa.auth", "username", m.Option("username")) if len(arg) == 0 { - m.Cmd("aaa.auth", "username", m.Option("username"), "session", "nodes").Table(func(sess map[string]string) { - m.Cmd("aaa.auth", sess["key"], "nodes").Table(func(node map[string]string) { - m.Add("key", node["key"]) - m.Add("meta", node["meta"]) - }) - }) - m.Table() + m.Cmdy("aaa.config", "auth", h+".data.clip") return } - m.Cmd("aaa.auth", arg[0], "username", m.Option("username")) + + switch arg[0] { + // 清空列表 + case "clear": + m.Conf("auth", []string{h, "data", "clip"}, []interface{}{}) + + // 添加文本 + default: + m.Conf("auth", []string{h, "data", "clip", kit.Select("-2", arg, 1)}, arg[0]) + m.Echo("%d", len(m.Confv("auth", []string{h, "data", "clip"}).([]interface{}))-1) + } return }}, @@ -804,169 +722,175 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "解密: rsa decrypt key content [defile]", "签名: rsa sign key content [signfile]", "验签: rsa verify pub content", - }, - Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { - switch arg[0] { - case "gen": - // 生成私钥 - keys, e := rsa.GenerateKey(crand.Reader, 1024) + }, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch arg[0] { + case "gen": + // 生成私钥 + keys, e := rsa.GenerateKey(crand.Reader, 1024) + m.Assert(e) + + private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(keys)})) + m.Echo(m.Append("private", private)) + + // 生成公钥 + pub, e := x509.MarshalPKIXPublicKey(&keys.PublicKey) + m.Assert(e) + + public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub})) + m.Echo(m.Append("public", public)) + + common := map[string]interface{}{} + for i := 0; i < len(m.Meta["common"]); i += 2 { + kit.Chain(common, m.Meta["common"][i], m.Meta["common"][i+1]) + } + + // 生成证书 + template := x509.Certificate{ + SerialNumber: big.NewInt(1), + IsCA: true, + BasicConstraintsValid: true, + KeyUsage: x509.KeyUsageCertSign, + Subject: pkix.Name{CommonName: kit.Format(common)}, + } + cert, e := x509.CreateCertificate(crand.Reader, &template, &template, &keys.PublicKey, keys) + m.Assert(e) + + certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})) + m.Echo(m.Append("certificate", certificate)) + + // 输出文件 + if len(arg) > 1 { + ioutil.WriteFile(arg[1], []byte(private), 0666) + } + if len(arg) > 2 { + ioutil.WriteFile(arg[2], []byte(public), 0666) + } + if len(arg) > 3 { + ioutil.WriteFile(arg[3], []byte(certificate), 0666) + } + case "sign": + private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) + m.Assert(e) + + h := md5.Sum(Input(arg[2])) + b, e := rsa.SignPKCS1v15(crand.Reader, private, crypto.MD5, h[:]) + m.Assert(e) + + res := base64.StdEncoding.EncodeToString(b) + if m.Echo(res); len(arg) > 3 { + ioutil.WriteFile(arg[3], []byte(res), 0666) + } + case "verify": + public, e := x509.ParsePKIXPublicKey(Decode(arg[1])) + if e != nil { + cert, e := x509.ParseCertificate(Decode(arg[1])) + m.Assert(e) + public = cert.PublicKey + } + + buf := make([]byte, 1024) + n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) + m.Assert(e) + buf = buf[:n] + + h := md5.Sum(Input(arg[3])) + m.Echo("%t", rsa.VerifyPKCS1v15(public.(*rsa.PublicKey), crypto.MD5, h[:], buf) == nil) + case "encrypt": + public, e := x509.ParsePKIXPublicKey(Decode(arg[1])) + m.Assert(e) + + b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), Input(arg[2])) + m.Assert(e) + + res := base64.StdEncoding.EncodeToString(b) + if m.Echo(res); len(arg) > 3 { + ioutil.WriteFile(arg[3], []byte(res), 0666) + } + case "decrypt": + private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) + m.Assert(e) + + buf := make([]byte, 1024) + n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) + m.Assert(e) + buf = buf[:n] + + b, e := rsa.DecryptPKCS1v15(crand.Reader, private, buf) + m.Assert(e) + + if m.Echo(string(b)); len(arg) > 3 { + ioutil.WriteFile(arg[3], b, 0666) + } + case "cert": + private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) + m.Assert(e) + + cert, e := x509.ParseCertificate(Decode(arg[2])) + m.Assert(e) + + public, e := x509.ParsePKIXPublicKey(Decode(arg[3])) + m.Assert(e) + + template := &x509.Certificate{ + SerialNumber: big.NewInt(rand.Int63()), + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(1, 0, 0), + } + buf, e := x509.CreateCertificate(crand.Reader, template, cert, public, private) + + certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: buf})) + if m.Echo(certificate); len(arg) > 4 { + ioutil.WriteFile(arg[4], []byte(certificate), 0666) + } + case "info": + cert, e := x509.ParseCertificate(Decode(arg[1])) + m.Assert(e) + + var common interface{} + json.Unmarshal([]byte(cert.Subject.CommonName), &common) + m.Put("option", "common", common).Cmdy("ctx.trans", "common", "format", "object") + case "grant": + private, e := x509.ParsePKCS1PrivateKey(Decode(arg[1])) + m.Assert(e) + + parent, e := x509.ParseCertificate(Decode(arg[2])) + m.Assert(e) + + for _, v := range arg[3:] { + template, e := x509.ParseCertificate(Decode(v)) m.Assert(e) - private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(keys)})) - m.Echo(m.Append("private", private)) - - // 生成公钥 - pub, e := x509.MarshalPKIXPublicKey(&keys.PublicKey) - m.Assert(e) - - public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub})) - m.Echo(m.Append("public", public)) - - common := map[string]interface{}{} - for i := 0; i < len(m.Meta["common"]); i += 2 { - kit.Chain(common, m.Meta["common"][i], m.Meta["common"][i+1]) - } - - // 生成证书 - template := x509.Certificate{ - SerialNumber: big.NewInt(1), - IsCA: true, - BasicConstraintsValid: true, - KeyUsage: x509.KeyUsageCertSign, - Subject: pkix.Name{CommonName: kit.Format(common)}, - } - cert, e := x509.CreateCertificate(crand.Reader, &template, &template, &keys.PublicKey, keys) + cert, e := x509.CreateCertificate(crand.Reader, template, parent, template.PublicKey, private) m.Assert(e) certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})) - m.Echo(m.Append("certificate", certificate)) - - // 输出文件 - if len(arg) > 1 { - ioutil.WriteFile(arg[1], []byte(private), 0666) - } - if len(arg) > 2 { - ioutil.WriteFile(arg[2], []byte(public), 0666) - } - if len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(certificate), 0666) - } - case "sign": - private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(arg[1])) - m.Assert(e) - - h := md5.Sum(Input(arg[2])) - b, e := rsa.SignPKCS1v15(crand.Reader, private, crypto.MD5, h[:]) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(res), 0666) - } - case "verify": - public, e := x509.ParsePKIXPublicKey(aaa.Decode(arg[1])) - if e != nil { - cert, e := x509.ParseCertificate(aaa.Decode(arg[1])) - m.Assert(e) - public = cert.PublicKey - } - - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) - m.Assert(e) - buf = buf[:n] - - h := md5.Sum(Input(arg[3])) - m.Echo("%t", rsa.VerifyPKCS1v15(public.(*rsa.PublicKey), crypto.MD5, h[:], buf) == nil) - case "encrypt": - public, e := x509.ParsePKIXPublicKey(aaa.Decode(arg[1])) - m.Assert(e) - - b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), Input(arg[2])) - m.Assert(e) - - res := base64.StdEncoding.EncodeToString(b) - if m.Echo(res); len(arg) > 3 { - ioutil.WriteFile(arg[3], []byte(res), 0666) - } - case "decrypt": - private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(arg[1])) - m.Assert(e) - - buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) - m.Assert(e) - buf = buf[:n] - - b, e := rsa.DecryptPKCS1v15(crand.Reader, private, buf) - m.Assert(e) - - if m.Echo(string(b)); len(arg) > 3 { - ioutil.WriteFile(arg[3], b, 0666) - } - case "cert": - private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(arg[1])) - m.Assert(e) - - cert, e := x509.ParseCertificate(aaa.Decode(arg[2])) - m.Assert(e) - - public, e := x509.ParsePKIXPublicKey(aaa.Decode(arg[3])) - m.Assert(e) - - template := &x509.Certificate{ - SerialNumber: big.NewInt(rand.Int63()), - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(1, 0, 0), - } - buf, e := x509.CreateCertificate(crand.Reader, template, cert, public, private) - - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: buf})) - if m.Echo(certificate); len(arg) > 4 { - ioutil.WriteFile(arg[4], []byte(certificate), 0666) - } - case "info": - cert, e := x509.ParseCertificate(aaa.Decode(arg[1])) - m.Assert(e) - - var common interface{} - json.Unmarshal([]byte(cert.Subject.CommonName), &common) - m.Put("option", "common", common).Cmdy("ctx.trans", "common", "format", "object") - case "grant": - private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(arg[1])) - m.Assert(e) - - parent, e := x509.ParseCertificate(aaa.Decode(arg[2])) - m.Assert(e) - - for _, v := range arg[3:] { - template, e := x509.ParseCertificate(aaa.Decode(v)) - m.Assert(e) - - cert, e := x509.CreateCertificate(crand.Reader, template, parent, template.PublicKey, private) - m.Assert(e) - - certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})) - m.Echo(certificate) - } - case "check": - parent, e := x509.ParseCertificate(aaa.Decode(arg[1])) - m.Assert(e) - - for _, v := range arg[2:] { - template, e := x509.ParseCertificate(aaa.Decode(v)) - m.Assert(e) - - if e = template.CheckSignatureFrom(parent); e != nil { - m.Echo("error: ").Echo("%v", e) - } - } - m.Echo("true") + m.Echo(certificate) } + case "check": + parent, e := x509.ParseCertificate(Decode(arg[1])) + m.Assert(e) + + for _, v := range arg[2:] { + template, e := x509.ParseCertificate(Decode(v)) + m.Assert(e) + + if e = template.CheckSignatureFrom(parent); e != nil { + m.Echo("error: ").Echo("%v", e) + } + } + m.Echo("true") } return }}, + "keys": &ctx.Command{Name: "keys [filename]", Help: "导出私钥", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { + private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(aaa.private)})) + if m.Echo(private); len(arg) > 0 { + m.Assert(ioutil.WriteFile(arg[0], []byte(private), 0666)) + } + } + return + }}, "cert": &ctx.Command{Name: "cert [filename]", Help: "导出证书", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.certificate != nil { certificate := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: aaa.certificate.Raw})) @@ -987,15 +911,6 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } return }}, - "keys": &ctx.Command{Name: "keys [filename]", Help: "导出私钥", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { - private := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(aaa.private)})) - if m.Echo(private); len(arg) > 0 { - m.Assert(ioutil.WriteFile(arg[0], []byte(private), 0666)) - } - } - return - }}, "sign": &ctx.Command{Name: "sign content [signfile]", Help: "数字签名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { h := md5.Sum(Input(arg[0])) diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index dbe47f2a..75ee780d 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-07-27 05:58:32", "com", 218, + "2019-07-27 06:00:22", "mac", 219, } diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index 896e924a..55a3659e 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -1070,22 +1070,21 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", return }}, "_exec": &ctx.Command{Name: "_exec", Help: "命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - access := kit.Hashs( + access := m.Option("access", kit.Hashs( m.Option("node.route"), m.Option("user.route"), m.Option("work.route"), m.Option("work.name"), m.Option("user.name"), m.Option("text.username"), - ) + )) - if m.Option("sessid", m.Cmd("aaa.auth", "access", access, "session").Append("key")); m.Option("username", m.Cmd("aaa.sess", "user").Append("meta")) != "" { // 历史会话 + if m.Option("sessid", m.Cmd("aaa.auth", "access", access, "session").Append("key")) != "" && + m.Option("username", m.Cmd("aaa.sess", "user").Append("meta")) != "" { // 历史会话 m.Log("warn", "access: %s", access) m.Log("info", "sessid: %s", m.Option("sessid")) m.Option("trust", m.Cmdx("aaa.auth", "access", access, "data", "trust")) - if m.Option("userrole", m.Cmdx("aaa.auth", "access", access, "data", "userrole")); !m.Options("userrole") { - m.Option("userrole", m.Cmd("aaa.user", "role").Append("meta")) - } + m.Option("userrole", m.Cmdx("aaa.auth", "access", access, "data", "userrole")) } else if m.Option("username", m.Option("text.username")); !m.Confs("runtime", "user.route") && m.Confs("trust", "fresh") { // 免签节点 m.Log("warn", "trust fresh %s", m.Option("node.route")) @@ -1116,7 +1115,10 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", return } - m.Log("info", "username: %s", m.Option("username")) + // 用户角色 + if m.Log("info", "username: %s", m.Option("username")); !m.Options("userrole") { + m.Option("userrole", kit.Select("void", m.Cmd("aaa.user", "role").Append("meta"))) + } m.Log("info", "userrole: %s", m.Option("userrole")) // 创建会话 @@ -1127,13 +1129,9 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", } // 权限检查 - if arg[0] != "tool" { - // 创建空间 - 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 - } + if !m.Cmds("aaa.role", m.Option("userrole"), "check", "remote", arg[0]) { + m.Echo("no right %s %s", "remote", arg[0]) + return } // 执行命令 diff --git a/src/toolkit/core.go b/src/toolkit/core.go index 4e42c519..835c8808 100644 --- a/src/toolkit/core.go +++ b/src/toolkit/core.go @@ -4,7 +4,6 @@ import ( "crypto/md5" "encoding/hex" "fmt" - "io" "math/rand" "os" "path" @@ -79,16 +78,6 @@ func Hash(arg ...interface{}) (string, []string) { args = append(args, Format(time.Now())) args = append(args, Format(rand.Int())) default: - if s, e := os.Stat(v); e == nil && !s.IsDir() { - if f, e := os.Open(v); e == nil { - defer f.Close() - m := md5.New() - io.Copy(m, f) - h := m.Sum(nil) - args = append(args, hex.EncodeToString(h[:])) - return hex.EncodeToString(h[:]), args - } - } args = append(args, v) } }