diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 3b369f99..a91eef58 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -3,7 +3,19 @@ package aaa // {{{ import ( // {{{ "contexts" + "io" + "io/ioutil" + "os" + + "crypto" "crypto/md5" + + crand "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "encoding/hex" "math/rand" @@ -155,6 +167,148 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Echo(msg.Cap("sessid")) } // }}} }}, + "md5": &ctx.Command{Name: "md5 [content][file filename]", Help: "散列", + Formats: map[string]int{"file": 1}, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if m.Options("file") { // {{{ + f, e := os.Open(m.Option("file")) + m.Assert(e) + + h := md5.New() + io.Copy(h, f) + + m.Echo(hex.EncodeToString(h.Sum([]byte{})[:])) + } else if len(arg) > 0 { + h := md5.Sum([]byte(arg[0])) + m.Echo(hex.EncodeToString(h[:])) + } + // }}} + }}, + "rsa": &ctx.Command{Name: "rsa gen|encrypt|decrypt|sign|verify [key str][keyfile filename][signs str][signfile filename][file filename][mm str][mmfile filename] content", + Help: ` 密钥: rsa gen keyfile key.pem + 加密: rsa encrypt keyfile pubkey.pem mmfile mm.txt hello + 解密: rsa decrypt keyfile key.pem mmfile mm.txt + 签名: rsa sign keyfile key.pem signfile sign.txt hello + 验签: rsa verify keyfile pubkey.pem signfile sign.txt hello`, + Formats: map[string]int{"key": 1, "keyfile": 1, "signs": 1, "signfile": 1, "file": 1, "mm": 1, "mmfile": 1}, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if arg[0] == "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.Append("private", private) + m.Echo(private) + + pub, e := x509.MarshalPKIXPublicKey(&keys.PublicKey) + m.Assert(e) + + public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub})) + m.Append("public", public) + m.Echo(public) + + if m.Options("keyfile") { + ioutil.WriteFile(m.Option("keyfile"), []byte(private), 0666) + ioutil.WriteFile("pub"+m.Option("keyfile"), []byte(public), 0666) + } + return + } + + keys := []byte(m.Option("key")) + if m.Options("keyfile") { + b, e := ioutil.ReadFile(m.Option("keyfile")) + m.Assert(e) + keys = b + } + + block, e := pem.Decode(keys) + m.Assert(e) + + if arg[0] == "decrypt" { + private, e := x509.ParsePKCS1PrivateKey(block.Bytes) + m.Assert(e) + + mm := []byte(m.Option("mm")) + if m.Options("mmfile") { + b, e := ioutil.ReadFile(m.Option("mmfile")) + m.Assert(e) + mm = b + } + + buf := make([]byte, 1024) + n, e := base64.StdEncoding.Decode(buf, mm) + m.Assert(e) + buf = buf[:n] + + b, e := rsa.DecryptPKCS1v15(crand.Reader, private, buf) + m.Assert(e) + + m.Echo(string(b)) + if m.Options("file") { + ioutil.WriteFile(m.Option("file"), b, 0666) + } + return + } + + var content []byte + if m.Options("file") { + b, e := ioutil.ReadFile(m.Option("file")) + m.Assert(e) + content = b + } else if len(arg) > 1 { + content = []byte(arg[1]) + } + + switch arg[0] { + case "encrypt": + public, e := x509.ParsePKIXPublicKey(block.Bytes) + m.Assert(e) + + b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), content) + m.Assert(e) + + res := base64.StdEncoding.EncodeToString(b) + m.Echo(res) + if m.Options("mmfile") { + ioutil.WriteFile(m.Option("mmfile"), []byte(res), 0666) + } + + case "sign": + private, e := x509.ParsePKCS1PrivateKey(block.Bytes) + m.Assert(e) + + h := md5.Sum(content) + b, e := rsa.SignPKCS1v15(crand.Reader, private, crypto.MD5, h[:]) + m.Assert(e) + + res := base64.StdEncoding.EncodeToString(b) + m.Echo(res) + + if m.Options("signfile") { + ioutil.WriteFile(m.Option("signfile"), []byte(res), 0666) + } + + case "verify": + public, e := x509.ParsePKIXPublicKey(block.Bytes) + m.Assert(e) + + sign := []byte(m.Option("sign")) + if m.Options("signfile") { + b, e := ioutil.ReadFile(m.Option("signfile")) + m.Assert(e) + sign = b + } + + buf := make([]byte, 1024) + n, e := base64.StdEncoding.Decode(buf, sign) + m.Assert(e) + buf = buf[:n] + + h := md5.Sum(content) + m.Echo("%t", rsa.VerifyPKCS1v15(public.(*rsa.PublicKey), crypto.MD5, h[:], buf) == nil) + } + // }}} + }}, }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", Commands: map[string]*ctx.Command{"login": &ctx.Command{}}}, diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 18d154bd..245f7ce2 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -280,8 +280,13 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ var Pulse *ctx.Message var Index = &ctx.Context{Name: "cli", Help: "管理中心", - Caches: map[string]*ctx.Cache{}, - Configs: map[string]*ctx.Config{}, + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "time": &ctx.Config{Name: "time", Value: "0", Help: "所有模块的当前目录", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + t := time.Now().Unix() + return fmt.Sprintf("%d", t) + }}, + }, Commands: map[string]*ctx.Command{ "alias": &ctx.Command{Name: "alias [short [long]]|[delete short]", Help: "查看、定义或删除命令别名, short: 命令别名, long: 命令原名, delete: 删除别名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index 603b69e7..ae92c868 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -1330,10 +1330,8 @@ var Index = &Context{Name: "ctx", Help: "模块中心", "nmessage": &Cache{Name: "消息数量", Value: "0", Help: "显示模块启动时所创建消息的数量"}, }, Configs: map[string]*Config{ - "debug": &Config{Name: "调试模式(true/false)", Value: "true", Help: "是否打印错误信息,off:不打印,on:打印)"}, - - "default": &Config{Name: "默认的搜索起点(root/back/home)", Value: "root", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"}, - + "debug": &Config{Name: "调试模式(true/false)", Value: "true", Help: "是否打印错误信息,off:不打印,on:打印)"}, + "default": &Config{Name: "默认的搜索起点(root/back/home)", Value: "root", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"}, "start": &Config{Name: "启动模块", Value: "cli", Help: "启动时自动运行的模块"}, "init.shy": &Config{Name: "启动脚本", Value: "etc/init.shy", Help: "模块启动时自动运行的脚本"}, "bench.log": &Config{Name: "日志文件", Value: "var/bench.log", Help: "模块日志输出的文件"}, @@ -1366,6 +1364,23 @@ var Index = &Context{Name: "ctx", Help: "模块中心", "key": &Config{Name: "私钥文件", Value: "etc/key.pem", Help: "私钥文件"}, }, Commands: map[string]*Command{ + "help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) { + if len(arg) == 0 { + m.Echo("^_^ Welcome to context world ^_^\n") + m.Echo("Context is to be a distributed operating system, try to simple everything in work and life. ") + m.Echo("In context you will find all kinds of tools, and you can also make new tool in a quick and easy way.\n") + m.Echo("Here is just a simple introduce, you can look github.com/shylinux/context/README.md for more information.\n") + m.Echo("0. example\n") + m.Echo("1. context\n") + m.Echo("2. message\n") + return + } + switch arg[0] { + case "example": + case "context": + case "message": + } + }}, "server": &Command{Name: "server [start|exit|switch][args]", Help: "服务启动停止切换", Hand: func(m *Message, c *Context, key string, arg ...string) { switch len(arg) { // {{{ case 0: diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index bd78d051..991bf9cd 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -318,14 +318,15 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "count": &ctx.Cache{Name: "count", Value: "0", Help: "主机协议"}, }, Configs: map[string]*ctx.Config{ - "protocol": &ctx.Config{Name: "protocol", Value: "", Help: "主机协议"}, - "hostname": &ctx.Config{Name: "hostname", Value: "", Help: "主机地址"}, - "port": &ctx.Config{Name: "port", Value: "", Help: "主机端口"}, - "dir": &ctx.Config{Name: "dir", Value: "/", Help: "主机路由"}, - "file": &ctx.Config{Name: "file", Value: "", Help: "主机文件"}, - "query": &ctx.Config{Name: "query", Value: "", Help: "主机参数"}, - "output": &ctx.Config{Name: "output", Value: "stdout", Help: "响应输出"}, - "editor": &ctx.Config{Name: "editor", Value: "vim", Help: "响应编辑器"}, + "protocol": &ctx.Config{Name: "protocol", Value: "", Help: "主机协议"}, + "hostname": &ctx.Config{Name: "hostname", Value: "", Help: "主机地址"}, + "port": &ctx.Config{Name: "port", Value: "", Help: "主机端口"}, + "dir": &ctx.Config{Name: "dir", Value: "/", Help: "主机路由"}, + "file": &ctx.Config{Name: "file", Value: "", Help: "主机文件"}, + "query": &ctx.Config{Name: "query", Value: "", Help: "主机参数"}, + "output": &ctx.Config{Name: "output", Value: "stdout", Help: "响应输出"}, + "editor": &ctx.Config{Name: "editor", Value: "vim", Help: "响应编辑器"}, + "upload_dir": &ctx.Config{Name: "upload_dir", Value: "tmp", Help: "上传文件路径"}, }, Commands: map[string]*ctx.Command{ "serve": &ctx.Command{Name: "serve [directory [address [protocol]]]", Help: "开启应用服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -400,7 +401,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // }}} }}, - "get": &ctx.Command{Name: "get [method GET|POST] [file filename] arg...", Help: "访问URL", + "get": &ctx.Command{Name: "get [method GET|POST] [file filename] url arg...", Help: "访问URL", Formats: map[string]int{"method": 1, "file": 2}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { web, ok := m.Target().Server.(*WEB) // {{{ @@ -544,14 +545,26 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } // }}} }}, - "/demo": &ctx.Command{Name: "/demo", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - r := m.Data["request"].(*http.Request) - file, _, e := r.FormFile("file") + "upload": &ctx.Command{Name: "upload file", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + msg := m.Spawn(m.Target()) // {{{ + msg.Cmd("get", "/upload", "method", "POST", "file", "file", arg[0]) + m.Copy(msg, "result") + // }}} + }}, + "/upload": &ctx.Command{Name: "/upload", Help: "文件上传", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + r := m.Data["request"].(*http.Request) // {{{ + + file, header, e := r.FormFile("file") m.Assert(e) - buf, e := ioutil.ReadAll(file) + + f, e := os.Create(path.Join(m.Conf("upload_dir"), header.Filename)) m.Assert(e) - m.Echo(string(buf)) - m.Add("append", "hi", "hello") + + n, e := io.Copy(f, file) + m.Assert(e) + + m.Echo("%d", n) + // }}} }}, "temp": &ctx.Command{Name: "temp", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { msg := m.Spawn(m.Target())