diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c5564f..53daf7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -76,4 +76,11 @@
3. 修正windows下的配置文件include问题
4. 支持linux远程桌面
-**注:linux受控端需使用np-cli.vnc程序进行启动,且目前无法以systemd等方式运行**
\ No newline at end of file
+**注:linux受控端需使用np-cli.vnc程序进行启动,且目前无法以systemd等系统服务方式运行**
+
+# v0.7.3
+
+1. vnc支持\键
+2. 全面迁移到[https://github.com/lwch/rdesktop](https://github.com/lwch/rdesktop),并去除robotgo库的依赖
+3. linux下统一到同一个可执行文件,并支持systemd方式启动
+4. 简化部署流程
\ No newline at end of file
diff --git a/build b/build
index 0880598..5d22e0a 100755
--- a/build
+++ b/build
@@ -1,6 +1,6 @@
#!/bin/sh
-VERSION=0.7.2
+VERSION=0.7.3
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
docker run --rm \
diff --git a/build_all b/build_all
index a7c79bd..73d210c 100755
--- a/build_all
+++ b/build_all
@@ -1,6 +1,6 @@
#!/bin/sh
-VERSION=0.7.2
+VERSION=0.7.3
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
docker run --rm \
diff --git a/code/client/global/conf.go b/code/client/global/conf.go
index 14cbf44..7c11535 100644
--- a/code/client/global/conf.go
+++ b/code/client/global/conf.go
@@ -4,6 +4,8 @@ import (
"crypto/md5"
"fmt"
"natpass/code/utils"
+ "os"
+ "path/filepath"
"time"
"github.com/lwch/runtime"
@@ -82,6 +84,11 @@ func LoadConf(dir string) *Configure {
if cfg.Link.WriteTimeout <= 0 {
cfg.Link.WriteTimeout = 5 * time.Second
}
+ if !filepath.IsAbs(cfg.Log.Dir) {
+ dir, err := os.Executable()
+ runtime.Assert(err)
+ cfg.Log.Dir = filepath.Join(filepath.Dir(dir), cfg.Log.Dir)
+ }
return &Configure{
ID: cfg.ID,
Server: cfg.Server,
diff --git a/code/client/main.go b/code/client/main.go
index 3f67044..70fa808 100644
--- a/code/client/main.go
+++ b/code/client/main.go
@@ -99,6 +99,7 @@ func main() {
switch *act {
case "install":
runtime.Assert(sv.Install())
+ utils.BuildLogDir(cfg.LogDir, *user)
case "uninstall":
runtime.Assert(sv.Uninstall())
default:
diff --git a/code/client/rule/vnc/worker/event.go b/code/client/rule/vnc/worker/event.go
index 471d360..d20c9b7 100644
--- a/code/client/rule/vnc/worker/event.go
+++ b/code/client/rule/vnc/worker/event.go
@@ -1,22 +1,100 @@
-//go:build !vnc
-// +build !vnc
-
package worker
import (
"natpass/code/client/rule/vnc/vncnetwork"
"github.com/gorilla/websocket"
+ "github.com/lwch/logging"
+ "github.com/lwch/rdesktop"
+ "google.golang.org/protobuf/proto"
)
-func runMouse(data *vncnetwork.MouseData) {
+func (worker *Worker) runMouse(data *vncnetwork.MouseData) {
+ detach, err := attachDesktop()
+ if err != nil {
+ logging.Error("attach desktop: %v", err)
+ return
+ }
+ defer detach()
+ worker.cli.MouseMove(int(data.GetX()), int(data.GetY()))
+ var button rdesktop.MouseButton
+ switch data.GetBtn() {
+ case vncnetwork.MouseData_left:
+ button = rdesktop.MouseLeft
+ case vncnetwork.MouseData_right:
+ button = rdesktop.MouseRight
+ case vncnetwork.MouseData_middle:
+ button = rdesktop.MouseMiddle
+ }
+ switch data.GetType() {
+ case vncnetwork.Status_down:
+ worker.cli.ToggleMouse(button, true)
+ case vncnetwork.Status_up:
+ worker.cli.ToggleMouse(button, false)
+ }
}
-func runKeyboard(data *vncnetwork.KeyboardData) {
+func (worker *Worker) runKeyboard(data *vncnetwork.KeyboardData) {
+ detach, err := attachDesktop()
+ if err != nil {
+ logging.Error("attach desktop: %v", err)
+ return
+ }
+ defer detach()
+ switch data.Type {
+ case vncnetwork.Status_down:
+ worker.cli.ToggleKey(data.Key, true)
+ case vncnetwork.Status_up:
+ worker.cli.ToggleKey(data.Key, false)
+ }
}
-func runScroll(data *vncnetwork.ScrollData) {
+func (worker *Worker) runScroll(data *vncnetwork.ScrollData) {
+ detach, err := attachDesktop()
+ if err != nil {
+ logging.Error("attach desktop: %v", err)
+ return
+ }
+ defer detach()
+ worker.cli.Scroll(int(data.X), int(data.Y))
}
-func runClipboard(conn *websocket.Conn, data *vncnetwork.ClipboardData) {
+func (worker *Worker) runClipboard(conn *websocket.Conn, data *vncnetwork.ClipboardData) {
+ detach, err := attachDesktop()
+ if err != nil {
+ logging.Error("attach desktop: %v", err)
+ return
+ }
+ defer detach()
+ if data.GetSet() {
+ worker.setClipboard(data)
+ } else {
+ worker.getClipboard(conn)
+ }
+}
+
+func (worker *Worker) setClipboard(data *vncnetwork.ClipboardData) {
+ switch data.GetXType() {
+ case vncnetwork.ClipboardData_file:
+ case vncnetwork.ClipboardData_image:
+ case vncnetwork.ClipboardData_text:
+ worker.cli.ClipboardSet(data.GetData())
+ }
+}
+
+func (worker *Worker) getClipboard(conn *websocket.Conn) {
+ data, _ := worker.cli.ClipboardGet()
+ var msg vncnetwork.VncMsg
+ msg.XType = vncnetwork.VncMsg_clipboard_event
+ msg.Payload = &vncnetwork.VncMsg_Clipboard{
+ Clipboard: &vncnetwork.ClipboardData{
+ Set: true,
+ XType: vncnetwork.ClipboardData_text,
+ Payload: &vncnetwork.ClipboardData_Data{
+ Data: data,
+ },
+ },
+ }
+ enc, _ := proto.Marshal(&msg)
+ conn.WriteMessage(websocket.BinaryMessage, enc)
}
diff --git a/code/client/rule/vnc/worker/event_auto.go b/code/client/rule/vnc/worker/event_auto.go
deleted file mode 100644
index bc4ed4e..0000000
--- a/code/client/rule/vnc/worker/event_auto.go
+++ /dev/null
@@ -1,103 +0,0 @@
-//go:build vnc
-// +build vnc
-
-package worker
-
-import (
- "natpass/code/client/rule/vnc/vncnetwork"
-
- "github.com/go-vgo/robotgo"
- "github.com/gorilla/websocket"
- "github.com/lwch/logging"
- "google.golang.org/protobuf/proto"
-)
-
-func runMouse(data *vncnetwork.MouseData) {
- detach, err := attachDesktop()
- if err != nil {
- logging.Error("attach desktop: %v", err)
- return
- }
- defer detach()
- robotgo.MoveMouse(int(data.GetX()), int(data.GetY()))
- var key string
- switch data.GetBtn() {
- case vncnetwork.MouseData_left:
- key = "left"
- case vncnetwork.MouseData_right:
- key = "right"
- case vncnetwork.MouseData_middle:
- key = "center"
- }
- switch data.GetType() {
- case vncnetwork.Status_down:
- robotgo.MouseToggle("down", key)
- case vncnetwork.Status_up:
- robotgo.MouseToggle("up", key)
- }
-}
-
-func runKeyboard(data *vncnetwork.KeyboardData) {
- detach, err := attachDesktop()
- if err != nil {
- logging.Error("attach desktop: %v", err)
- return
- }
- defer detach()
- switch data.Type {
- case vncnetwork.Status_down:
- robotgo.KeyToggle(data.Key, "down")
- case vncnetwork.Status_up:
- robotgo.KeyToggle(data.Key, "up")
- }
-}
-
-func runScroll(data *vncnetwork.ScrollData) {
- detach, err := attachDesktop()
- if err != nil {
- logging.Error("attach desktop: %v", err)
- return
- }
- defer detach()
- robotgo.Scroll(int(data.X), int(data.Y), 1)
-}
-
-func runClipboard(conn *websocket.Conn, data *vncnetwork.ClipboardData) {
- detach, err := attachDesktop()
- if err != nil {
- logging.Error("attach desktop: %v", err)
- return
- }
- defer detach()
- if data.GetSet() {
- setClipboard(data)
- } else {
- getClipboard(conn)
- }
-}
-
-func setClipboard(data *vncnetwork.ClipboardData) {
- switch data.GetXType() {
- case vncnetwork.ClipboardData_file:
- case vncnetwork.ClipboardData_image:
- case vncnetwork.ClipboardData_text:
- robotgo.WriteAll(data.GetData())
- }
-}
-
-func getClipboard(conn *websocket.Conn) {
- data, _ := robotgo.ReadAll()
- var msg vncnetwork.VncMsg
- msg.XType = vncnetwork.VncMsg_clipboard_event
- msg.Payload = &vncnetwork.VncMsg_Clipboard{
- Clipboard: &vncnetwork.ClipboardData{
- Set: true,
- XType: vncnetwork.ClipboardData_text,
- Payload: &vncnetwork.ClipboardData_Data{
- Data: data,
- },
- },
- }
- enc, _ := proto.Marshal(&msg)
- conn.WriteMessage(websocket.BinaryMessage, enc)
-}
diff --git a/code/client/rule/vnc/worker/worker.go b/code/client/rule/vnc/worker/worker.go
index 9463750..e46c4c1 100644
--- a/code/client/rule/vnc/worker/worker.go
+++ b/code/client/rule/vnc/worker/worker.go
@@ -23,6 +23,7 @@ func NewWorker(showCursor bool) *Worker {
worker := &Worker{}
cli, err := rdesktop.New()
if err != nil {
+ logging.Error("create rdesktop: %v", err)
return nil
}
worker.cli = cli
@@ -57,15 +58,15 @@ func (worker *Worker) Do(conn *websocket.Conn) {
enc, _ := proto.Marshal(&msg)
conn.WriteMessage(websocket.BinaryMessage, enc)
case vncnetwork.VncMsg_mouse_event:
- runMouse(msg.GetMouse())
+ worker.runMouse(msg.GetMouse())
case vncnetwork.VncMsg_keyboard_event:
- runKeyboard(msg.GetKeyboard())
+ worker.runKeyboard(msg.GetKeyboard())
case vncnetwork.VncMsg_set_cursor:
worker.cli.ShowCursor(msg.GetShowCursor())
case vncnetwork.VncMsg_scroll_event:
- runScroll(msg.GetScroll())
+ worker.runScroll(msg.GetScroll())
case vncnetwork.VncMsg_clipboard_event:
- runClipboard(conn, msg.GetClipboard())
+ worker.runClipboard(conn, msg.GetClipboard())
}
}
}
diff --git a/code/server/global/conf.go b/code/server/global/conf.go
index 7dfde98..7ddba0d 100644
--- a/code/server/global/conf.go
+++ b/code/server/global/conf.go
@@ -3,6 +3,8 @@ package global
import (
"crypto/md5"
"natpass/code/utils"
+ "os"
+ "path/filepath"
"time"
"github.com/lwch/runtime"
@@ -42,6 +44,11 @@ func LoadConf(dir string) *Configure {
} `yaml:"tls"`
}
runtime.Assert(yaml.Decode(dir, &cfg))
+ if !filepath.IsAbs(cfg.Log.Dir) {
+ dir, err := os.Executable()
+ runtime.Assert(err)
+ cfg.Log.Dir = filepath.Join(filepath.Dir(dir), cfg.Log.Dir)
+ }
return &Configure{
Listen: cfg.Listen,
Enc: md5.Sum([]byte(cfg.Secret)),
diff --git a/code/server/main.go b/code/server/main.go
index edc5ffe..efee3d4 100644
--- a/code/server/main.go
+++ b/code/server/main.go
@@ -6,6 +6,7 @@ import (
"fmt"
"natpass/code/server/global"
"natpass/code/server/handler"
+ "natpass/code/utils"
"net"
"os"
"path/filepath"
@@ -102,6 +103,7 @@ func main() {
switch *act {
case "install":
runtime.Assert(sv.Install())
+ utils.BuildLogDir(cfg.LogDir, *user)
case "uninstall":
runtime.Assert(sv.Uninstall())
default:
diff --git a/code/utils/utils.go b/code/utils/utils.go
new file mode 100644
index 0000000..e263e2e
--- /dev/null
+++ b/code/utils/utils.go
@@ -0,0 +1,21 @@
+package utils
+
+import (
+ "os"
+ "os/user"
+ "strconv"
+
+ "github.com/lwch/runtime"
+)
+
+// BuildLogDir mkdir for log and chown
+func BuildLogDir(dir, u string) {
+ runtime.Assert(os.MkdirAll(dir, 0755))
+ if len(u) > 0 {
+ us, err := user.Lookup(u)
+ runtime.Assert(err)
+ uid, _ := strconv.ParseInt(us.Uid, 10, 64)
+ gid, _ := strconv.ParseInt(us.Gid, 10, 64)
+ runtime.Assert(os.Chown(dir, int(uid), int(gid)))
+ }
+}
diff --git a/conf/client.yaml b/conf/client.yaml
index 43738c9..ce5915b 100644
--- a/conf/client.yaml
+++ b/conf/client.yaml
@@ -4,6 +4,6 @@ dashboard: # web面板
enabled: true # 是否开放dashboard
listen: 0.0.0.0 # 监听地址
port: 8080 # 监听端口号
-#include conf.d/*.yaml
+#include common.yaml
rules: # rule列表
#include rule.d/*.yaml
\ No newline at end of file
diff --git a/conf/common.yaml b/conf/common.yaml
new file mode 100644
index 0000000..064d65f
--- /dev/null
+++ b/conf/common.yaml
@@ -0,0 +1,9 @@
+secret: 0123456789 # 预共享密钥,否则握手失败
+link:
+ connections: 3 # 连接数,仅client有效
+ read_timeout: 1s # 读取数据包超时时间
+ write_timeout: 1s # 发送数据包超时时间
+log:
+ dir: ./logs # 路径,相对于可执行文件所在目录的相对路径
+ size: 50M # 单个文件大小
+ rotate: 7 # 保留数量
\ No newline at end of file
diff --git a/conf/conf.d/conn.yaml b/conf/conf.d/conn.yaml
deleted file mode 100644
index c1eb316..0000000
--- a/conf/conf.d/conn.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-secret: 0123456789 # 预共享密钥,否则握手失败
-link:
- connections: 3 # 连接数,仅client有效
- read_timeout: 1s # 读取数据包超时时间
- write_timeout: 1s # 发送数据包超时时间
\ No newline at end of file
diff --git a/conf/conf.d/log.yaml b/conf/conf.d/log.yaml
deleted file mode 100644
index 836bfd7..0000000
--- a/conf/conf.d/log.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-log:
- dir: ./logs # 路径
- size: 50M # 单个文件大小
- rotate: 7 # 保留数量
\ No newline at end of file
diff --git a/conf/server.yaml b/conf/server.yaml
index 36a9d5c..051eb90 100644
--- a/conf/server.yaml
+++ b/conf/server.yaml
@@ -1,5 +1,5 @@
listen: 6154 # 监听端口号
-#include conf.d/*.yaml
+#include common.yaml
tls:
key: /dir/to/tls/key/file # tls密钥
crt: /dir/to/tls/crt/file # tls证书
\ No newline at end of file
diff --git a/contrib/build/Dockerfile b/contrib/build/Dockerfile
index 6ad67d3..e08fb1f 100644
--- a/contrib/build/Dockerfile
+++ b/contrib/build/Dockerfile
@@ -1,6 +1,6 @@
ARG APT_MIRROR=mirrors.ustc.edu.cn
ARG LIBPNG_VERSION=1.6.37
-ARG GO_VERSION=1.17.4
+ARG GO_VERSION=1.17.5
ARG GO_PROXY=https://goproxy.cn,direct
# build libpng
diff --git a/contrib/build/build_all.go b/contrib/build/build_all.go
index d3b2abc..b6ddabe 100644
--- a/contrib/build/build_all.go
+++ b/contrib/build/build_all.go
@@ -167,8 +167,8 @@ func build(t target) {
ldflags := "-X 'main.gitHash=" + gitHash() + "' " +
"-X 'main.gitReversion=" + gitReversion() + "' " +
"-X 'main.buildTime=" + buildTime() + "' " +
- "-X 'main.version=" + version + "' " +
- "--extldflags '-static -fpic -lssp'"
+ "-X 'main.version=" + version + "' "
+ // "--extldflags '-static -fpic -lssp'"
logging.Info("build server...")
cmd := exec.Command("go", "build", "-o", path.Join(buildDir, "np-svr"+t.ext),
@@ -190,7 +190,8 @@ func build(t target) {
fmt.Sprintf("CXX=%s", t.cxx))
args := []string{"build", "-o", path.Join(buildDir, "np-cli"+t.ext), "-ldflags", ldflags}
if t.os == "windows" && !strings.Contains(t.arch, "arm") {
- args = append(args, "-tags", "vnc")
+ env = append(env, "CGO_ENABLED=1")
+ } else if t.os == "linux" && !strings.Contains(t.arch, "arm") {
env = append(env, "CGO_ENABLED=1")
}
args = append(args,
@@ -201,27 +202,6 @@ func build(t target) {
cmd.Env = env
runtime.Assert(cmd.Run())
- if t.os == "linux" && !strings.Contains(t.arch, "arm") {
- ldflags := "-X 'main.gitHash=" + gitHash() + "' " +
- "-X 'main.gitReversion=" + gitReversion() + "' " +
- "-X 'main.buildTime=" + buildTime() + "' " +
- "-X 'main.version=" + version + "'"
- logging.Info("build client.vnc...")
- env := append(os.Environ(),
- fmt.Sprintf("GOOS=%s", t.os),
- fmt.Sprintf("GOARCH=%s", t.arch))
- args := []string{"build", "-o", path.Join(buildDir, "np-cli.vnc"), "-ldflags", ldflags}
- args = append(args, "-tags", "vnc")
- env = append(env, "CGO_ENABLED=1")
- args = append(args,
- path.Join("code", "client", "main.go"))
- cmd = exec.Command("go", args...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Env = env
- runtime.Assert(cmd.Run())
- }
-
logging.Info("packing...")
pack(buildDir, path.Join(releaseDir, "natpass_"+version+"_"+t.os+"_"+t.arch+t.packExt))
}
diff --git a/docs/startup.md b/docs/startup.md
index f18cff4..fe88a70 100644
--- a/docs/startup.md
+++ b/docs/startup.md
@@ -9,20 +9,14 @@
1. 在服务器上[下载](https://github.com/lwch/natpass/releases)并解压到任意目录
2. 修改server.yaml配置文件,设置*key*和*crt*参数到你的证书所在路径
-3. 修改conf.d/conn.yaml配置文件,修改*secret*密钥,建议使用以下命令生成随机16位密钥
+3. 修改common.yaml配置文件,修改*secret*密钥,建议使用以下命令生成随机16位密钥
tr -dc A-Za-z0-9 < /dev/urandom|dd bs=16 count=1 2>/dev/null
-4. 修改conf.d/log.yaml配置文件,将log目录设置为一个绝对路径
-5. 使用以下命令将np-svr注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份(建议使用nobody身份启动)
+4. 使用以下命令将np-svr注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份(建议使用nobody身份启动)
sudo ./np-svr -conf server.yaml -action install -user nobody
-6. 手动创建第4步中设置的log目录,并将其属主设置为nobody
+5. 启动服务
- sudo mkdir -p
- sudo chown -R nobody
-7. 将该服务设置为系统启动项,并启动服务
-
- sudo systemctl enable np-svr
sudo systemctl start np-svr
## 受控端部署
@@ -31,43 +25,26 @@
2. 修改client.yaml配置文件,设置*id*为remote,设置*server*地址,并删除以下配置
#include rule.d/*.yaml
-3. 修改conf.d/conn.yaml配置文件,修改*secret*密钥,该密钥必须与服务器端保持一致
-4. 修改conf.d/log.yaml配置文件,将log目录设置为一个绝对路径
-5. 使用以下命令将np-cli注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份(建议使用nobody身份启动)
+3. 修改common.yaml配置文件,修改*secret*密钥,该密钥必须与服务器端保持一致
+4. 使用以下命令将np-cli注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份
+ sudo ./np-cli -conf client.yaml -action install -user `whoami`
+5. 启动服务
- sudo ./np-cli -conf client.yaml -action install -user nobody
-6. 手动创建第4步中设置的log目录,并将其属主设置为nobody
-
- sudo mkdir -p
- sudo chown -R nobody
-7. 将该服务设置为系统启动项,并启动服务
-
- sudo systemctl enable np-cli
sudo systemctl start np-cli
-**注:当受控端为linux操作系统时,请使用np-cli.vnc程序进行启动,暂不支持系统服务方式启动,手工启动命令如下**
-
- ./np-cli -conf client.yaml
-
## 控制端部署
1. 在本地控制机上[下载](https://github.com/lwch/natpass/releases)并解压到任意目录
2. 修改client.yaml配置文件,设置*id*为local,设置*server*地址
-3. 修改conf.d/conn.yaml配置文件,修改*secret*密钥,该密钥必须与服务器端保持一致
-4. 修改conf.d/log.yaml配置文件,将log目录设置为一个绝对路径
-5. 修改rule.d目录下的规则配置文件,[rule配置方法](rules.md)
-6. 使用以下命令将np-cli注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份(建议使用nobody身份启动)
+3. 修改common.yaml配置文件,修改*secret*密钥,该密钥必须与服务器端保持一致
+4. 修改rule.d目录下的规则配置文件,[rule配置方法](rules.md)
+5. 使用以下命令将np-cli注册为系统服务,其中-conf参数后跟配置文件所在路径,-user参数后为程序启动身份(建议使用nobody身份启动)
sudo ./np-cli -conf client.yaml -action install -user nobody
-7. 手动创建第4步中设置的log目录,并将其属主设置为nobody
+6. 启动服务
- sudo mkdir -p
- sudo chown -R nobody
-8. 将该服务设置为系统启动项,并启动服务
-
- sudo systemctl enable np-cli
sudo systemctl start np-cli
-9. 在以上操作成功后即可在浏览器中通过client.yaml中配置的端口号进行访问,默认地址:
+7. 在以上操作成功后即可在浏览器中通过client.yaml中配置的端口号进行访问,默认地址:
http://127.0.0.1:8080
diff --git a/go.mod b/go.mod
index 9d4f2f0..e64f257 100644
--- a/go.mod
+++ b/go.mod
@@ -6,20 +6,16 @@ require (
github.com/creack/pty v1.1.17
github.com/dustin/go-humanize v1.0.0
github.com/go-bindata/go-bindata/v3 v3.1.3
- github.com/go-vgo/robotgo v0.100.9
github.com/gorilla/websocket v1.4.2
github.com/kardianos/service v1.2.0
github.com/kisielk/errcheck v1.6.0 // indirect
github.com/lwch/logging v0.0.0-20211203094902-ecb971ed7cdc
- github.com/lwch/rdesktop v0.0.0-20211207101551-b892a4a5e2b5
+ github.com/lwch/rdesktop v0.0.0-20211229040606-1ab25b15434c
github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d
github.com/lwch/yaml v0.0.0-20211206085137-772f80e85a26
- github.com/shirou/gopsutil v3.21.11+incompatible // indirect
- github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.5.1 // indirect
- golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
+ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
golang.org/x/text v0.3.7
- golang.org/x/tools v0.1.7 // indirect
+ golang.org/x/tools v0.1.8 // indirect
google.golang.org/protobuf v1.27.1
)
diff --git a/go.sum b/go.sum
index d159254..6e6537c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,20 +1,9 @@
-github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
-github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
-github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/go-bindata/go-bindata/v3 v3.1.3 h1:F0nVttLC3ws0ojc7p60veTurcOm//D4QBODNM7EGrCI=
github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7NhEvIN9+Z6R5/xH4I=
-github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
-github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/go-vgo/robotgo v0.100.9 h1:dgt4qaxBw6+vg4P5tUeH26VsL5M0v/IRwRmkingZ2YU=
-github.com/go-vgo/robotgo v0.100.9/go.mod h1:7QeIpSHX7bjeXWRPxvQeKSx9mHI+3l80Ahq+CQF0C68=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -28,88 +17,48 @@ github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/lwch/logging v0.0.0-20211115073745-0db19179db17/go.mod h1:aXQui5bsF/d4I+z6szuiBWY5m4y9t6pyZ2Q/sLgkBBg=
github.com/lwch/logging v0.0.0-20211203094902-ecb971ed7cdc h1:QHC/AggBsu39IWcbzjgIc2ApNXuWhZhD1ieCkFgWfeM=
github.com/lwch/logging v0.0.0-20211203094902-ecb971ed7cdc/go.mod h1:aXQui5bsF/d4I+z6szuiBWY5m4y9t6pyZ2Q/sLgkBBg=
-github.com/lwch/rdesktop v0.0.0-20211207101551-b892a4a5e2b5 h1:RF5uIUO37p6WVgqd3mrkPLYNvJCBHs9sOpBsbTYdzO4=
-github.com/lwch/rdesktop v0.0.0-20211207101551-b892a4a5e2b5/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
+github.com/lwch/rdesktop v0.0.0-20211229023040-e12f4166b311 h1:myjL50IJ8WXVOLlNnrZU/Dj1D0g8DQrT4N36axMccYg=
+github.com/lwch/rdesktop v0.0.0-20211229023040-e12f4166b311/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
+github.com/lwch/rdesktop v0.0.0-20211229032819-c130bc8f29af h1:RDKhLIR9CpjuJebkYMja9Zj4RlESJ7WVxba5r3KFhWo=
+github.com/lwch/rdesktop v0.0.0-20211229032819-c130bc8f29af/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
+github.com/lwch/rdesktop v0.0.0-20211229035251-e2ccadf35f97 h1:LuszXjKntydv39X2afm9aK0dLiUGSu9jqC0HcMZqtYI=
+github.com/lwch/rdesktop v0.0.0-20211229035251-e2ccadf35f97/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
+github.com/lwch/rdesktop v0.0.0-20211229035721-f527d0bcd64c h1:jIoEdoB+hBeH6Xo7cS3jcJF9ed0l+b8wM06TGVSBV2U=
+github.com/lwch/rdesktop v0.0.0-20211229035721-f527d0bcd64c/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
+github.com/lwch/rdesktop v0.0.0-20211229040606-1ab25b15434c h1:P8L8xYlrQx7mUuWnQpnUeWNabqwQYMyhNtrSmLdGRTE=
+github.com/lwch/rdesktop v0.0.0-20211229040606-1ab25b15434c/go.mod h1:vZtkNUaG1bDuzJavu8OQQoBbHVS6cYJE7y4oxtmhYYM=
github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d h1:Xg+zzPtvX22DaoJD5Bp0tqPdB8gn5WypghIJ4fluqiQ=
github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d/go.mod h1:uEt0zu1MDC7WnVvodPBGSYAD/KMKk0v36xE8UE5veM8=
github.com/lwch/yaml v0.0.0-20211206085137-772f80e85a26 h1:sR3nbPhdfstDxYLp7c1EnsKH3z8+u+wgnhC3AI9/qf0=
github.com/lwch/yaml v0.0.0-20211206085137-772f80e85a26/go.mod h1:Dz0eixDQvioB5pqCXGQJ6sTJetbS6TCHegLuRh2Bw2U=
-github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
-github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
-github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
-github.com/otiai10/gosseract v2.2.1+incompatible h1:Ry5ltVdpdp4LAa2bMjsSJH34XHVOV7XMi41HtzL8X2I=
-github.com/otiai10/gosseract v2.2.1+incompatible/go.mod h1:XrzWItCzCpFRZ35n3YtVTgq5bLAhFIkascoRo8G32QE=
-github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc=
-github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/robotn/gohook v0.31.3 h1:kGX8iukJ9ensVRwRKnTtdojAMQOpa6KFnXDi4OA4RaI=
-github.com/robotn/gohook v0.31.3/go.mod h1:wyGik0yb4iwCfJjDprtNkTyxkgQWuKoVPQ3hkz6+6js=
-github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934 h1:2lhSR8N3T6I30q096DT7/5AKEIcf1vvnnWAmS0wfnNY=
-github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
-github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770 h1:2uX8QRLkkxn2EpAQ6I3KhA79BkdRZfvugJUzJadiJwk=
-github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU=
-github.com/shirou/gopsutil v3.21.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
-github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
-github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
-github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
-github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
-github.com/vcaesar/gops v0.21.3 h1:VR7amkxVv9CQfsotkXrmMyT19dVuNTa1PM/oopJeIc0=
-github.com/vcaesar/gops v0.21.3/go.mod h1:3e2EnlZTI9/44bqzRwkeZ3s0ZQwK2Cn4QPLx8Ii8Agk=
-github.com/vcaesar/imgo v0.30.0 h1:ODQVX0EFJEh+WkKahCBtE0SqcDCIjl/kjiOplR0Ouh8=
-github.com/vcaesar/imgo v0.30.0/go.mod h1:8TGnt5hjaMgwDByvMFIzUDSh5uSea4n1tAbSvnhvA6U=
-github.com/vcaesar/keycode v0.10.0 h1:Qx5QE8ZXHyRyjoA2QOxBp25OKMKB+zxMVqm0FWGV0d4=
-github.com/vcaesar/keycode v0.10.0/go.mod h1:JNlY7xbKsh+LAGfY2j4M3znVrGEm5W1R8s/Uv6BJcfQ=
-github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA=
-github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
-golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
-golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc=
-golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
@@ -119,8 +68,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
-golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
+golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -131,6 +80,5 @@ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+Rur
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/html/vnc/index.js b/html/vnc/index.js
index 42669c2..cdbf6eb 100644
--- a/html/vnc/index.js
+++ b/html/vnc/index.js
@@ -201,6 +201,8 @@ var page = {
key = '[';
} else if (e.which == 221) {
key = ']';
+ } else if (e.which == 220) {
+ key = '\\';
} else if (e.which == 186) {
key = ';';
} else if (e.which == 222) {