mirror of
https://github.com/lwch/natpass.git
synced 2026-10-21 09:39:10 +00:00
+10
-1
@@ -67,4 +67,13 @@
|
||||
|
||||
# v0.7.1
|
||||
|
||||
1. vnc页面支持远程设置或读取剪贴板(仅支持文本内容)
|
||||
1. vnc页面支持远程设置或读取剪贴板(仅支持文本内容)
|
||||
|
||||
# v0.7.2
|
||||
|
||||
1. 截屏库统一抽取到https://github.com/lwch/rdesktop
|
||||
2. 修正windows下的错误日志显示格式问题
|
||||
3. 修正windows下的配置文件include问题
|
||||
4. 支持linux远程桌面
|
||||
|
||||
**注:linux受控端需使用np-cli.vnc程序进行启动,且目前无法以systemd等方式运行**
|
||||
@@ -59,6 +59,18 @@ windows11远程桌面
|
||||
|
||||

|
||||
|
||||
ubuntu远程桌面
|
||||
|
||||

|
||||
|
||||
fedora远程桌面
|
||||
|
||||

|
||||
|
||||
deepin远程桌面
|
||||
|
||||

|
||||
|
||||
windows读取剪贴板内容
|
||||
|
||||

|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION=0.7.1
|
||||
VERSION=0.7.2
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
|
||||
docker run --rm \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION=0.7.1
|
||||
VERSION=0.7.2
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
|
||||
docker run --rm \
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package define
|
||||
|
||||
import "syscall"
|
||||
|
||||
var (
|
||||
libGdi32, _ = syscall.LoadLibrary("Gdi32.dll")
|
||||
// FuncGetDeviceCaps https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps
|
||||
FuncGetDeviceCaps, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "GetDeviceCaps")
|
||||
// FuncCreateCompatibleDC https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatibledc
|
||||
FuncCreateCompatibleDC, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "CreateCompatibleDC")
|
||||
// FuncCreateCompatibleBitmap https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatiblebitmap
|
||||
FuncCreateCompatibleBitmap, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "CreateCompatibleBitmap")
|
||||
// FuncSelectObject https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject
|
||||
FuncSelectObject, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "SelectObject")
|
||||
// FuncDeleteDC https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-deletedc
|
||||
FuncDeleteDC, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "DeleteDC")
|
||||
// FuncDeleteObject https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-deleteobject
|
||||
FuncDeleteObject, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "DeleteObject")
|
||||
// FuncBitBlt https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-bitblt
|
||||
FuncBitBlt, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "BitBlt")
|
||||
// FuncGetDIBits https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdibits
|
||||
FuncGetDIBits, _ = syscall.GetProcAddress(syscall.Handle(libGdi32), "GetDIBits")
|
||||
)
|
||||
|
||||
const (
|
||||
// HORZRES https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps
|
||||
HORZRES = 8
|
||||
// VERTRES https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps
|
||||
VERTRES = 10
|
||||
// BITSPIXEL https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps
|
||||
BITSPIXEL = 12
|
||||
)
|
||||
|
||||
const (
|
||||
// SRCCOPY https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-bitblt
|
||||
SRCCOPY = 0x00CC0020
|
||||
)
|
||||
|
||||
const (
|
||||
// BIRGB https://docs.microsoft.com/en-us/previous-versions/dd183376(v=vs.85)
|
||||
BIRGB = 0
|
||||
// DIBRGBCOLORS https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdibits
|
||||
DIBRGBCOLORS = 0
|
||||
)
|
||||
@@ -6,24 +6,7 @@ var (
|
||||
libKernel32, _ = syscall.LoadLibrary("kernel32.dll")
|
||||
// FuncWTSGetActiveConsoleSessionID https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-wtsgetactiveconsolesessionid
|
||||
FuncWTSGetActiveConsoleSessionID, _ = syscall.GetProcAddress(syscall.Handle(libKernel32), "WTSGetActiveConsoleSessionId")
|
||||
// FuncGlobalAlloc https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
FuncGlobalAlloc, _ = syscall.GetProcAddress(syscall.Handle(libKernel32), "GlobalAlloc")
|
||||
// FuncGlobalFree https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalfree
|
||||
FuncGlobalFree, _ = syscall.GetProcAddress(syscall.Handle(libKernel32), "GlobalFree")
|
||||
)
|
||||
|
||||
// PROCESSALLACCESS https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
||||
const PROCESSALLACCESS = 0x1F0FFF
|
||||
|
||||
const (
|
||||
// GHND https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
GHND = 0x0042
|
||||
// GMEMFIXED https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
GMEMFIXED = 0x0000
|
||||
// GMEMMOVEABLE https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
GMEMMOVEABLE = 0x0002
|
||||
// GMEMZEROINIT https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
GMEMZEROINIT = 0x0040
|
||||
// GPTR https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc
|
||||
GPTR = 0x0040
|
||||
)
|
||||
|
||||
@@ -4,67 +4,12 @@ import "syscall"
|
||||
|
||||
var (
|
||||
libUser32, _ = syscall.LoadLibrary("user32.dll")
|
||||
// FuncGetThreadDesktop https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddesktop
|
||||
FuncGetThreadDesktop, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetThreadDesktop")
|
||||
// FuncOpenInputDesktop https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-openinputdesktop
|
||||
FuncOpenInputDesktop, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "OpenInputDesktop")
|
||||
// FuncSetThreadDesktop https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setthreaddesktop
|
||||
FuncSetThreadDesktop, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "SetThreadDesktop")
|
||||
// FuncGetThreadDesktop https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getthreaddesktop
|
||||
FuncGetThreadDesktop, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetThreadDesktop")
|
||||
// FuncCloseDesktop https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-closedesktop
|
||||
FuncCloseDesktop, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "CloseDesktop")
|
||||
// FuncGetDesktopWindow https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdesktopwindow
|
||||
FuncGetDesktopWindow, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetDesktopWindow")
|
||||
// FuncGetDC https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc
|
||||
FuncGetDC, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetDC")
|
||||
// FuncReleaseDC https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-releasedc
|
||||
FuncReleaseDC, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "ReleaseDC")
|
||||
// FuncGetCursorInfo https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcursorinfo
|
||||
FuncGetCursorInfo, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetCursorInfo")
|
||||
// FuncGetIconInfo https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-geticoninfo
|
||||
FuncGetIconInfo, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "GetIconInfo")
|
||||
// FuncDrawIcon https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawicon
|
||||
FuncDrawIcon, _ = syscall.GetProcAddress(syscall.Handle(libUser32), "DrawIcon")
|
||||
)
|
||||
|
||||
type (
|
||||
// HANDLE handle object
|
||||
HANDLE uintptr
|
||||
// BOOL bool
|
||||
BOOL int32
|
||||
// DWORD double word
|
||||
DWORD uint32
|
||||
// LONG long
|
||||
LONG int32
|
||||
// HCURSOR cursor handle
|
||||
HCURSOR HANDLE
|
||||
// HBITMAP bitmap handle
|
||||
HBITMAP HANDLE
|
||||
)
|
||||
|
||||
// POINT pointer
|
||||
type POINT struct {
|
||||
X LONG
|
||||
Y LONG
|
||||
}
|
||||
|
||||
// CURSORINFO cursor info
|
||||
type CURSORINFO struct {
|
||||
CbSize DWORD
|
||||
Flags DWORD
|
||||
HCursor HCURSOR
|
||||
PTScreenPos POINT
|
||||
}
|
||||
|
||||
// ICONINFO icon info
|
||||
type ICONINFO struct {
|
||||
FIcon BOOL
|
||||
XHotspot DWORD
|
||||
YHotspot DWORD
|
||||
HbmMask HBITMAP
|
||||
HbmColor HBITMAP
|
||||
}
|
||||
|
||||
const (
|
||||
// CURSORSHOWING https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cursorinfo
|
||||
CURSORSHOWING = 0x00000001
|
||||
)
|
||||
|
||||
@@ -3,12 +3,15 @@ package process
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"natpass/code/client/rule/vnc/vncnetwork"
|
||||
"natpass/code/utils"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/lwch/logging"
|
||||
@@ -112,3 +115,61 @@ func (p *Process) kill() {
|
||||
ps.Kill()
|
||||
}
|
||||
}
|
||||
|
||||
// Close close process
|
||||
func (p *Process) Close() {
|
||||
if p.srv != nil {
|
||||
p.srv.Close()
|
||||
}
|
||||
if p.chImage != nil {
|
||||
close(p.chImage)
|
||||
p.chImage = nil
|
||||
}
|
||||
if p.chClipboard != nil {
|
||||
close(p.chClipboard)
|
||||
p.chClipboard = nil
|
||||
}
|
||||
if p.chWrite != nil {
|
||||
close(p.chWrite)
|
||||
p.chWrite = nil
|
||||
}
|
||||
p.kill()
|
||||
}
|
||||
|
||||
// Capture capture desktop image
|
||||
func (p *Process) Capture(timeout time.Duration) (*image.RGBA, error) {
|
||||
var msg vncnetwork.VncMsg
|
||||
msg.XType = vncnetwork.VncMsg_capture_req
|
||||
p.chWrite <- &msg
|
||||
trans := func(data *vncnetwork.ImageData) *image.RGBA {
|
||||
img := image.NewRGBA(image.Rect(0, 0, int(data.GetWidth()), int(data.GetHeight())))
|
||||
copy(img.Pix, data.GetData())
|
||||
// dumpImage(img)
|
||||
return img
|
||||
}
|
||||
if timeout > 0 {
|
||||
select {
|
||||
case data := <-p.chImage:
|
||||
return trans(data), nil
|
||||
case <-time.After(timeout):
|
||||
return nil, errors.New("timeout")
|
||||
}
|
||||
} else {
|
||||
data := <-p.chImage
|
||||
return trans(data), nil
|
||||
}
|
||||
}
|
||||
|
||||
func dumpImage(img image.Image) {
|
||||
f, err := os.Create(`C:\Users\lwch\Pictures\debug.jpeg`)
|
||||
if err != nil {
|
||||
logging.Error("debug: %v", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
err = jpeg.Encode(f, img, nil)
|
||||
if err != nil {
|
||||
logging.Error("encode: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package process
|
||||
|
||||
// CreateWorker create worker process
|
||||
func CreateWorker(name, confDir string, showCursor bool) (*Process, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"natpass/code/client/rule/vnc/vncnetwork"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// CreateWorker create worker process
|
||||
func CreateWorker(name, confDir string, showCursor bool) (*Process, error) {
|
||||
dir, err := os.Executable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var p Process
|
||||
p.chWrite = make(chan *vncnetwork.VncMsg)
|
||||
p.chImage = make(chan *vncnetwork.ImageData)
|
||||
p.chClipboard = make(chan *vncnetwork.ClipboardData)
|
||||
port, err := p.listenAndServe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command(dir, "-conf", confDir,
|
||||
"-action", "vnc.worker",
|
||||
"-name", name,
|
||||
"-vport", fmt.Sprintf("%d", port))
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
p.Close()
|
||||
return nil, err
|
||||
}
|
||||
return &p, nil
|
||||
}
|
||||
@@ -1,20 +1,15 @@
|
||||
package process
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"natpass/code/client/rule/vnc/define"
|
||||
"natpass/code/client/rule/vnc/vncnetwork"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"github.com/lwch/logging"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
@@ -123,61 +118,3 @@ func createWorker(name, confDir string, tk windows.Token, showCursor bool) (*Pro
|
||||
p.pid = int(process.ProcessId)
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// Close close process
|
||||
func (p *Process) Close() {
|
||||
if p.srv != nil {
|
||||
p.srv.Close()
|
||||
}
|
||||
if p.chImage != nil {
|
||||
close(p.chImage)
|
||||
p.chImage = nil
|
||||
}
|
||||
if p.chClipboard != nil {
|
||||
close(p.chClipboard)
|
||||
p.chClipboard = nil
|
||||
}
|
||||
if p.chWrite != nil {
|
||||
close(p.chWrite)
|
||||
p.chWrite = nil
|
||||
}
|
||||
p.kill()
|
||||
}
|
||||
|
||||
// Capture capture desktop image
|
||||
func (p *Process) Capture(timeout time.Duration) (*image.RGBA, error) {
|
||||
var msg vncnetwork.VncMsg
|
||||
msg.XType = vncnetwork.VncMsg_capture_req
|
||||
p.chWrite <- &msg
|
||||
trans := func(data *vncnetwork.ImageData) *image.RGBA {
|
||||
img := image.NewRGBA(image.Rect(0, 0, int(data.GetWidth()), int(data.GetHeight())))
|
||||
copy(img.Pix, data.GetData())
|
||||
// dumpImage(img)
|
||||
return img
|
||||
}
|
||||
if timeout > 0 {
|
||||
select {
|
||||
case data := <-p.chImage:
|
||||
return trans(data), nil
|
||||
case <-time.After(timeout):
|
||||
return nil, errors.New("timeout")
|
||||
}
|
||||
} else {
|
||||
data := <-p.chImage
|
||||
return trans(data), nil
|
||||
}
|
||||
}
|
||||
|
||||
func dumpImage(img image.Image) {
|
||||
f, err := os.Create(`C:\Users\lwch\Pictures\debug.jpeg`)
|
||||
if err != nil {
|
||||
logging.Error("debug: %v", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
err = jpeg.Encode(f, img, nil)
|
||||
if err != nil {
|
||||
logging.Error("encode: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
"image"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CreateWorker create worker process
|
||||
func CreateWorker(name, confDir string, showCursor bool) (*Process, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// Close close process
|
||||
func (p *Process) Close() {
|
||||
}
|
||||
|
||||
// Capture capture desktop image
|
||||
func (p *Process) Capture(timeout time.Duration) (*image.RGBA, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"natpass/code/client/rule/vnc/define"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func attachDesktop() (func(), error) {
|
||||
runtime.LockOSThread()
|
||||
locked := true
|
||||
oldDesktop, _, err := syscall.Syscall(define.FuncGetThreadDesktop, 1, uintptr(windows.GetCurrentThreadId()), 0, 0)
|
||||
if oldDesktop == 0 {
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("get thread desktop: %v", err)
|
||||
}
|
||||
desktop, _, err := syscall.Syscall(define.FuncOpenInputDesktop, 3, 0, 0, windows.GENERIC_ALL)
|
||||
if desktop == 0 {
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("open input desktop: %v", err)
|
||||
}
|
||||
ok, _, err := syscall.Syscall(define.FuncSetThreadDesktop, 1, desktop, 0, 0)
|
||||
if ok == 0 {
|
||||
syscall.Syscall(define.FuncCloseDesktop, 1, desktop, 0, 0)
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("set thread desktop: %v", err)
|
||||
}
|
||||
return func() {
|
||||
syscall.Syscall(define.FuncSetThreadDesktop, 1, oldDesktop, 0, 0)
|
||||
syscall.Syscall(define.FuncCloseDesktop, 1, desktop, 0, 0)
|
||||
if locked {
|
||||
runtime.UnlockOSThread()
|
||||
locked = false
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
@@ -3,13 +3,6 @@
|
||||
|
||||
package worker
|
||||
|
||||
type workerOsBased struct {
|
||||
}
|
||||
|
||||
func (worker *Worker) init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func attachDesktop() (func(), error) {
|
||||
return func() {}, nil
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"natpass/code/client/rule/vnc/vncnetwork"
|
||||
|
||||
"github.com/lwch/logging"
|
||||
)
|
||||
|
||||
func (worker *Worker) runCapture() vncnetwork.ImageData {
|
||||
detach, err := attachDesktop()
|
||||
if err != nil {
|
||||
logging.Error("attach desktop: " + err.Error())
|
||||
return vncnetwork.ImageData{
|
||||
Ok: false,
|
||||
Msg: fmt.Sprintf("attach desktop: " + err.Error()),
|
||||
}
|
||||
}
|
||||
defer detach()
|
||||
img, err := worker.cli.Screenshot()
|
||||
if err != nil {
|
||||
logging.Error("screenshot: " + err.Error())
|
||||
return vncnetwork.ImageData{
|
||||
Ok: false,
|
||||
Msg: fmt.Sprintf("screenshot: " + err.Error()),
|
||||
}
|
||||
}
|
||||
data := make([]byte, len(img.Pix))
|
||||
copy(data, img.Pix)
|
||||
return vncnetwork.ImageData{
|
||||
Ok: true,
|
||||
Bits: 32,
|
||||
Width: uint32(img.Rect.Max.X),
|
||||
Height: uint32(img.Rect.Max.Y),
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"natpass/code/client/rule/vnc/define"
|
||||
"natpass/code/client/rule/vnc/vncnetwork"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/lwch/logging"
|
||||
)
|
||||
|
||||
func (worker *Worker) runCapture() vncnetwork.ImageData {
|
||||
err := worker.capture()
|
||||
if err != nil {
|
||||
return vncnetwork.ImageData{
|
||||
Ok: false,
|
||||
Msg: err.Error(),
|
||||
}
|
||||
}
|
||||
data := make([]byte, worker.info.width*worker.info.height*worker.info.bits/8)
|
||||
for i := 0; i < len(data); i++ {
|
||||
data[i] = *(*uint8)(unsafe.Pointer(worker.buffer + uintptr(i)))
|
||||
}
|
||||
// BGR => RGB
|
||||
for i := 0; i < len(data); i += (worker.info.bits / 8) {
|
||||
data[i], data[i+2] = data[i+2], data[i]
|
||||
}
|
||||
return vncnetwork.ImageData{
|
||||
Ok: true,
|
||||
Bits: uint32(worker.info.bits),
|
||||
Width: uint32(worker.info.width),
|
||||
Height: uint32(worker.info.height),
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
func (worker *Worker) capture() error {
|
||||
detach, err := attachDesktop()
|
||||
if err != nil {
|
||||
return errors.New("attach desktop: " + err.Error())
|
||||
}
|
||||
defer detach()
|
||||
cancel, hdc, err := worker.getHandle()
|
||||
if err != nil {
|
||||
return errors.New("get handle: " + err.Error())
|
||||
}
|
||||
defer cancel()
|
||||
info := worker.info
|
||||
err = worker.updateInfo(hdc)
|
||||
if err != nil {
|
||||
return errors.New("update info: " + err.Error())
|
||||
}
|
||||
if info.bits != worker.info.bits ||
|
||||
info.width != worker.info.width ||
|
||||
info.height != worker.info.height {
|
||||
err = worker.updateBuffer()
|
||||
if err != nil {
|
||||
return errors.New("update buffer: " + err.Error())
|
||||
}
|
||||
}
|
||||
// logging.Info("width=%d, height=%d, bits=%d", info.width, info.height, info.bits)
|
||||
memDC, bitmap, free, err := worker.bitblt(hdc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer free()
|
||||
defer worker.copyImageData(hdc, bitmap)
|
||||
return worker.drawCursor(memDC)
|
||||
}
|
||||
|
||||
func (worker *Worker) bitblt(hdc uintptr) (uintptr, uintptr, func(), error) {
|
||||
memDC, _, err := syscall.Syscall(define.FuncCreateCompatibleDC, 1, hdc, 0, 0)
|
||||
if memDC == 0 {
|
||||
return 0, 0, nil, errors.New("create dc: " + err.Error())
|
||||
}
|
||||
bitmap, _, err := syscall.Syscall(define.FuncCreateCompatibleBitmap, 3, hdc,
|
||||
uintptr(worker.info.width), uintptr(worker.info.height))
|
||||
if bitmap == 0 {
|
||||
syscall.Syscall(define.FuncDeleteDC, 1, memDC, 0, 0)
|
||||
return 0, 0, nil, errors.New("create bitmap: " + err.Error())
|
||||
}
|
||||
oldDC, _, err := syscall.Syscall(define.FuncSelectObject, 2, memDC, bitmap, 0)
|
||||
if oldDC == 0 {
|
||||
syscall.Syscall(define.FuncDeleteObject, 1, bitmap, 0, 0)
|
||||
syscall.Syscall(define.FuncDeleteDC, 1, memDC, 0, 0)
|
||||
return 0, 0, nil, errors.New("select object: " + err.Error())
|
||||
}
|
||||
ok, _, err := syscall.Syscall9(define.FuncBitBlt, 9, memDC, 0, 0,
|
||||
uintptr(worker.info.width), uintptr(worker.info.height), hdc, 0, 0, define.SRCCOPY)
|
||||
if ok == 0 {
|
||||
syscall.Syscall(define.FuncSelectObject, 2, memDC, oldDC, 0)
|
||||
syscall.Syscall(define.FuncDeleteObject, 1, bitmap, 0, 0)
|
||||
syscall.Syscall(define.FuncDeleteDC, 1, memDC, 0, 0)
|
||||
return 0, 0, nil, errors.New("bitblt: " + err.Error())
|
||||
}
|
||||
return memDC, bitmap, func() {
|
||||
syscall.Syscall(define.FuncSelectObject, 2, memDC, oldDC, 0)
|
||||
syscall.Syscall(define.FuncDeleteObject, 1, bitmap, 0, 0)
|
||||
syscall.Syscall(define.FuncDeleteDC, 1, memDC, 0, 0)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (worker *Worker) drawCursor(memDC uintptr) error {
|
||||
if !worker.showCursor {
|
||||
return nil
|
||||
}
|
||||
var curInfo define.CURSORINFO
|
||||
curInfo.CbSize = define.DWORD(unsafe.Sizeof(curInfo))
|
||||
ok, _, err := syscall.Syscall(define.FuncGetCursorInfo, 1, uintptr(unsafe.Pointer(&curInfo)), 0, 0)
|
||||
if ok == 0 {
|
||||
logging.Error("get cursor info: %v", err)
|
||||
return nil
|
||||
}
|
||||
if curInfo.Flags == define.CURSORSHOWING {
|
||||
var info define.ICONINFO
|
||||
ok, _, err = syscall.Syscall(define.FuncGetIconInfo, 2, uintptr(curInfo.HCursor), uintptr(unsafe.Pointer(&info)), 0)
|
||||
if ok == 0 {
|
||||
logging.Error("get icon info: %v", err)
|
||||
return nil
|
||||
}
|
||||
x := curInfo.PTScreenPos.X - define.LONG(info.XHotspot)
|
||||
y := curInfo.PTScreenPos.Y - define.LONG(info.YHotspot)
|
||||
ok, _, err = syscall.Syscall6(define.FuncDrawIcon, 4, memDC, uintptr(x), uintptr(y), uintptr(curInfo.HCursor), 0, 0)
|
||||
if ok == 0 {
|
||||
logging.Error("draw icon: %v", err)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BITMAPINFOHEADER https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
|
||||
type BITMAPINFOHEADER struct {
|
||||
BiSize uint32
|
||||
BiWidth int32
|
||||
BiHeight int32
|
||||
BiPlanes uint16
|
||||
BiBitCount uint16
|
||||
BiCompression uint32
|
||||
BiSizeImage uint32
|
||||
BiXPelsPerMeter int32
|
||||
BiYPelsPerMeter int32
|
||||
BiClrUsed uint32
|
||||
BiClrImportant uint32
|
||||
}
|
||||
|
||||
func (worker *Worker) copyImageData(hdc, bitmap uintptr) {
|
||||
var hdr BITMAPINFOHEADER
|
||||
hdr.BiSize = uint32(unsafe.Sizeof(hdr))
|
||||
hdr.BiPlanes = 1
|
||||
hdr.BiBitCount = uint16(worker.info.bits)
|
||||
hdr.BiWidth = int32(worker.info.width)
|
||||
hdr.BiHeight = int32(-worker.info.height)
|
||||
hdr.BiCompression = define.BIRGB
|
||||
hdr.BiSizeImage = 0
|
||||
lines, _, err := syscall.Syscall9(define.FuncGetDIBits, 7, hdc, bitmap, 0, uintptr(worker.info.height),
|
||||
worker.buffer, uintptr(unsafe.Pointer(&hdr)), define.DIBRGBCOLORS, 0, 0)
|
||||
if lines == 0 {
|
||||
logging.Error("get bits: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package worker
|
||||
|
||||
import "natpass/code/client/rule/vnc/vncnetwork"
|
||||
|
||||
func (worker *Worker) runCapture() vncnetwork.ImageData {
|
||||
return vncnetwork.ImageData{}
|
||||
}
|
||||
@@ -8,32 +8,24 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/lwch/logging"
|
||||
"github.com/lwch/rdesktop"
|
||||
"github.com/lwch/runtime"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type desktopInfo struct {
|
||||
bits int
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
// Worker worker object
|
||||
type Worker struct {
|
||||
workerOsBased
|
||||
info desktopInfo
|
||||
showCursor bool
|
||||
cli *rdesktop.Client
|
||||
}
|
||||
|
||||
// NewWorker create worker
|
||||
func NewWorker(showCursor bool) *Worker {
|
||||
worker := &Worker{
|
||||
showCursor: showCursor,
|
||||
}
|
||||
err := worker.init()
|
||||
worker := &Worker{}
|
||||
cli, err := rdesktop.New()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
worker.cli = cli
|
||||
return worker
|
||||
}
|
||||
|
||||
@@ -69,7 +61,7 @@ func (worker *Worker) Do(conn *websocket.Conn) {
|
||||
case vncnetwork.VncMsg_keyboard_event:
|
||||
runKeyboard(msg.GetKeyboard())
|
||||
case vncnetwork.VncMsg_set_cursor:
|
||||
worker.showCursor = msg.GetShowCursor()
|
||||
worker.cli.ShowCursor(msg.GetShowCursor())
|
||||
case vncnetwork.VncMsg_scroll_event:
|
||||
runScroll(msg.GetScroll())
|
||||
case vncnetwork.VncMsg_clipboard_event:
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
package worker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"natpass/code/client/rule/vnc/define"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/lwch/logging"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type workerOsBased struct {
|
||||
buffer uintptr
|
||||
}
|
||||
|
||||
func attachDesktop() (func(), error) {
|
||||
runtime.LockOSThread()
|
||||
locked := true
|
||||
oldDesktop, _, err := syscall.Syscall(define.FuncGetThreadDesktop, 1, uintptr(windows.GetCurrentThreadId()), 0, 0)
|
||||
if oldDesktop == 0 {
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("get thread desktop: %v", err)
|
||||
}
|
||||
desktop, _, err := syscall.Syscall(define.FuncOpenInputDesktop, 3, 0, 0, windows.GENERIC_ALL)
|
||||
if desktop == 0 {
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("open input desktop: %v", err)
|
||||
}
|
||||
ok, _, err := syscall.Syscall(define.FuncSetThreadDesktop, 1, desktop, 0, 0)
|
||||
if ok == 0 {
|
||||
syscall.Syscall(define.FuncCloseDesktop, 1, desktop, 0, 0)
|
||||
runtime.UnlockOSThread()
|
||||
return nil, fmt.Errorf("set thread desktop: %v", err)
|
||||
}
|
||||
return func() {
|
||||
syscall.Syscall(define.FuncSetThreadDesktop, 1, oldDesktop, 0, 0)
|
||||
syscall.Syscall(define.FuncCloseDesktop, 1, desktop, 0, 0)
|
||||
if locked {
|
||||
runtime.UnlockOSThread()
|
||||
locked = false
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (worker *Worker) init() error {
|
||||
detach, err := attachDesktop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer detach()
|
||||
cancel, hdc, err := worker.getHandle()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cancel()
|
||||
err = worker.updateInfo(hdc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
detach()
|
||||
return worker.updateBuffer()
|
||||
}
|
||||
|
||||
func (worker *workerOsBased) getHandle() (func(), uintptr, error) {
|
||||
hwnd, _, err := syscall.Syscall(define.FuncGetDesktopWindow, 0, 0, 0, 0)
|
||||
if hwnd == 0 {
|
||||
return nil, 0, fmt.Errorf("get desktop window: %v", err)
|
||||
}
|
||||
hdc, _, err := syscall.Syscall(define.FuncGetDC, 1, hwnd, 0, 0)
|
||||
if hdc == 0 {
|
||||
return nil, 0, fmt.Errorf("get dc: %v", err)
|
||||
}
|
||||
return func() {
|
||||
syscall.Syscall(define.FuncReleaseDC, 2, hwnd, hdc, 0)
|
||||
}, hdc, nil
|
||||
}
|
||||
|
||||
func (worker *Worker) updateInfo(hdc uintptr) error {
|
||||
bits, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.BITSPIXEL, 0)
|
||||
if bits == 0 {
|
||||
return fmt.Errorf("get device caps(bits): %v", err)
|
||||
}
|
||||
width, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.HORZRES, 0)
|
||||
if width == 0 {
|
||||
return fmt.Errorf("get device caps(width): %v", err)
|
||||
}
|
||||
height, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.VERTRES, 0)
|
||||
if height == 0 {
|
||||
return fmt.Errorf("get device caps(height): %v", err)
|
||||
}
|
||||
worker.info.bits = int(bits)
|
||||
worker.info.width = int(width)
|
||||
worker.info.height = int(height)
|
||||
if worker.info.bits != 32 {
|
||||
worker.info.bits = 32
|
||||
logging.Info("reset bits to 32")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (worker *Worker) updateBuffer() error {
|
||||
addr, _, err := syscall.Syscall(define.FuncGlobalAlloc, 2, define.GMEMFIXED, uintptr(worker.info.bits*worker.info.width*worker.info.height/8), 0)
|
||||
if addr == 0 {
|
||||
return fmt.Errorf("global alloc: %v", err)
|
||||
}
|
||||
if worker.buffer != 0 {
|
||||
syscall.Syscall(define.FuncGlobalFree, 1, worker.buffer, 0, 0)
|
||||
}
|
||||
worker.buffer = addr
|
||||
return nil
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG APT_MIRROR=mirrors.ustc.edu.cn
|
||||
ARG LIBPNG_VERSION=1.6.37
|
||||
ARG GO_VERSION=1.17.3
|
||||
ARG GO_VERSION=1.17.4
|
||||
ARG GO_PROXY=https://goproxy.cn,direct
|
||||
|
||||
# build libpng
|
||||
@@ -38,6 +38,7 @@ WORKDIR /build
|
||||
|
||||
RUN sed -i "s|deb.debian.org|$APT_MIRROR|g" /etc/apt/sources.list && \
|
||||
sed -i "s|security.debian.org|$APT_MIRROR|g" /etc/apt/sources.list && \
|
||||
dpkg --add-architecture i386 && \
|
||||
apt-get update && apt-get upgrade -y && \
|
||||
apt-get install -y gcc libc6-dev && \
|
||||
apt-get install -y libx11-dev xorg-dev libxtst-dev libpng++-dev && \
|
||||
@@ -48,6 +49,10 @@ RUN sed -i "s|deb.debian.org|$APT_MIRROR|g" /etc/apt/sources.list && \
|
||||
apt-get install -y gcc-mingw-w64 && \
|
||||
apt-get install -y libz-mingw-w64-dev && \
|
||||
apt-get install -y curl git && \
|
||||
apt-get update && \
|
||||
apt-get install -y libx11-dev:i386 libxtst-dev:i386 libpng-dev:i386 && \
|
||||
apt-get install -y xcb:i386 libxcb-xkb-dev:i386 x11-xkb-utils:i386 libx11-xcb-dev:i386 libxkbcommon-x11-dev:i386 && \
|
||||
apt-get install -y libxkbcommon-dev:i386 && \
|
||||
curl -L https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz|tar -xz -C /usr/local && \
|
||||
cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
|
||||
@@ -161,6 +161,8 @@ func build(t target) {
|
||||
runtime.Assert(err)
|
||||
err = copyFile("CHANGELOG.md", path.Join(buildDir, "CHANGELOG.md"))
|
||||
runtime.Assert(err)
|
||||
err = copyFile("docs/startup.md", path.Join(buildDir, "startup.md"))
|
||||
runtime.Assert(err)
|
||||
|
||||
ldflags := "-X 'main.gitHash=" + gitHash() + "' " +
|
||||
"-X 'main.gitReversion=" + gitReversion() + "' " +
|
||||
@@ -199,6 +201,27 @@ 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))
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
+6
-2
@@ -20,7 +20,7 @@
|
||||
sudo systemctl enable np-svr
|
||||
sudo systemctl start np-svr
|
||||
|
||||
## 远端部署
|
||||
## 受控端部署
|
||||
|
||||
1. 在远端机器上[下载](https://github.com/lwch/natpass/releases)并解压到任意目录
|
||||
2. 修改client.yaml配置文件,设置*id*为remote,设置*server*地址,并删除以下配置
|
||||
@@ -35,7 +35,11 @@
|
||||
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*地址
|
||||
|
||||
@@ -6,19 +6,19 @@ 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-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-vgo/robotgo v0.100.8
|
||||
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-20211115073745-0db19179db17
|
||||
github.com/lwch/logging v0.0.0-20211203094902-ecb971ed7cdc
|
||||
github.com/lwch/rdesktop v0.0.0-20211207101551-b892a4a5e2b5
|
||||
github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d
|
||||
github.com/lwch/yaml v0.0.0-20211009070949-2d4c64e2b789
|
||||
github.com/shirou/gopsutil v3.21.10+incompatible // indirect
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
|
||||
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-20211117180635-dee7805ff2e1
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
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=
|
||||
@@ -14,8 +13,8 @@ github.com/go-bindata/go-bindata/v3 v3.1.3/go.mod h1:1/zrpXsLD8YDIbhZRqXzm1Ghc7N
|
||||
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.8 h1:fBcmqPoQq/0vOr0C45T6SSScKwuYgAEJr9+T1PulHOA=
|
||||
github.com/go-vgo/robotgo v0.100.8/go.mod h1:GCjwxRFoUkuekzm02WexYBV0paDLCbrrlKEfxt/CB10=
|
||||
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=
|
||||
@@ -26,12 +25,15 @@ github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6RlY=
|
||||
github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/lwch/logging v0.0.0-20211115073745-0db19179db17 h1:LJ8K1245kOPu1BGgEsmW/tr5gdkrX1vdQ+aztXjMjAA=
|
||||
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/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-20211009070949-2d4c64e2b789 h1:Z9jucdBfDaTXBT+jxyOw08op3DYpr9lEZJkTbVJ3bmU=
|
||||
github.com/lwch/yaml v0.0.0-20211009070949-2d4c64e2b789/go.mod h1:Dz0eixDQvioB5pqCXGQJ6sTJetbS6TCHegLuRh2Bw2U=
|
||||
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=
|
||||
@@ -41,15 +43,15 @@ 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.2 h1:ADIppQ3T0Sd+kaDMb4Vnv6UeSmhNfK0H0HpPWCd8G5I=
|
||||
github.com/robotn/gohook v0.31.2/go.mod h1:0BQit8783ey63WXFau8TvoaTYfNtsAhqZ0RJaqlYi6E=
|
||||
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.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.10+incompatible h1:AL2kpVykjkqeN+MFe1WcwSBVUjGjvdU8/ubvCuXAjrU=
|
||||
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=
|
||||
@@ -57,14 +59,18 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev
|
||||
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.2 h1:OwWoJR0zb+AK41TN2adhZUP9lAmaRMzkWwf7Ux5Mx00=
|
||||
github.com/vcaesar/gops v0.21.2/go.mod h1:BEJGigAc9GORbEegWX9rRon/qwibjDs8p50WYm2KlXw=
|
||||
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=
|
||||
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=
|
||||
@@ -98,10 +104,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 h1:kwrAHlwJ0DUBZwQ238v+Uod/3eZ8B2K5rYsUHBQvzmI=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/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/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=
|
||||
|
||||
Reference in New Issue
Block a user