1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-26 01:24:05 +08:00
This commit is contained in:
shaoying 2020-09-07 08:13:20 +08:00
parent dcd559d99a
commit 67c79631d5
5 changed files with 202 additions and 95 deletions

View File

@ -36,14 +36,14 @@ func _file_list(m *ice.Message, root string, name string, level int, deep bool,
}
if fs, e := ioutil.ReadDir(path.Join(root, name)); e != nil {
if f, e := os.Open(path.Join(root, name)); e == nil {
if f, e := os.Open(path.Join(root, name)); e != nil {
} else {
defer f.Close()
if b, e := ioutil.ReadAll(f); e == nil {
m.Echo(string(b))
return
}
}
m.Log(ice.LOG_WARN, "%s", e)
} else {
for _, f := range fs {
if f.Name() == "." || f.Name() == ".." {
@ -170,16 +170,18 @@ func _file_list(m *ice.Message, root string, name string, level int, deep bool,
}
}
func _file_show(m *ice.Message, name string) {
if n := m.Cmd("file_rewrite", name).Append("to"); n != "" {
m.Logs("rewrite", "from", name, "to", n)
name = n
}
// if n := m.Cmd("file_rewrite", name).Append("to"); n != "" {
// m.Logs("rewrite", "from", name, "to", n)
// name = n
// }
if strings.HasPrefix(name, "http") {
m.Cmdy("web.spide", "dev", "raw", "GET", name)
return
}
if f, e := os.OpenFile(path.Join(m.Option(DIR_ROOT), name), os.O_RDONLY, 0640); m.Assert(e) {
if f, e := os.OpenFile(path.Join(m.Option(DIR_ROOT), name), os.O_RDONLY, 0640); os.IsNotExist(e) {
m.Cmdy("web.spide", "dev", "raw", "GET", path.Join("/share/local/", name))
} else if e == nil {
defer f.Close()
if s, e := f.Stat(); m.Assert(e) {

View File

@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"os/exec"
@ -62,9 +63,37 @@ func _ssh_close(m *ice.Message, c net.Conn, channel ssh.Channel) {
defer channel.Close()
channel.Write([]byte(m.Conf(PUBLIC, "meta.goodbye")))
}
func _ssh_watch(m *ice.Message, meta map[string]string, input io.Reader, output io.Writer) {
m.Gos(m, func(m *ice.Message) {
r, w := io.Pipe()
bio := io.TeeReader(input, w)
m.Gos(m, func(m *ice.Message) {
i, buf := 0, make([]byte, 1024)
for {
n, e := bio.Read(buf[i:])
if e != nil {
break
}
switch buf[i] {
case ' ':
case '\r', '\n':
cmd := strings.TrimSpace(string(buf[:i+n]))
m.Log_IMPORT("hostname", meta["hostname"], "username", meta["username"], "cmd", cmd)
i = 0
default:
m.Debug("what %v", buf[i])
}
if i += n; i >= 1024 {
i = 0
}
}
})
io.Copy(output, r)
})
}
func _ssh_reopen(m *ice.Message, c net.Conn, channel ssh.Channel) {
}
func _ssh_handle(m *ice.Message, hostname string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) {
func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) {
m.Logs(CHANNEL, aaa.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
defer m.Logs("dischan", aaa.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr())
@ -78,6 +107,9 @@ func _ssh_handle(m *ice.Message, hostname string, c net.Conn, channel ssh.Channe
defer f.Close()
h := m.Cmdx(mdb.INSERT, m.Prefix(SESSION), "", mdb.HASH, aaa.HOSTPORT, c.RemoteAddr().String(), kit.MDB_STATUS, "open", "tty", tty.Name())
m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) {
value["channel"] = channel
})
for request := range requests {
m.Logs(REQUEST, aaa.HOSTPORT, c.RemoteAddr(), "type", request.Type)
@ -103,41 +135,67 @@ func _ssh_handle(m *ice.Message, hostname string, c net.Conn, channel ssh.Channe
list = append(list, env.Name+"="+env.Value)
case "exec":
if meta["username"] == "revert" {
n, e := channel.Write([]byte("pwd"))
n, e = channel.Write([]byte("pwd"))
n, e = channel.Write([]byte("pwd"))
n, e = channel.Write([]byte("pwd"))
n, e = channel.Write([]byte("pwd"))
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
break
}
_ssh_exec(m, shell, []string{"-c", string(request.Payload[4 : request.Payload[3]+4])}, list,
channel, func() { channel.Close() })
case "shell":
_ssh_exec(m, shell, nil, list, f, func() {
defer m.Cmd(mdb.MODIFY, m.Prefix(SESSION), "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, "close")
_ssh_close(m, c, channel)
})
m.Gos(m, func(m *ice.Message) {
r, w := io.Pipe()
bio := io.TeeReader(channel, w)
if m.Richs(SESSION, "", meta["username"], func(key string, value map[string]interface{}) {
ttyp := value["channel"].(ssh.Channel)
m.Gos(m, func(m *ice.Message) { io.Copy(channel, tty) })
_ssh_watch(m, meta, channel, ttyp)
}) != nil {
break
}
if meta["username"] == "revert" {
n, e := channel.Write([]byte("pwd"))
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
m.Debug("what %v %v", n, e)
break
} else if meta["username"] == "ssh" {
m.I, m.O = f, f
m.Render(ice.RENDER_VOID)
m.Gos(m, func(m *ice.Message) {
i, buf := 0, make([]byte, 1024)
for {
n, e := bio.Read(buf[i:])
if e != nil {
break
}
switch buf[i] {
case ' ':
case '\r', '\n':
cmd := strings.TrimSpace(string(buf[:i+n]))
m.Cmd(mdb.MODIFY, m.Prefix(SESSION), "", mdb.HASH, kit.MDB_HASH, h, "cmd", cmd)
m.Log_IMPORT(h, hostname, "cmd", cmd)
i = 0
}
if i += n; i >= 1024 {
i = 0
}
}
m.Cmdy(SOURCE, tty.Name())
_ssh_close(m, c, channel)
})
io.Copy(tty, r)
})
m.Gos(m, func(m *ice.Message) {
io.Copy(channel, tty)
})
} else {
_ssh_exec(m, shell, nil, list, f, func() {
defer m.Cmd(mdb.MODIFY, m.Prefix(SESSION), "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, "close")
_ssh_close(m, c, channel)
})
}
m.Gos(m, func(m *ice.Message) { io.Copy(channel, tty) })
_ssh_watch(m, meta, channel, tty)
}
request.Reply(true, nil)
}
@ -172,9 +230,11 @@ func _ssh_listen(m *ice.Message, hostport string) {
}
hostname := sc.Permissions.Extensions["hostname"]
username := sc.Permissions.Extensions["username"]
begin := time.Now()
h := m.Cmdx(mdb.INSERT, m.Prefix(CONNECT), "", mdb.HASH, aaa.HOSTPORT, c.RemoteAddr().String(), kit.MDB_STATUS, "connect", "hostname", hostname)
h := m.Cmdx(mdb.INSERT, m.Prefix(CONNECT), "", mdb.HASH, aaa.HOSTPORT, c.RemoteAddr().String(), kit.MDB_STATUS, "connect", "hostname", hostname, "username", username)
defer m.Cmd(mdb.MODIFY, m.Prefix(CONNECT), "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, "close", "close_time", time.Now().Format(ice.MOD_TIME), "duration", time.Now().Sub(begin).String())
sc.Permissions.Extensions["connhash"] = h
m.Gos(m, func(m *ice.Message) {
ssh.DiscardRequests(req)
@ -188,7 +248,7 @@ func _ssh_listen(m *ice.Message, hostport string) {
func(channel ssh.Channel, requests <-chan *ssh.Request) {
m.Gos(m, func(m *ice.Message) {
_ssh_handle(m, hostname, c, channel, requests)
_ssh_handle(m, sc.Permissions.Extensions, c, channel, requests)
})
}(channel, requests)
}
@ -203,23 +263,25 @@ func _ssh_config(m *ice.Message) *ssh.ServerConfig {
return m.Conf(PUBLIC, "meta.welcome")
},
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
meta, res := map[string]string{}, errors.New(ice.ErrNotAuth)
m.Richs(PUBLIC, "", kit.MDB_FOREACH, func(k string, value map[string]interface{}) {
if !strings.HasPrefix(kit.Format(value[kit.MDB_NAME]), conn.User()+"@") {
return
}
if s, e := base64.StdEncoding.DecodeString(kit.Format(value[kit.MDB_TEXT])); !m.Warn(e != nil, e) {
if pub, e := ssh.ParsePublicKey([]byte(s)); !m.Warn(e != nil) {
if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), "publickey", value[kit.MDB_NAME])
meta["hostname"] = kit.Format(value[kit.MDB_NAME])
res = nil
meta, res := map[string]string{"username": conn.User()}, errors.New(ice.ErrNotAuth)
if tcp.IPIsLocal(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), "white", conn.RemoteAddr())
res = nil
} else {
m.Richs(PUBLIC, "", kit.MDB_FOREACH, func(k string, value map[string]interface{}) {
if !strings.HasPrefix(kit.Format(value[kit.MDB_NAME]), conn.User()+"@") {
return
}
if s, e := base64.StdEncoding.DecodeString(kit.Format(value[kit.MDB_TEXT])); !m.Warn(e != nil, e) {
if pub, e := ssh.ParsePublicKey([]byte(s)); !m.Warn(e != nil) {
if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), "publickey", value[kit.MDB_NAME])
meta["hostname"] = kit.Format(value[kit.MDB_NAME])
res = nil
}
}
}
}
})
if tcp.IPIsLocal(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
res = nil
})
}
return &ssh.Permissions{Extensions: meta}, res
},
@ -284,7 +346,7 @@ func init() {
mdb.FIELDS, "time,hash,hostport,status",
)},
CONNECT: {Name: CONNECT, Help: "连接", Value: kit.Data(
mdb.FIELDS, "time,hash,hostport,status,duration,close_time,hostname",
mdb.FIELDS, "time,hash,hostport,status,duration,close_time,hostname,username",
)},
SESSION: {Name: SESSION, Help: "会话", Value: kit.Data(
mdb.FIELDS, "time,hash,hostport,status,tty,cmd",
@ -369,7 +431,7 @@ func init() {
m.Cmdy(mdb.SELECT, m.Prefix(SESSION), "", mdb.HASH, kit.MDB_HASH, arg)
}},
DIAL: {Name: "dial hash auto 登录 cmd:textarea=pwd", Help: "连接", Action: map[string]*ice.Action{
DIAL: {Name: "dial hash auto 受控 登录 cmd:textarea=pwd", Help: "连接", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create", Help: "登录", List: kit.List(
kit.MDB_INPUT, "text", kit.MDB_NAME, aaa.USERNAME, kit.MDB_VALUE, "shy",
kit.MDB_INPUT, "text", kit.MDB_NAME, aaa.HOSTPORT, kit.MDB_VALUE, "shylinux.com:22",
@ -388,6 +450,33 @@ func init() {
))
m.Echo(h)
}},
"revert": {Name: "revert", Help: "受控", List: kit.List(
kit.MDB_INPUT, "text", kit.MDB_NAME, aaa.HOSTPORT, kit.MDB_VALUE, "192.168.0.105:9030",
), Hand: func(m *ice.Message, arg ...string) {
for i := 0; i < len(arg); i += 2 {
m.Option(arg[i], arg[i+1])
}
connect, e := _ssh_dial(m, "revert", m.Option(aaa.HOSTPORT))
m.Assert(e)
h := m.Rich(DIAL, "", kit.Dict(
aaa.USERNAME, "revert",
aaa.HOSTPORT, m.Option(aaa.HOSTPORT),
CONNECT, connect,
))
session, e := connect.NewSession()
m.Assert(e)
r, w := io.Pipe()
session.Stdout = w
_ssh_watch(m, map[string]string{}, r, ioutil.Discard)
session.Start("bash")
m.Echo(h)
}},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, m.Prefix(DIAL), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))

View File

@ -67,6 +67,30 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
msg.Append(ice.MSG_OUTPUT, ice.RENDER_OUTPUT)
}
func _ssh_script(m *ice.Message, name string) io.Reader {
if strings.Contains(m.Option("_script"), "/") {
name = path.Join(path.Dir(m.Option("_script")), name)
}
m.Option("_script", name)
if s, e := os.Open(name); e == nil {
return s
}
if msg := m.Cmd("web.spide", "dev", "GET", path.Join("/share/local/", name)); msg.Result(0) != ice.ErrWarn {
bio := bytes.NewBuffer([]byte(msg.Result()))
return bio
}
if strings.HasPrefix(name, "usr") {
ls := strings.Split(name, "/")
m.Cmd("web.code.git.repos", ls[1], "usr/"+ls[1])
if s, e := os.Open(name); e == nil {
return s
}
}
return nil
}
func (f *Frame) history(m *ice.Message, line string) string {
favor := m.Conf(SOURCE, kit.Keys(kit.MDB_META, web.FAVOR))
if strings.HasPrefix(strings.TrimSpace(line), "!!") {
@ -104,7 +128,7 @@ func (f *Frame) printf(m *ice.Message, res string, arg ...interface{}) *Frame {
return f
}
func (f *Frame) prompt(m *ice.Message, list ...string) *Frame {
if f.stdout != os.Stdout {
if f.source != STDIO {
return f
}
if len(list) == 0 {
@ -292,6 +316,13 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
m.Option(ice.MSG_USERZONE, "boot")
aaa.UserRoot(m)
default:
if strings.HasPrefix(arg[0], "/dev") {
// 脚本解析
r, f.stdout = m.I, m.O
f.source, f.target = STDIO, m.Source()
m.Cap(ice.CTX_STREAM, STDIO)
break
}
if b, ok := ice.BinPack[arg[0]]; ok {
m.Debug("binpack %v %v", arg[0], len(b))
buf := bytes.NewBuffer(make([]byte, 0, 4096))
@ -304,27 +335,15 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
f.target = m.Source()
break
}
s, e := os.Open(arg[0])
if os.IsNotExist(e) && strings.HasPrefix(arg[0], "usr") {
ls := strings.Split(arg[0], "/")
m.Cmd("web.code.git.repos", ls[1], "usr/"+ls[1])
s, e = os.Open(arg[0])
}
if !m.Warn(e != nil, "%s", e) {
defer s.Close()
s := _ssh_script(m, arg[0])
buf := bytes.NewBuffer(make([]byte, 0, 4096))
defer func() { m.Echo(buf.String()) }()
buf := bytes.NewBuffer(make([]byte, 0, 4096))
defer func() { m.Echo(buf.String()) }()
// 脚本解析
f.source = arg[0]
r, f.stdout = s, buf
m.Cap(ice.CTX_STREAM, arg[0])
f.target = m.Source()
break
}
return true
// 脚本解析
r, f.stdout = s, buf
f.source, f.target = arg[0], m.Source()
m.Cap(ice.CTX_STREAM, arg[0])
}
f.scan(m, kit.Select(STDIO, arg, 0), "", r)
@ -371,10 +390,6 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块",
}},
SOURCE: {Name: "source file", Help: "脚本解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if _, e := os.Stat(arg[0]); e != nil {
arg[0] = path.Join(path.Dir(m.Option("_script")), arg[0])
}
m.Option("_script", arg[0])
m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...)
}},
TARGET: {Name: "target name", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -203,10 +203,10 @@ func init() {
// 请求地址
uri, arg := arg[0], arg[1:]
if n := m.Cmd("spide_rewrite", uri).Append("to"); n != "" && n != uri {
m.Logs("rewrite", "from", uri, "to", n)
uri = n
}
// if n := m.Cmd("spide_rewrite", uri).Append("to"); n != "" && n != uri {
// m.Logs("rewrite", "from", uri, "to", n)
// uri = n
// }
// 渲染引擎
head := map[string]string{}
@ -315,7 +315,7 @@ func init() {
// 检查结果
m.Cost("%s %s: %s", res.Status, res.Header.Get(ContentLength), res.Header.Get(ContentType))
if m.Warn(res.StatusCode != http.StatusOK, "%s", res.Status) {
if m.Warn(res.StatusCode != http.StatusOK, res.Status) {
m.Set(ice.MSG_RESULT)
// return
}

View File

@ -40,18 +40,19 @@ func _wiki_upload(m *ice.Message, cmd string) {
func reply(m *ice.Message, cmd string, arg ...string) bool {
// 文件列表
m.Option(nfs.DIR_ROOT, m.Conf(cmd, "meta.path"))
m.Option(nfs.DIR_REG, m.Conf(cmd, "meta.regs"))
m.Cmdy(nfs.DIR, kit.Select("./", arg, 0))
m.Sort("time", "time_r")
if len(arg) == 0 || strings.HasSuffix(arg[0], "/") {
m.Option("_display", "table")
if m.Option(nfs.DIR_DEEP) == "true" {
return true
}
// if m.Option(nfs.DIR_DEEP) == "true" {
// return true
// }
// 目录列表
m.Option(nfs.DIR_REG, "")
m.Option(nfs.DIR_TYPE, "dir")
m.Option(nfs.DIR_TYPE, nfs.DIR)
m.Cmdy(nfs.DIR, kit.Select("./", arg, 0))
// 文件列表
m.Option(nfs.DIR_TYPE, nfs.FILE)
m.Option(nfs.DIR_REG, m.Conf(cmd, "meta.regs"))
m.Cmdy(nfs.DIR, kit.Select("./", arg, 0))
return true
}