mirror of
https://shylinux.com/x/ContextOS
synced 2025-06-27 02:17:31 +08:00
mac opt ssh&aaa
This commit is contained in:
parent
cf7f1a0056
commit
1cc1ab4b87
@ -5,3 +5,6 @@ source etc/local.shy
|
|||||||
|
|
||||||
alias import nfs
|
alias import nfs
|
||||||
alias send send
|
alias send send
|
||||||
|
alias dial dial
|
||||||
|
|
||||||
|
config debug on
|
||||||
|
@ -2,6 +2,7 @@ package aaa // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
import ( // {{{
|
import ( // {{{
|
||||||
"contexts"
|
"contexts"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
@ -12,6 +13,8 @@ import ( // {{{
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
@ -29,6 +32,12 @@ import ( // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
type AAA struct {
|
type AAA struct {
|
||||||
|
public *rsa.PublicKey
|
||||||
|
private *rsa.PrivateKey
|
||||||
|
certificate *x509.Certificate
|
||||||
|
encrypt cipher.BlockMode
|
||||||
|
decrypt cipher.BlockMode
|
||||||
|
|
||||||
sessions map[string]*ctx.Message
|
sessions map[string]*ctx.Message
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
@ -68,6 +77,21 @@ func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
s := new(AAA)
|
s := new(AAA)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
s.sessions = aaa.sessions
|
s.sessions = aaa.sessions
|
||||||
|
if m.Has("cert") {
|
||||||
|
s.certificate = m.Optionv("certificate").(*x509.Certificate)
|
||||||
|
s.public = s.certificate.PublicKey.(*rsa.PublicKey)
|
||||||
|
}
|
||||||
|
if m.Has("pub") {
|
||||||
|
s.public = m.Optionv("public").(*rsa.PublicKey)
|
||||||
|
m.Log("fuck", "public %v", s.public)
|
||||||
|
}
|
||||||
|
if m.Has("key") {
|
||||||
|
s.private = m.Optionv("private").(*rsa.PrivateKey)
|
||||||
|
s.public = &s.private.PublicKey
|
||||||
|
m.Log("fuck", "public %v", s.public)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,15 +131,76 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
"rootname": &ctx.Config{Name: "rootname", Value: "root", Help: "根用户名"},
|
"rootname": &ctx.Config{Name: "rootname", Value: "root", Help: "根用户名"},
|
||||||
"expire": &ctx.Config{Name: "expire(s)", Value: "7200", Help: "会话超时"},
|
"expire": &ctx.Config{Name: "expire(s)", Value: "7200", Help: "会话超时"},
|
||||||
"cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"},
|
"pub": &ctx.Config{Name: "pub", Value: "etc/pub.pem", Help: "公钥文件"},
|
||||||
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"},
|
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"},
|
||||||
|
|
||||||
|
"aaa_name": &ctx.Config{Name: "aaa_name", Value: "user", Help: "默认模块名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||||
|
if len(arg) > 0 { // {{{
|
||||||
|
return arg[0]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s%d", x.Value, m.Capi("nuser", 1))
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"aaa_help": &ctx.Config{Name: "aaa_help", Value: "登录用户", Help: "默认模块帮助"},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"login": &ctx.Command{
|
"login": &ctx.Command{
|
||||||
Name: "login [sessid]|[username password]|[load|save filename]",
|
Name: "login [sessid]|[username password]|[cert certfile]|[pub pubfile]|[key keyfile]|[ip ipstr]|[load|save filename]",
|
||||||
Help: "用户登录, sessid: 会话ID, username: 用户名, password: 密码, load: 加载用户信息, save: 保存用户信息, filename: 文件名",
|
Help: "用户登录, sessid: 会话ID, username: 用户名, password: 密码, load: 加载用户信息, save: 保存用户信息, filename: 文件名",
|
||||||
|
Form: map[string]int{"cert": 1, "pub": 1, "key": 1, "ip": 1, "load": 1, "save": 1},
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { // {{{
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { // {{{
|
||||||
|
stream := ""
|
||||||
|
if m.Has("ip") {
|
||||||
|
stream = m.Option("ip")
|
||||||
|
}
|
||||||
|
if m.Has("pub") {
|
||||||
|
stream = m.Option("pub")
|
||||||
|
buf, e := ioutil.ReadFile(m.Option("pub"))
|
||||||
|
if e != nil {
|
||||||
|
buf = []byte(m.Option("pub"))
|
||||||
|
e = nil
|
||||||
|
stream = "RSA PUBLIC KEY"
|
||||||
|
}
|
||||||
|
block, _ := pem.Decode(buf)
|
||||||
|
public, e := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
m.Assert(e)
|
||||||
|
m.Optionv("public", public)
|
||||||
|
}
|
||||||
|
if m.Options("cert") {
|
||||||
|
stream = m.Option("cert")
|
||||||
|
buf, e := ioutil.ReadFile(m.Option("cert"))
|
||||||
|
if e != nil {
|
||||||
|
buf = []byte(m.Option("cert"))
|
||||||
|
e = nil
|
||||||
|
stream = "CERTIFICATE"
|
||||||
|
}
|
||||||
|
block, _ := pem.Decode(buf)
|
||||||
|
cert, e := x509.ParseCertificate(block.Bytes)
|
||||||
|
m.Assert(e)
|
||||||
|
m.Optionv("certificate", cert)
|
||||||
|
}
|
||||||
|
if m.Has("key") {
|
||||||
|
stream = m.Option("key")
|
||||||
|
buf, e := ioutil.ReadFile(m.Option("key"))
|
||||||
|
if e != nil {
|
||||||
|
buf = []byte(m.Option("key"))
|
||||||
|
e = nil
|
||||||
|
stream = "RSA PRIVATE KEY"
|
||||||
|
}
|
||||||
|
block, buf := pem.Decode(buf)
|
||||||
|
private, e := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
m.Assert(e)
|
||||||
|
m.Optionv("private", private)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Log("fuck", "stream %s", stream)
|
||||||
|
if stream != "" {
|
||||||
|
m.Start(m.Confx("aaa_name"), m.Confx("aaa_help"), arg[0], "", aaa.Session(arg[0]))
|
||||||
|
m.Cap("stream", stream)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch len(arg) {
|
switch len(arg) {
|
||||||
case 0:
|
case 0:
|
||||||
m.Travel(func(m *ctx.Message, i int) bool {
|
m.Travel(func(m *ctx.Message, i int) bool {
|
||||||
@ -154,19 +239,247 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if msg := m.Find(arg[0], false); msg == nil {
|
find := false
|
||||||
m.Start(arg[0], "用户", arg[0], aaa.Password(arg[1]), aaa.Session(arg[0]))
|
m.Travel(func(m *ctx.Message, line int) bool {
|
||||||
|
if line > 0 && m.Cap("username") == arg[0] {
|
||||||
|
if m.Cap("password") == aaa.Password(arg[1]) {
|
||||||
|
m.Log("fuck", "%v", m.Format())
|
||||||
|
m.Sess("aaa", m.Target())
|
||||||
|
m.Echo(m.Cap("sessid"))
|
||||||
|
} else {
|
||||||
|
m.Sess("aaa", c)
|
||||||
|
}
|
||||||
|
find = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}, c)
|
||||||
|
|
||||||
|
if !find {
|
||||||
|
m.Start(m.Confx("aaa_name"), m.Confx("aaa_help"), arg[0], aaa.Password(arg[1]), aaa.Session(arg[0]))
|
||||||
|
m.Cap("stream", arg[0])
|
||||||
|
m.Sess("aaa", m)
|
||||||
m.Echo(m.Cap("sessid"))
|
m.Echo(m.Cap("sessid"))
|
||||||
} else if msg.Cap("password") != aaa.Password(arg[1]) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
m.Echo(msg.Cap("sessid"))
|
|
||||||
m.Copy(msg, "target")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // }}}
|
} // }}}
|
||||||
}},
|
}},
|
||||||
|
"certificate": &ctx.Command{Name: "certificate filename", Help: "散列",
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
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}))
|
||||||
|
if m.Echo(certificate); len(arg) > 0 {
|
||||||
|
m.Assert(ioutil.WriteFile(arg[0], []byte(certificate), 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"public": &ctx.Command{Name: "public filename", Help: "散列",
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { // {{{
|
||||||
|
pub, e := x509.MarshalPKIXPublicKey(aaa.public)
|
||||||
|
m.Assert(e)
|
||||||
|
public := string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pub}))
|
||||||
|
if m.Echo(public); len(arg) > 0 {
|
||||||
|
m.Assert(ioutil.WriteFile(arg[0], []byte(public), 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"private": &ctx.Command{Name: "private filename", Help: "散列",
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"sign": &ctx.Command{Name: "sign [file filename][content] [sign signfile]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1, "sign": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content = []byte(arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
h := md5.Sum(content)
|
||||||
|
b, e := rsa.SignPKCS1v15(crand.Reader, aaa.private, crypto.MD5, h[:])
|
||||||
|
m.Assert(e)
|
||||||
|
|
||||||
|
res := base64.StdEncoding.EncodeToString(b)
|
||||||
|
if m.Echo(res); m.Has("sign") {
|
||||||
|
m.Assert(ioutil.WriteFile(m.Option("sign"), []byte(res), 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"verify": &ctx.Command{Name: "verify [file filename][content] [sign signfile][signature]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1, "sign": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content, arg = []byte(arg[0]), arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
var sign []byte
|
||||||
|
if m.Has("sign") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("sign"))
|
||||||
|
m.Assert(e)
|
||||||
|
sign = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
sign, arg = []byte(arg[0]), arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
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(aaa.public, crypto.MD5, h[:], buf) == nil)
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"seal": &ctx.Command{Name: "seal [file filename][content] [seal sealfile]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1, "seal": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content = []byte(arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
b, e := rsa.EncryptPKCS1v15(crand.Reader, aaa.public, content)
|
||||||
|
m.Assert(e)
|
||||||
|
|
||||||
|
res := base64.StdEncoding.EncodeToString(b)
|
||||||
|
if m.Echo(res); m.Has("seal") {
|
||||||
|
m.Assert(ioutil.WriteFile(m.Option("seal"), []byte(res), 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"deal": &ctx.Command{Name: "deal [file filename][content]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content, arg = []byte(arg[0]), arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, e := base64.StdEncoding.Decode(buf, content)
|
||||||
|
m.Assert(e)
|
||||||
|
buf = buf[:n]
|
||||||
|
|
||||||
|
b, e := rsa.DecryptPKCS1v15(crand.Reader, aaa.private, buf)
|
||||||
|
m.Assert(e)
|
||||||
|
m.Echo(string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"newcipher": &ctx.Command{Name: "newcipher", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { // {{{
|
||||||
|
salt := md5.Sum([]byte(arg[0]))
|
||||||
|
block, e := aes.NewCipher(salt[:])
|
||||||
|
m.Assert(e)
|
||||||
|
aaa.encrypt = cipher.NewCBCEncrypter(block, salt[:])
|
||||||
|
aaa.decrypt = cipher.NewCBCDecrypter(block, salt[:])
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"encrypt": &ctx.Command{Name: "encrypt [file filename][content] [enfile]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.encrypt != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content, arg = []byte(arg[0]), arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
bsize := aaa.encrypt.BlockSize()
|
||||||
|
size := (len(content) / bsize) * bsize
|
||||||
|
if len(content)%bsize != 0 {
|
||||||
|
size += bsize
|
||||||
|
}
|
||||||
|
buf := make([]byte, size)
|
||||||
|
for pos := 0; pos < len(content); pos += bsize {
|
||||||
|
end := pos + bsize
|
||||||
|
if end > len(content) {
|
||||||
|
end = len(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, bsize)
|
||||||
|
copy(b, content[pos:end])
|
||||||
|
|
||||||
|
m.Log("fuck", "pos: %d end: %d", pos, end)
|
||||||
|
aaa.encrypt.CryptBlocks(buf[pos:pos+bsize], b)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := base64.StdEncoding.EncodeToString(buf)
|
||||||
|
if m.Echo(res); len(arg) > 0 {
|
||||||
|
m.Assert(ioutil.WriteFile(arg[0], []byte(res), 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
|
"decrypt": &ctx.Command{Name: "decrypt [file filename][content] [defile]", Help: "散列",
|
||||||
|
Form: map[string]int{"file": 1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.decrypt != nil { // {{{
|
||||||
|
var content []byte
|
||||||
|
if m.Has("file") {
|
||||||
|
b, e := ioutil.ReadFile(m.Option("file"))
|
||||||
|
m.Assert(e)
|
||||||
|
content = b
|
||||||
|
} else if len(arg) > 0 {
|
||||||
|
content, arg = []byte(arg[0]), arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Log("fuck", "why %v", content)
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, e := base64.StdEncoding.Decode(buf, content)
|
||||||
|
m.Assert(e)
|
||||||
|
buf = buf[:n]
|
||||||
|
|
||||||
|
res := make([]byte, n)
|
||||||
|
aaa.decrypt.CryptBlocks(res, buf)
|
||||||
|
|
||||||
|
if m.Echo(string(res)); len(arg) > 0 {
|
||||||
|
m.Assert(ioutil.WriteFile(arg[0], res, 0666))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
"md5": &ctx.Command{Name: "md5 [file filename][content]", Help: "散列",
|
"md5": &ctx.Command{Name: "md5 [file filename][content]", Help: "散列",
|
||||||
Form: map[string]int{"file": 1},
|
Form: map[string]int{"file": 1},
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
@ -210,9 +523,18 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
m.Append("public", public)
|
m.Append("public", public)
|
||||||
m.Echo(public)
|
m.Echo(public)
|
||||||
|
|
||||||
|
template := x509.Certificate{SerialNumber: big.NewInt(1)}
|
||||||
|
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.Append("certificate", certificate)
|
||||||
|
m.Echo(certificate)
|
||||||
|
|
||||||
if m.Options("keyfile") {
|
if m.Options("keyfile") {
|
||||||
ioutil.WriteFile(m.Option("keyfile"), []byte(private), 0666)
|
ioutil.WriteFile(m.Option("keyfile"), []byte(private), 0666)
|
||||||
ioutil.WriteFile("pub"+m.Option("keyfile"), []byte(public), 0666)
|
ioutil.WriteFile("pub"+m.Option("keyfile"), []byte(public), 0666)
|
||||||
|
ioutil.WriteFile("cert"+m.Option("keyfile"), []byte(certificate), 0666)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -312,23 +634,6 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"deal": &ctx.Command{Name: "deal init|sell|buy|done [keyfile name][key str]", Help: "散列",
|
|
||||||
Form: 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[:]))
|
|
||||||
}
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
|||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "模块文档"},
|
"cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "模块文档"},
|
||||||
"cmd_timeout": &ctx.Config{Name: "cmd_timeout", Value: "3s", Help: "系统命令超时"},
|
"cmd_timeout": &ctx.Config{Name: "cmd_timeout", Value: "10s", Help: "系统命令超时"},
|
||||||
|
|
||||||
"time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"},
|
"time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"},
|
||||||
"time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"},
|
"time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"},
|
||||||
@ -740,6 +740,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
|||||||
go func() {
|
go func() {
|
||||||
if out, e := cmd.CombinedOutput(); e != nil {
|
if out, e := cmd.CombinedOutput(); e != nil {
|
||||||
m.Echo("error: ").Echo("%s\n", e)
|
m.Echo("error: ").Echo("%s\n", e)
|
||||||
|
m.Echo("%s\n", string(out))
|
||||||
} else {
|
} else {
|
||||||
m.Echo(string(out))
|
m.Echo(string(out))
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,12 @@ func Trans(arg ...interface{}) []string { // {{{
|
|||||||
ls := []string{}
|
ls := []string{}
|
||||||
for _, v := range arg {
|
for _, v := range arg {
|
||||||
switch val := v.(type) {
|
switch val := v.(type) {
|
||||||
|
case *Message:
|
||||||
|
if val.Hand {
|
||||||
|
ls = append(ls, val.Meta["result"]...)
|
||||||
|
} else {
|
||||||
|
ls = append(ls, val.Meta["detail"]...)
|
||||||
|
}
|
||||||
case string:
|
case string:
|
||||||
ls = append(ls, val)
|
ls = append(ls, val)
|
||||||
case bool:
|
case bool:
|
||||||
@ -96,6 +102,7 @@ type Context struct {
|
|||||||
|
|
||||||
requests []*Message
|
requests []*Message
|
||||||
sessions []*Message
|
sessions []*Message
|
||||||
|
message *Message
|
||||||
|
|
||||||
contexts map[string]*Context
|
contexts map[string]*Context
|
||||||
context *Context
|
context *Context
|
||||||
@ -150,6 +157,7 @@ func (c *Context) Begin(m *Message, arg ...string) *Context { // {{{
|
|||||||
|
|
||||||
c.requests = append(c.requests, m)
|
c.requests = append(c.requests, m)
|
||||||
m.source.sessions = append(m.source.sessions, m)
|
m.source.sessions = append(m.source.sessions, m)
|
||||||
|
c.message = m
|
||||||
|
|
||||||
m.Log("begin", "%d context %v %v", m.root.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
|
m.Log("begin", "%d context %v %v", m.root.Capi("ncontext", 1), m.Meta["detail"], m.Meta["option"])
|
||||||
for k, x := range c.Configs {
|
for k, x := range c.Configs {
|
||||||
@ -181,6 +189,7 @@ func (c *Context) Start(m *Message, arg ...string) bool { // {{{
|
|||||||
go m.TryCatch(m, true, func(m *Message) {
|
go m.TryCatch(m, true, func(m *Message) {
|
||||||
m.Log(m.Cap("status", "start"), "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
|
m.Log(m.Cap("status", "start"), "%d server %v %v", m.root.Capi("nserver", 1), m.Meta["detail"], m.Meta["option"])
|
||||||
|
|
||||||
|
c.message = m
|
||||||
c.exit = make(chan bool, 2)
|
c.exit = make(chan bool, 2)
|
||||||
if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) {
|
if running <- true; c.Server != nil && c.Server.Start(m, m.Meta["detail"]...) {
|
||||||
c.Close(m, m.Meta["detail"]...)
|
c.Close(m, m.Meta["detail"]...)
|
||||||
@ -237,6 +246,11 @@ func (c *Context) Context() *Context { // {{{
|
|||||||
return c.context
|
return c.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (c *Context) Message() *Message { // {{{
|
||||||
|
return c.message
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Has(key ...string) bool { // {{{
|
func (c *Context) Has(key ...string) bool { // {{{
|
||||||
switch len(key) {
|
switch len(key) {
|
||||||
@ -402,6 +416,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{
|
|||||||
e = errors.New(msg[0])
|
e = errors.New(msg[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.Log("error", "%s", fmt.Sprintln(e))
|
||||||
panic(m.Set("result", "error: ", fmt.Sprintln(e), "\n"))
|
panic(m.Set("result", "error: ", fmt.Sprintln(e), "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,10 +510,15 @@ func (m *Message) Travel(hand func(m *Message, i int) bool, c ...*Context) { //
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (m *Message) Spawn(arg ...*Context) *Message { // {{{
|
func (m *Message) Spawn(arg ...interface{}) *Message { // {{{
|
||||||
c := m.target
|
c := m.target
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
c = arg[0]
|
switch v := arg[0].(type) {
|
||||||
|
case *Context:
|
||||||
|
c = v
|
||||||
|
case *Message:
|
||||||
|
c = v.target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &Message{
|
msg := &Message{
|
||||||
@ -1292,10 +1312,11 @@ func (m *Message) Cmd(args ...interface{}) *Message { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (m *Message) Confx(key string, arg ...interface{}) string { // {{{
|
func (m *Message) Confx(key string, arg ...interface{}) string { // {{{
|
||||||
|
conf := m.Conf(key)
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
value := m.Option(key)
|
value := m.Option(key)
|
||||||
if value == "" {
|
if value == "" {
|
||||||
value = m.Conf(key)
|
value = conf
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
@ -1327,7 +1348,7 @@ func (m *Message) Confx(key string, arg ...interface{}) string { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !force && value == "" {
|
if !force && value == "" {
|
||||||
value = m.Conf(key)
|
value = conf
|
||||||
}
|
}
|
||||||
|
|
||||||
format := "%s"
|
format := "%s"
|
||||||
@ -2183,9 +2204,16 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(arg) == 1 {
|
if len(arg) == 1 {
|
||||||
if sub := msg.Sess(arg[0], false); sub != nil {
|
m.Log("fuck", "%v", m.Meta)
|
||||||
m.Echo("%d", sub.code)
|
for msg = msg; msg != nil; msg = msg.message {
|
||||||
|
for k, v := range msg.Sessions {
|
||||||
|
if k == arg[0] {
|
||||||
|
m.Echo("%d", v.code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
m.Log("fuck", "%v", m.Meta)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2352,6 +2380,11 @@ var Index = &Context{Name: "ctx", Help: "模块中心",
|
|||||||
} else {
|
} else {
|
||||||
m.Add("append", "context", "")
|
m.Add("append", "context", "")
|
||||||
}
|
}
|
||||||
|
if msg.target.Message != nil {
|
||||||
|
m.Add("append", "message", msg.target.message.code)
|
||||||
|
} else {
|
||||||
|
m.Add("append", "message", "")
|
||||||
|
}
|
||||||
|
|
||||||
m.Add("append", "status", msg.Cap("status"))
|
m.Add("append", "status", msg.Cap("status"))
|
||||||
m.Add("append", "stream", msg.Cap("stream"))
|
m.Add("append", "stream", msg.Cap("stream"))
|
||||||
|
@ -52,7 +52,7 @@ type NFS struct {
|
|||||||
|
|
||||||
func (nfs *NFS) open(name string) (*os.File, error) { // {{{
|
func (nfs *NFS) open(name string) (*os.File, error) { // {{{
|
||||||
if path.IsAbs(name) {
|
if path.IsAbs(name) {
|
||||||
nfs.Log("info", "open %s", name)
|
nfs.Message.Log("info", "open %s", name)
|
||||||
return os.Open(name)
|
return os.Open(name)
|
||||||
}
|
}
|
||||||
for i := len(nfs.paths) - 1; i >= 0; i-- {
|
for i := len(nfs.paths) - 1; i >= 0; i-- {
|
||||||
@ -538,7 +538,6 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||||
nfs.Message = m
|
|
||||||
if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") {
|
if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") {
|
||||||
c.Caches = map[string]*ctx.Cache{
|
c.Caches = map[string]*ctx.Cache{
|
||||||
"pos": &ctx.Cache{Name: "pos", Value: "0", Help: "pos"},
|
"pos": &ctx.Cache{Name: "pos", Value: "0", Help: "pos"},
|
||||||
@ -679,28 +678,22 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
nfs.io = m.Optionv("io").(net.Conn)
|
nfs.io = m.Optionv("io").(net.Conn)
|
||||||
nfs.hand = map[int]*ctx.Message{}
|
nfs.hand = map[int]*ctx.Message{}
|
||||||
nfs.send = make(chan *ctx.Message, 10)
|
nfs.send = make(chan *ctx.Message, 10)
|
||||||
m.Log("fuck", "send %p", nfs.send)
|
|
||||||
nfs.recv = make(chan *ctx.Message, 10)
|
nfs.recv = make(chan *ctx.Message, 10)
|
||||||
|
|
||||||
go func() {
|
go func() { //发送消息队列
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case msg := <-nfs.send:
|
case msg := <-nfs.send:
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
|
||||||
head, body := "detail", "option"
|
head, body := "detail", "option"
|
||||||
if msg.Hand {
|
if msg.Hand {
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
|
||||||
head, body = "result", "append"
|
head, body = "result", "append"
|
||||||
send_code := msg.Option("send_code")
|
send_code := msg.Option("send_code")
|
||||||
msg.Append("send_code1", send_code)
|
msg.Append("send_code1", send_code)
|
||||||
m.Log("info", "%s recv: %v %v", msg.Option("recv_code"), msg.Meta[head], msg.Meta[body])
|
m.Log("info", "%s recv: %v %v", msg.Option("recv_code"), msg.Meta[head], msg.Meta[body])
|
||||||
} else {
|
} else {
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
msg.Option("send_code", m.Capi("nsend", 1))
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
m.Log("info", "%d send: %v %v", m.Capi("nsend"), msg.Meta[head], msg.Meta[body])
|
||||||
m.Log("info", "%d send: %v %v", m.Capi("nsend", 1), msg.Meta[head], msg.Meta[body])
|
|
||||||
nfs.hand[m.Capi("nsend")] = msg
|
nfs.hand[m.Capi("nsend")] = msg
|
||||||
msg.Option("send_code", m.Capi("nsend"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range msg.Meta[head] {
|
for _, v := range msg.Meta[head] {
|
||||||
@ -723,12 +716,18 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() { //接收消息队列
|
||||||
bio := bufio.NewScanner(nfs.io)
|
bio := bufio.NewScanner(nfs.io)
|
||||||
var e error
|
var e error
|
||||||
for msg, head, body := m.Sess("target"), "", ""; bio.Scan(); {
|
var msg *ctx.Message
|
||||||
|
for head, body := "", ""; bio.Scan(); {
|
||||||
|
if msg == nil {
|
||||||
|
msg = m.Sess("target")
|
||||||
|
}
|
||||||
|
if msg.Meta == nil {
|
||||||
|
msg.Meta = map[string][]string{}
|
||||||
|
}
|
||||||
line := bio.Text()
|
line := bio.Text()
|
||||||
m.Log("fuck", "send %p %v", nfs.send, msg.Meta)
|
|
||||||
m.Capi("nread", len(line)+1)
|
m.Capi("nread", len(line)+1)
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
|
|
||||||
@ -742,7 +741,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
h.Copy(msg, "result").Copy(msg, "append")
|
h.Copy(msg, "result").Copy(msg, "append")
|
||||||
h.Remote <- true
|
h.Remote <- true
|
||||||
}
|
}
|
||||||
msg = m.Sess("target")
|
msg = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,8 +766,6 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case msg := <-nfs.recv:
|
case msg := <-nfs.recv:
|
||||||
m.Log("fuck", "why %s %v", msg.Format(), msg.Meta)
|
|
||||||
|
|
||||||
nfs.send <- msg.Cmd()
|
nfs.send <- msg.Cmd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1286,16 +1283,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
|||||||
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
|
m.Sess("tcp").Call(func(sub *ctx.Message) *ctx.Message {
|
||||||
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
|
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
|
||||||
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
|
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
|
||||||
sub.Log("fuck", "send")
|
nfs, _ := sub.Target().Server.(*NFS)
|
||||||
nfs, ok := sub.Target().Server.(*NFS)
|
|
||||||
sub.Log("fuck", "send %v", ok)
|
|
||||||
m.Log("fuck", "send %p", nfs.send)
|
|
||||||
sub1.Remote = make(chan bool, 1)
|
sub1.Remote = make(chan bool, 1)
|
||||||
sub.Log("info", "before send %d", len(nfs.send))
|
|
||||||
nfs.send <- sub1
|
nfs.send <- sub1
|
||||||
sub.Log("info", "middle send %d", len(nfs.send))
|
|
||||||
<-sub1.Remote
|
<-sub1.Remote
|
||||||
sub.Log("info", "after send %d", len(nfs.send))
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}, m.Meta["detail"])
|
}, m.Meta["detail"])
|
||||||
@ -1308,13 +1299,9 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
|
|||||||
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
|
sub.Start(fmt.Sprintf("file%d", m.Capi("nfile", 1)), "远程文件")
|
||||||
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
|
return sub.Sess("target", m.Source()).Call(func(sub1 *ctx.Message) *ctx.Message {
|
||||||
nfs, _ := sub.Target().Server.(*NFS)
|
nfs, _ := sub.Target().Server.(*NFS)
|
||||||
m.Log("fuck", "send %p", nfs.send)
|
|
||||||
sub1.Remote = make(chan bool, 1)
|
sub1.Remote = make(chan bool, 1)
|
||||||
sub.Log("info", "before send %d", len(nfs.send))
|
|
||||||
nfs.send <- sub1
|
nfs.send <- sub1
|
||||||
sub.Log("info", "middle send %d", len(nfs.send))
|
|
||||||
<-sub1.Remote
|
<-sub1.Remote
|
||||||
sub.Log("info", "after send %d", len(nfs.send))
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}, m.Meta["detail"])
|
}, m.Meta["detail"])
|
||||||
|
@ -11,9 +11,9 @@ import ( // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
type SSH struct {
|
type SSH struct {
|
||||||
nfs *ctx.Context
|
nfs *ctx.Context
|
||||||
|
peer map[string]*ctx.Message
|
||||||
|
|
||||||
*ctx.Message
|
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,6 @@ func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
ssh.Message = m
|
|
||||||
ssh.Caches["hostname"] = &ctx.Cache{Name: "hostname", Value: "", Help: "主机数量"}
|
ssh.Caches["hostname"] = &ctx.Cache{Name: "hostname", Value: "", Help: "主机数量"}
|
||||||
if ssh.Context == Index {
|
if ssh.Context == Index {
|
||||||
Pulse = m
|
Pulse = m
|
||||||
@ -40,7 +39,6 @@ func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
ssh.Message = m
|
|
||||||
ssh.nfs = m.Source()
|
ssh.nfs = m.Source()
|
||||||
m.Cap("stream", m.Source().Name)
|
m.Cap("stream", m.Source().Name)
|
||||||
return false
|
return false
|
||||||
@ -59,7 +57,7 @@ func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
m.Sess("nfs", "nfs")
|
m.Sess("nfs", "nfs")
|
||||||
for !m.Caps("stream") {
|
for !m.Caps("stream") {
|
||||||
time.Sleep(time.Second * time.Duration(m.Confi("interval")))
|
time.Sleep(time.Second * time.Duration(m.Confi("interval")))
|
||||||
go ssh.Message.Spawn(m.Target()).Copy(ssh.Message, "detail").Cmd()
|
go ssh.Message().Spawn(m.Target()).Copy(ssh.Message(), "detail").Cmd()
|
||||||
time.Sleep(time.Second * time.Duration(m.Confi("interval")))
|
time.Sleep(time.Second * time.Duration(m.Confi("interval")))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -102,7 +100,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
|||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
"interval": &ctx.Config{Name: "interval", Value: "3", Help: "主机数量"},
|
"interval": &ctx.Config{Name: "interval", Value: "3", Help: "主机数量"},
|
||||||
"hostname": &ctx.Config{Name: "hostname", Value: "host", Help: "主机数量"},
|
"hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机数量"},
|
||||||
"domain.json": &ctx.Config{Name: "domain.json", Value: "var/domain.json", Help: "主机数量"},
|
"domain.json": &ctx.Config{Name: "domain.json", Value: "var/domain.json", Help: "主机数量"},
|
||||||
"domain.png": &ctx.Config{Name: "domain.png", Value: "var/domain.png", Help: "主机数量"},
|
"domain.png": &ctx.Config{Name: "domain.png", Value: "var/domain.png", Help: "主机数量"},
|
||||||
|
|
||||||
@ -136,125 +134,73 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
|||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行",
|
"send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行",
|
||||||
Form: map[string]int{"domain": 1},
|
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
m.Log("why", "send")
|
|
||||||
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{
|
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{
|
||||||
if m.Options("domain") {
|
domain := ""
|
||||||
find := false
|
if len(arg) > 1 && arg[0] == "domain" {
|
||||||
host := strings.SplitN(m.Option("domain"), ".", 2)
|
domain, arg = arg[1], arg[2:]
|
||||||
|
domain = strings.TrimPrefix(strings.TrimPrefix(domain, m.Cap("domain")), ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
if domain != "" {
|
||||||
|
domain_miss := true
|
||||||
|
host := strings.SplitN(domain, ".", 2)
|
||||||
m.Travel(func(m *ctx.Message, i int) bool {
|
m.Travel(func(m *ctx.Message, i int) bool {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
if m.Cap("hostname") == host[0] {
|
if m.Cap("hostname") == host[0] {
|
||||||
ssh, ok := m.Target().Server.(*SSH)
|
ssh, ok := m.Target().Server.(*SSH)
|
||||||
m.Assert(ok)
|
m.Assert(ok)
|
||||||
msg := m.Spawn(ssh.Message.Source())
|
|
||||||
|
msg := m.Spawn(ssh.Message().Source()).Copy(m, "option")
|
||||||
if len(host) > 1 {
|
if len(host) > 1 {
|
||||||
msg.Option("domain", host[1])
|
msg.Options("downflow", true)
|
||||||
msg.Detail("send", arg)
|
msg.Detail("send", "domain", host[1], arg)
|
||||||
} else {
|
} else {
|
||||||
msg.Detail(arg)
|
msg.Detail(arg)
|
||||||
}
|
}
|
||||||
m.Log("why", "send")
|
|
||||||
m.Log("why", "send %s", ssh.Message.Format())
|
if ssh.Message().Back(msg); !msg.Appends("domain_miss") {
|
||||||
ssh.Message.Back(msg)
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
m.Copy(msg, "result").Copy(msg, "append")
|
domain_miss = false
|
||||||
find = true
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}, c)
|
}, c)
|
||||||
|
|
||||||
if !find && m.Cap("domain") != "com" {
|
if domain_miss && !m.Options("downflow") && m.Cap("domain") != m.Conf("domain") {
|
||||||
ssh, ok := c.Server.(*SSH)
|
ssh, ok := c.Server.(*SSH)
|
||||||
m.Assert(ok)
|
m.Assert(ok)
|
||||||
|
|
||||||
msg := m.Spawn(ssh.Message.Source())
|
msg := m.Spawn(ssh.Message().Source()).Copy(m, "option")
|
||||||
msg.Option("domain", m.Option("domain"))
|
msg.Detail("send", "domain", domain, arg)
|
||||||
m.Log("why", "send------ %s", c.Name)
|
|
||||||
msg.Detail("send", arg)
|
if ssh.Message().Back(msg); !msg.Appends("domain_miss") {
|
||||||
m.Log("why", "send %s", ssh.Message.Format())
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
ssh.Message.Back(msg)
|
domain_miss = false
|
||||||
m.Copy(msg, "result").Copy(msg, "append")
|
}
|
||||||
find = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.Appends("domain_miss", domain_miss)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := m.Spawn(ssh.Message.Source())
|
|
||||||
m.Log("why", "send")
|
|
||||||
msg.Detail(arg)
|
|
||||||
m.Log("why", "send %s", ssh.Message.Format())
|
|
||||||
ssh.Message.Back(msg)
|
|
||||||
m.Copy(msg, "result").Copy(msg, "append")
|
|
||||||
return
|
|
||||||
|
|
||||||
if m.Option("domain") == m.Cap("domain") { //本地命令
|
if m.Options("send_code") || m.Cap("status") != "start" {
|
||||||
msg := m.Spawn(m.Target())
|
msg := m.Spawn().Cmd(arg)
|
||||||
msg.Cmd(arg)
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
|
} else {
|
||||||
|
msg := m.Spawn(ssh.Message().Source())
|
||||||
|
msg.Copy(m, "option").Detail(arg)
|
||||||
|
ssh.Message().Back(msg)
|
||||||
m.Copy(msg, "result").Copy(msg, "append")
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
m.Back(m)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
return
|
||||||
target := strings.Split(m.Option("domain"), ".")
|
} // }}}
|
||||||
name, rest := target[0], target[1:]
|
|
||||||
if name == m.Conf("domain") {
|
|
||||||
if len(target) > 1 {
|
|
||||||
name = target[1]
|
|
||||||
rest = target[2:]
|
|
||||||
} else {
|
|
||||||
name = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rest) == 0 && len(name) == 0 { //点对点通信
|
|
||||||
if m.Options("nsend") { //接收命令
|
|
||||||
msg := m.Spawn(m.Target())
|
|
||||||
msg.Cmd(arg)
|
|
||||||
m.Copy(msg, "result").Copy(msg, "append")
|
|
||||||
m.Back(m)
|
|
||||||
} else { //发送命令
|
|
||||||
ssh.Message.Sess("nfs").CallBack(m.Options("stdio"), func(host *ctx.Message) *ctx.Message {
|
|
||||||
m.Back(m.Copy(host, "result").Copy(host, "append"))
|
|
||||||
return nil
|
|
||||||
}, "send", "send", arg)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
miss := true
|
|
||||||
m.Travel(func(m *ctx.Message, i int) bool { //向下搜索
|
|
||||||
if ssh, ok := m.Target().Server.(*SSH); ok && m.Conf("domains") == name {
|
|
||||||
msg := m.Spawn(ssh.nfs)
|
|
||||||
msg.Option("domain", strings.Join(rest, "."))
|
|
||||||
msg.CallBack(m.Options("stdio"), func(host *ctx.Message) *ctx.Message {
|
|
||||||
return m.Copy(host, "result").Copy(host, "append")
|
|
||||||
}, "send", "send", arg)
|
|
||||||
|
|
||||||
miss = false
|
|
||||||
}
|
|
||||||
return miss
|
|
||||||
}, c)
|
|
||||||
|
|
||||||
if miss {
|
|
||||||
if name == m.Cap("domain") {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if miss { //向上搜索
|
|
||||||
if ssh, ok := c.Server.(*SSH); m.Assert(ok) && ssh.nfs != nil {
|
|
||||||
msg := m.Spawn(ssh.nfs)
|
|
||||||
msg.Option("domain", m.Option("domain"))
|
|
||||||
msg.CallBack(m.Options("stdio"), func(host *ctx.Message) *ctx.Message {
|
|
||||||
return m.Copy(host, "result").Copy(host, "append")
|
|
||||||
}, "send", "send", arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }}}
|
|
||||||
}},
|
}},
|
||||||
"pwd": &ctx.Command{Name: "pwd", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
"pwd": &ctx.Command{Name: "pwd", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 { // {{{
|
||||||
if m.Target() == c {
|
if m.Target() == c {
|
||||||
m.Echo(m.Cap("domain"))
|
m.Echo(m.Cap("domain"))
|
||||||
} else {
|
} else {
|
||||||
@ -268,49 +214,98 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
|
|||||||
m.Copy(msg, "result").Copy(msg, "append")
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
m.Cap("domain", msg.Result(0))
|
m.Cap("domain", msg.Result(0))
|
||||||
} else if m.Options("send_code") {
|
} else if m.Options("send_code") {
|
||||||
m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname", arg[0]))
|
hostname := arg[0]
|
||||||
}
|
m.Travel(func(m *ctx.Message, line int) bool {
|
||||||
return
|
if hostname == m.Cap("hostname") {
|
||||||
|
hostname += m.Cap("nhost")
|
||||||
switch len(arg) { // {{{
|
return false
|
||||||
case 0:
|
|
||||||
m.Echo(m.Cap("domain"))
|
|
||||||
case 1:
|
|
||||||
if m.Options("nsend") {
|
|
||||||
domain := arg[0]
|
|
||||||
|
|
||||||
m.Travel(func(m *ctx.Message, i int) bool {
|
|
||||||
if m.Conf("domains") == domain {
|
|
||||||
domain = domain + m.Cap("nhost")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}, c)
|
|
||||||
m.Conf("domains", domain)
|
|
||||||
|
|
||||||
mdb := m.Find(m.Conf("mdb"), true)
|
|
||||||
if mdb != nil {
|
|
||||||
domain := m.Cap("domain") + "." + m.Conf("domains")
|
|
||||||
mdb.Cmd("exec", "delete from goodship where value=?", domain)
|
|
||||||
mdb.Cmd("exec", "insert into goodship(uid, share, level, type, value, kind, name) value(?, 'root', 'root', 'terminal', ?, 'terminal', ?)", m.Conf("uid"), domain, domain)
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
m.Echo(m.Cap("domain"))
|
}, c)
|
||||||
m.Echo(".")
|
m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname", hostname))
|
||||||
m.Echo(m.Conf("domains"))
|
} // }}}
|
||||||
} else {
|
}},
|
||||||
m.Spawn(m.Target()).CallBack(m.Options("stdio"), func(msg *ctx.Message) *ctx.Message {
|
"hello": &ctx.Command{Name: "hello request", Help: "加密请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
m.Conf("domain", msg.Result(2))
|
aaa := m.Target().Message().Sess("aaa", false) // {{{
|
||||||
m.Echo(m.Cap("domain", strings.Join(msg.Meta["result"], "")))
|
for _, k := range m.Meta["seal"] {
|
||||||
m.Back(msg)
|
for i, v := range m.Meta[k] {
|
||||||
|
m.Meta[k][i] = m.Spawn(aaa).Cmd("deal", v).Result(0)
|
||||||
m.Spawn(m.Target()).Cmd("save")
|
|
||||||
return nil
|
|
||||||
}, "send", "pwd", arg[0])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, k := range m.Meta["encrypt"] {
|
||||||
|
for i, v := range m.Meta[k] {
|
||||||
|
m.Meta[k][i] = m.Spawn(aaa).Cmd("decrypt", v).Result(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(arg) == 0 {
|
||||||
|
if !m.Has("mi") {
|
||||||
|
cert := aaa.Spawn().Cmd("certificate")
|
||||||
|
m.Echo(cert.Result(0))
|
||||||
|
} else {
|
||||||
|
msg := m.Sess("aaa").Cmd("login", m.Option("mi"), m.Option("mi"))
|
||||||
|
m.Echo(msg.Result(0))
|
||||||
|
msg.Sess("aaa").Cmd("newcipher", m.Option("mi"))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := m.Spawn().Copy(m, "option").Cmd(arg)
|
||||||
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
"shake": &ctx.Command{
|
||||||
|
Name: "shake [domain host] cmd... [seal option...][encrypt option...]",
|
||||||
|
Help: "加密通信",
|
||||||
|
Form: map[string]int{"seal": -1, "encrypt": -1},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{
|
||||||
|
if len(arg) == 0 {
|
||||||
|
for k, v := range ssh.peer {
|
||||||
|
m.Echo("%s: %s\n", k, v.Cap("stream"))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
peer := "peer"
|
||||||
|
args := []string{}
|
||||||
|
if len(arg) > 1 && arg[0] == "domain" {
|
||||||
|
args = append(args, "domain", arg[1])
|
||||||
|
peer, arg = arg[1], arg[2:]
|
||||||
|
}
|
||||||
|
if ssh.peer == nil {
|
||||||
|
ssh.peer = map[string]*ctx.Message{}
|
||||||
|
}
|
||||||
|
user, ok := ssh.peer[peer]
|
||||||
|
if !ok {
|
||||||
|
user = m.Sess("aaa").Cmd("login", "cert", m.Spawn().Cmd("send", args, "hello"), peer)
|
||||||
|
ssh.peer[peer] = user
|
||||||
|
mi := user.Cap("sessid")
|
||||||
|
|
||||||
|
remote := m.Spawn().Add("option", mi, m.Spawn(user).Cmd("seal", mi)).Add("option", "seal", mi).Cmd("send", args, "hello")
|
||||||
|
m.Spawn(user).Cmd("newcipher", mi)
|
||||||
|
user.Cap("remote", "remote", remote.Result(0), "远程会话")
|
||||||
|
user.Cap("remote_mi", "remote_mi", mi, "远程密钥")
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := m.Spawn(ssh.Message().Source()).Copy(m, "option")
|
||||||
|
msg.Option("hello", "world")
|
||||||
|
msg.Option("world", "hello")
|
||||||
|
for _, k := range msg.Meta["seal"] {
|
||||||
|
for i, v := range msg.Meta[k] {
|
||||||
|
msg.Meta[k][i] = msg.Spawn(user).Cmd("seal", v).Result(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, k := range msg.Meta["encrypt"] {
|
||||||
|
for i, v := range msg.Meta[k] {
|
||||||
|
msg.Meta[k][i] = msg.Spawn(user).Cmd("encrypt", v).Result(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.Detail("send", args, "hello", arg)
|
||||||
|
ssh.Message().Back(msg)
|
||||||
|
m.Copy(msg, "result").Copy(msg, "append")
|
||||||
|
} // }}}
|
||||||
|
}},
|
||||||
"close": &ctx.Command{Name: "close", Help: "连接断开", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
"close": &ctx.Command{Name: "close", Help: "连接断开", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
m.Target().Close(m)
|
m.Target().Close(m)
|
||||||
}},
|
}},
|
||||||
|
@ -21,7 +21,8 @@ type TCP struct {
|
|||||||
func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||||
c.Caches = map[string]*ctx.Cache{
|
c.Caches = map[string]*ctx.Cache{
|
||||||
"protocol": &ctx.Cache{Name: "网络协议(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "网络协议"},
|
"protocol": &ctx.Cache{Name: "网络协议(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "网络协议"},
|
||||||
"security": &ctx.Cache{Name: "加密通信(true/false)", Value: m.Conf("security"), Help: "加密通信"},
|
"certfile": &ctx.Cache{Name: "certfile", Value: "", Help: "加密通信"},
|
||||||
|
"keyfile": &ctx.Cache{Name: "keyfile", Value: "", Help: "加密通信"},
|
||||||
"address": &ctx.Cache{Name: "网络地址", Value: "", Help: "网络地址"},
|
"address": &ctx.Cache{Name: "网络地址", Value: "", Help: "网络地址"},
|
||||||
"nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "网络地址"},
|
"nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "网络地址"},
|
||||||
"nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "网络地址"},
|
"nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "网络地址"},
|
||||||
@ -41,15 +42,17 @@ func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
m.Cap("address", m.Confx("address", arg, 1))
|
m.Cap("address", m.Confx("address", arg, 1))
|
||||||
m.Cap("security", m.Confx("security", arg, 2))
|
m.Cap("certfile", m.Confx("certfile", arg, 2))
|
||||||
m.Cap("protocol", m.Confx("protocol", arg, 3))
|
m.Cap("keyfile", m.Confx("keyfile", arg, 3))
|
||||||
|
m.Cap("protocol", m.Confx("protocol", arg, 4))
|
||||||
|
|
||||||
switch arg[0] {
|
switch arg[0] {
|
||||||
case "dial":
|
case "dial":
|
||||||
if m.Caps("security") {
|
if m.Caps("certfile") {
|
||||||
cert, e := tls.LoadX509KeyPair(m.Conf("cert"), m.Conf("key"))
|
m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp"))
|
||||||
|
cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
conf := &tls.Config{Certificates: []tls.Certificate{cert}}
|
conf := &tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
|
||||||
|
|
||||||
c, e := tls.Dial(m.Cap("protocol"), m.Cap("address"), conf)
|
c, e := tls.Dial(m.Cap("protocol"), m.Cap("address"), conf)
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
@ -74,8 +77,9 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
m.Put("option", "io", tcp.Conn).Back(m.Spawn(m.Source()))
|
m.Put("option", "io", tcp.Conn).Back(m.Spawn(m.Source()))
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
if m.Cap("security") != "false" {
|
if m.Caps("certfile") {
|
||||||
cert, e := tls.LoadX509KeyPair(m.Conf("cert"), m.Conf("key"))
|
m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp"))
|
||||||
|
cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile"))
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
conf := &tls.Config{Certificates: []tls.Certificate{cert}}
|
conf := &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user