diff --git a/code/client/pool/send_vnc.go b/code/client/pool/send_vnc.go index cc86511..3d5875b 100644 --- a/code/client/pool/send_vnc.go +++ b/code/client/pool/send_vnc.go @@ -155,8 +155,8 @@ func (conn *Conn) SendVNCScroll(to string, toIdx uint32, id string, x, y int32) } } -// SendVNCClipboardSet send vnc set clipboard -func (conn *Conn) SendVNCClipboardSet(to string, toIdx uint32, id, data string) { +// SendVNCClipboardData send vnc clipboard data +func (conn *Conn) SendVNCClipboardData(to string, toIdx uint32, id string, set bool, data string) { var msg network.Msg msg.To = to msg.ToIdx = toIdx @@ -164,7 +164,7 @@ func (conn *Conn) SendVNCClipboardSet(to string, toIdx uint32, id, data string) msg.LinkId = id msg.Payload = &network.Msg_Vclipboard{ Vclipboard: &network.VncClipboard{ - Set: true, + Set: set, XType: network.VncClipboard_text, Payload: &network.VncClipboard_Data{ Data: data, diff --git a/code/client/rule/vnc/h_clipboard.go b/code/client/rule/vnc/h_clipboard.go index da15c24..db339ae 100644 --- a/code/client/rule/vnc/h_clipboard.go +++ b/code/client/rule/vnc/h_clipboard.go @@ -16,6 +16,12 @@ func (v *VNC) Clipboard(pool *pool.Pool, w http.ResponseWriter, r *http.Request) } func (v *VNC) getClipboard(pool *pool.Pool, w http.ResponseWriter, r *http.Request) { + if v.link == nil { + http.NotFound(w, r) + return + } + conn := pool.Get(v.link.id) + conn.SendVNCClipboardData(v.link.target, v.link.targetIdx, v.link.id, false, "") } func (v *VNC) setClipboard(pool *pool.Pool, w http.ResponseWriter, r *http.Request) { @@ -25,6 +31,6 @@ func (v *VNC) setClipboard(pool *pool.Pool, w http.ResponseWriter, r *http.Reque return } conn := pool.Get(v.link.id) - conn.SendVNCClipboardSet(v.link.target, v.link.targetIdx, v.link.id, data) + conn.SendVNCClipboardData(v.link.target, v.link.targetIdx, v.link.id, true, data) fmt.Fprint(w, "ok") } diff --git a/code/client/rule/vnc/link.go b/code/client/rule/vnc/link.go index b81229f..fc0f638 100644 --- a/code/client/rule/vnc/link.go +++ b/code/client/rule/vnc/link.go @@ -110,7 +110,12 @@ func (link *Link) remoteRead() { case network.Msg_vnc_scroll: link.ps.ScrollEvent(msg.GetVscroll()) case network.Msg_vnc_clipboard: - link.ps.ClipboardEvent(msg.GetVclipboard()) + if msg.GetVclipboard().GetSet() { + link.ps.SetClipboard(msg.GetVclipboard()) + } else { + data := link.ps.GetClipboard() + link.remote.SendVNCClipboardData(link.target, link.targetIdx, link.id, true, data) + } case network.Msg_disconnect: logging.Info("link %s disconnected", link.id) return diff --git a/code/client/rule/vnc/process/event.go b/code/client/rule/vnc/process/event.go index 74cd8e2..92c9b44 100644 --- a/code/client/rule/vnc/process/event.go +++ b/code/client/rule/vnc/process/event.go @@ -79,8 +79,8 @@ func (p *Process) ScrollEvent(data *network.VncScroll) { p.chWrite <- &msg } -// ClipboardEvent dispatch clipboard event to child process -func (p *Process) ClipboardEvent(data *network.VncClipboard) { +// SetClipboard set clipboard data to child process +func (p *Process) SetClipboard(data *network.VncClipboard) { t := vncnetwork.ClipboardData_unset_type var payload vncnetwork.ClipboardData_Data switch data.GetXType() { @@ -103,3 +103,17 @@ func (p *Process) ClipboardEvent(data *network.VncClipboard) { } p.chWrite <- &msg } + +// GetClipboard get clipboard data from child process +func (p *Process) GetClipboard() string { + var msg vncnetwork.VncMsg + msg.XType = vncnetwork.VncMsg_clipboard_event + msg.Payload = &vncnetwork.VncMsg_Clipboard{ + Clipboard: &vncnetwork.ClipboardData{ + Set: false, + }, + } + p.chWrite <- &msg + data := <-p.chClipboard + return data.GetData() +} diff --git a/code/client/rule/vnc/process/process.go b/code/client/rule/vnc/process/process.go index a85d3f8..722b7fe 100644 --- a/code/client/rule/vnc/process/process.go +++ b/code/client/rule/vnc/process/process.go @@ -22,10 +22,11 @@ const ( // Process process type Process struct { - pid int - srv *http.Server - chWrite chan *vncnetwork.VncMsg - chImage chan *vncnetwork.ImageData + pid int + srv *http.Server + chWrite chan *vncnetwork.VncMsg + chImage chan *vncnetwork.ImageData + chClipboard chan *vncnetwork.ClipboardData } func (p *Process) listenAndServe() (uint16, error) { @@ -80,6 +81,8 @@ func (p *Process) ws(w http.ResponseWriter, r *http.Request) { switch msg.GetXType() { case vncnetwork.VncMsg_capture_data: p.chImage <- msg.GetData() + case vncnetwork.VncMsg_clipboard_event: + p.chClipboard <- msg.GetClipboard() default: } } diff --git a/code/client/rule/vnc/process/process_windows.go b/code/client/rule/vnc/process/process_windows.go index ca19e84..9f6204d 100644 --- a/code/client/rule/vnc/process/process_windows.go +++ b/code/client/rule/vnc/process/process_windows.go @@ -95,6 +95,7 @@ func createWorker(name, confDir string, tk windows.Token, showCursor bool) (*Pro 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 @@ -132,6 +133,10 @@ func (p *Process) Close() { 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 diff --git a/code/client/rule/vnc/worker/event.go b/code/client/rule/vnc/worker/event.go index 3e51371..471d360 100644 --- a/code/client/rule/vnc/worker/event.go +++ b/code/client/rule/vnc/worker/event.go @@ -3,7 +3,11 @@ package worker -import "natpass/code/client/rule/vnc/vncnetwork" +import ( + "natpass/code/client/rule/vnc/vncnetwork" + + "github.com/gorilla/websocket" +) func runMouse(data *vncnetwork.MouseData) { } @@ -14,5 +18,5 @@ func runKeyboard(data *vncnetwork.KeyboardData) { func runScroll(data *vncnetwork.ScrollData) { } -func runClipboard(data *vncnetwork.ClipboardData) { +func runClipboard(conn *websocket.Conn, data *vncnetwork.ClipboardData) { } diff --git a/code/client/rule/vnc/worker/event_auto.go b/code/client/rule/vnc/worker/event_auto.go index cf7c88d..bc4ed4e 100644 --- a/code/client/rule/vnc/worker/event_auto.go +++ b/code/client/rule/vnc/worker/event_auto.go @@ -7,7 +7,9 @@ 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) { @@ -60,7 +62,7 @@ func runScroll(data *vncnetwork.ScrollData) { robotgo.Scroll(int(data.X), int(data.Y), 1) } -func runClipboard(data *vncnetwork.ClipboardData) { +func runClipboard(conn *websocket.Conn, data *vncnetwork.ClipboardData) { detach, err := attachDesktop() if err != nil { logging.Error("attach desktop: %v", err) @@ -70,7 +72,7 @@ func runClipboard(data *vncnetwork.ClipboardData) { if data.GetSet() { setClipboard(data) } else { - getClipboard() + getClipboard(conn) } } @@ -83,5 +85,19 @@ func setClipboard(data *vncnetwork.ClipboardData) { } } -func getClipboard() { +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 0702d10..183468a 100644 --- a/code/client/rule/vnc/worker/worker.go +++ b/code/client/rule/vnc/worker/worker.go @@ -73,7 +73,7 @@ func (worker *Worker) Do(conn *websocket.Conn) { case vncnetwork.VncMsg_scroll_event: runScroll(msg.GetScroll()) case vncnetwork.VncMsg_clipboard_event: - runClipboard(msg.GetClipboard()) + runClipboard(conn, msg.GetClipboard()) } } } diff --git a/html/vnc/clipboard_dialog.js b/html/vnc/clipboard_dialog.js new file mode 100644 index 0000000..42ae26b --- /dev/null +++ b/html/vnc/clipboard_dialog.js @@ -0,0 +1,19 @@ +var clipboard_dialog = { + init: function() { + $('#dlg-clipboard #set-clipboard').click(clipboard_dialog.set); + $('#dlg-clipboard #get-clipboard').click(clipboard_dialog.get); + }, + modal: function() { + $('#dlg-clipboard textarea').val(''); + $('#dlg-clipboard').modal(); + }, + set: function() { + $.post('/clipboard', {data: $('#dlg-clipboard textarea').val()}); + }, + get: function() { + $.get('/clipboard', function(ret) { + $('#dlg-clipboard textarea').val(ret); + }); + } +}; +$(document).ready(clipboard_dialog.init); \ No newline at end of file diff --git a/html/vnc/index.css b/html/vnc/index.css index 4255398..14a5465 100644 --- a/html/vnc/index.css +++ b/html/vnc/index.css @@ -13,6 +13,7 @@ float: right; } #cad, +#clipboard, #info { float: right; margin-right: 5px; @@ -29,4 +30,12 @@ label, span { #fullscreen { cursor: pointer; font-size: 38px; +} + +#dlg-clipboard textarea { + resize: vertical; + min-height: 300px; +} +#dlg-clipboard #row-data { + margin-top: 10px; } \ No newline at end of file diff --git a/html/vnc/index.html b/html/vnc/index.html index a830734..ba55e73 100644 --- a/html/vnc/index.html +++ b/html/vnc/index.html @@ -14,6 +14,7 @@ +
@@ -32,11 +33,37 @@ + fps: 0, bandwidth: 0 B/s +