Compare commits

...

25 Commits
v1.1 ... master

Author SHA1 Message Date
Amit Bezalel
ea8f9b5109
Merge pull request #16 from t-yuki/patch-1
Fix nil reference error for color map message
2020-01-18 10:43:10 +02:00
Yukinari Toyota
faa9021021
Update server-messages.go
Fix nil reference error
2020-01-17 13:21:09 +09:00
Bezalel
1c052273de Fix noVnc 1.1.0 problem (bad message type 248) 2019-12-19 07:56:00 +02:00
amit b
f07be04814 use circle 2019-06-16 20:38:05 +03:00
amit b
55cf83519a remove temp build dirs 2019-06-16 20:30:12 +03:00
amit b
92ee157817 fixing artifact collection 2019-06-16 20:20:10 +03:00
amit b
f635a73757 Merge branch 'master' of https://github.com/amitbet/VncProxy 2019-06-16 20:17:21 +03:00
amit b
149e26b6f7 added packaging to build 2019-06-16 20:16:22 +03:00
Amit Bezalel
3d42d4fa5f
changed badge style 2019-06-16 03:11:33 +03:00
Amit Bezalel
f66f550c77
added circleCI badge 2019-06-16 03:09:29 +03:00
amit b
c7ac36d15f remove steps in circleCI config 2019-06-16 03:04:55 +03:00
amit b
0ba10fab76 fixed cicrleCI testing 2019-06-16 02:59:17 +03:00
amit b
76299f1bc3 fixed error found in circleCI testing 2019-06-16 02:51:50 +03:00
amit b
a9dce0e6c6 Merge branch 'master' of https://github.com/amitbet/VncProxy 2019-06-16 02:37:07 +03:00
amit b
fa416220ea add circleCI config 2019-06-16 02:36:39 +03:00
Amit Bezalel
efc5741057
Update README.md
Added qemu to tested servers list
2018-12-04 19:03:16 +02:00
amit b
82e1549c4f fixed proxy cmdline parameters and logs 2018-12-01 14:59:32 +02:00
Amit Bezalel
33be77dedc
Merge pull request #9 from exoscale/go-mod-compatible
global: make the whole package go mod ready
2018-12-01 14:21:53 +02:00
Yoan Blanc
11b1d45ce9
global: make the whole package go mod ready
Signed-off-by: Yoan Blanc <yoan.blanc@exoscale.ch>
2018-11-30 09:40:45 +01:00
Amit Bezalel
42873297d2
Merge pull request #8 from exoscale/master
Fix recording bug in proxy
2018-11-14 13:45:02 +02:00
Marc Falzon
f00e2c33e7
Merge pull request #1 from exoscale/feature/unixsock-target
Add support for UNIX socket VNC target
2018-11-14 11:12:53 +01:00
Marc Falzon
9a52a433ea Add support for UNIX socket VNC target
This change add support for targeting a VNC server via a local UNIX
socket. It introduces a new `-target` CLI flag able to handle both TCP
"address:port" and "/path/to/unix.socket" formats, and deprecates the
previous `-targHost` and `-targPort` flags for future removal.
2018-11-01 10:14:15 +01:00
Marc Falzon
06e555775f Fix recording bug in proxy
This change fixes a bug in the proxy session recording management, where
the proxy would record sessions even if the user didn't provide a value
for the `-recDir` CLI flag.
2018-11-01 10:04:29 +01:00
Amit Bezalel
3e882d6140
Update README.md 2018-10-27 08:42:36 +03:00
Amit Bezalel
5a488bcd0f
Update README.md 2018-10-27 08:40:48 +03:00
41 changed files with 292 additions and 118 deletions

129
.circleci/config.yml Normal file
View File

@ -0,0 +1,129 @@
version: 2 # use CircleCI 2.0
jobs: # basic units of work in a run
build: # runs not using Workflows must have a `build` job as entry point
docker: # run the steps with Docker
# CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/
- image: circleci/golang:1.12
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
- image: circleci/postgres:9.6-alpine
environment: # environment variables for primary container
POSTGRES_USER: circleci-demo-go
POSTGRES_DB: circle_test
parallelism: 2
environment: # environment variables for the build itself
TEST_RESULTS: /tmp/test-results # path to where test results will be saved
steps: # steps that comprise the `build` job
- checkout # check out source code to working directory
- run: mkdir -p $TEST_RESULTS # create the test results directory
- restore_cache: # restores saved cache if no changes are detected since last run
keys:
- go-mod-v4-{{ checksum "go.sum" }}
# Wait for Postgres to be ready before proceeding
- run:
name: Waiting for Postgres to be ready
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Run unit tests
environment: # environment variables for the database url and path to migration files
CONTACTS_DB_URL: "postgres://circleci-demo-go@localhost:5432/circle_test?sslmode=disable"
CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
# store the results of our tests in the $TEST_RESULTS directory
command: |
PACKAGE_NAMES=$(go list ./... | circleci tests split --split-by=timings --timings-type=classname)
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES
# Build
- run:
name: Build and package all OS flavors
command: |
#!/bin/bash
sum="sha1sum"
# VERSION=`date -u +%Y%m%d`
VERSION="v1.11"
LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS=""
if ! hash sha1sum 2>/dev/null; then
if ! hash shasum 2>/dev/null; then
echo "I can't see 'sha1sum' or 'shasum'"
echo "Please install one of them!"
exit
fi
sum="shasum"
fi
UPX=false
if hash upx 2>/dev/null; then
UPX=true
fi
OSES=( linux darwin windows )
ARCHS=(amd64 386 )
for os in ${OSES[@]}; do
for arch in ${ARCHS[@]}; do
suffix=""
if [ "$os" == "windows" ]
then
suffix=".exe"
fi
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o ./dist/${os}_${arch}/recorder${suffix} ./recorder/cmd
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o ./dist/${os}_${arch}/player${suffix} ./player/cmd
env CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -ldflags "$LDFLAGS" -gcflags "$GCFLAGS" -o ./dist/${os}_${arch}/proxy${suffix} ./proxy/cmd
if $UPX; then upx -9 client_${os}_${arch}${suffix} server_${os}_${arch}${suffix};fi
# tar -zcf ./dist/${CIRCLE_PROJECT_REPONAME}-${os}-${arch}-$VERSION.tar.gz ./dist/${os}_${arch}/proxy${suffix} ./dist/${os}_${arch}/player${suffix} ./dist/${os}_${arch}/recorder${suffix}
cd dist/${os}_${arch}/
zip -D -q -r ../${CIRCLE_PROJECT_REPONAME}-${os}-${arch}-$VERSION.zip proxy${suffix} player${suffix} recorder${suffix}
cd ../..
export
$sum ./dist/${CIRCLE_PROJECT_REPONAME}-${os}-${arch}-$VERSION.zip
rm -rf ./dist/${os}_${arch}/
done
done
- store_artifacts: # upload test summary for display in Artifacts
path: ./dist
destination: release-artifacts
# - run: make # pull and build dependencies for the project
# - save_cache:
# key: go-mod-v4-{{ checksum "go.sum" }}
# paths:
# - "/go/pkg/mod"
# - run:
# name: Start service
# environment:
# CONTACTS_DB_URL: "postgres://circleci-demo-go@localhost:5432/circle_test?sslmode=disable"
# CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
# command: ./workdir/contacts
# background: true # keep service running and proceed to next step
# - run:
# name: Validate service is working
# command: |
# sleep 5
# curl --retry 10 --retry-delay 1 -X POST --header "Content-Type: application/json" -d '{"email":"test@example.com","name":"Test User"}' http://localhost:8080/contacts
# - store_artifacts: # upload test summary for display in Artifacts
# path: /tmp/test-results
# destination: raw-test-output
# - store_test_results: # upload test results for display in Test Summary
# path: /tmp/test-results
workflows:
version: 2
build-workflow:
jobs:
- build

View File

@ -1,9 +1,10 @@
# VncProxy # VncProxy [![CircleCI](https://circleci.com/gh/amitbet/vncproxy/tree/master.svg?style=shield)](https://circleci.com/gh/amitbet/vncproxy/tree/master) [![MIT Licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/CircleCI-Public/circleci-demo-go/master/LICENSE.md)
An RFB proxy, written in go that can save and replay FBS files An RFB proxy, written in go that can save and replay FBS files
* Supports all modern encodings & most useful pseudo-encodings * Supports all modern encodings & most useful pseudo-encodings
* Supports multiple VNC client connections & multi servers (chosen by sessionId) * Supports multiple VNC client connections & multi servers (chosen by sessionId)
* Supports being a "websockify" proxy (for web clients like NoVnc) * Supports being a "websockify" proxy (for web clients like NoVnc)
* Produces FBS files compatible with tightvnc player (while using tight's default 3Byte color format) * Produces FBS files compatible with [tightvnc's rfb player](https://www.tightvnc.com/rfbplayer.php) (while using tight's default 3Byte color format)
* Can also be used as: * Can also be used as:
* A screen recorder vnc-client * A screen recorder vnc-client
* A replay server to show fbs recordings to connecting clients * A replay server to show fbs recordings to connecting clients
@ -15,6 +16,7 @@ An RFB proxy, written in go that can save and replay FBS files
- ChickenOfTheVnc(client) - ChickenOfTheVnc(client)
- VineVnc(server) - VineVnc(server)
- TigerVnc(client) - TigerVnc(client)
- Qemu vnc(server)
### Executables (see releases) ### Executables (see releases)
@ -23,7 +25,7 @@ An RFB proxy, written in go that can save and replay FBS files
* player - a toy player that will replay a given fbs file to all incoming connections * player - a toy player that will replay a given fbs file to all incoming connections
## Usage: ## Usage:
recorder -recDir=./recording.rbs -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ recorder -recFile=./recording.rbs -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@
player -fbsFile=./myrec.fbs -tcpPort=5905 player -fbsFile=./myrec.fbs -tcpPort=5905
proxy -recDir=./recordings/ -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ -tcpPort=5903 -wsPort=5905 -vncPass=@!@!@! proxy -recDir=./recordings/ -targHost=192.168.0.100 -targPort=5903 -targPass=@@@@@ -tcpPort=5903 -wsPort=5905 -vncPass=@!@!@!

View File

@ -2,7 +2,7 @@
sum="sha1sum" sum="sha1sum"
# VERSION=`date -u +%Y%m%d` # VERSION=`date -u +%Y%m%d`
VERSION="v1.02" VERSION="v1.11"
LDFLAGS="-X main.VERSION=$VERSION -s -w" LDFLAGS="-X main.VERSION=$VERSION -s -w"
GCFLAGS="" GCFLAGS=""

View File

@ -4,11 +4,11 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/amitbet/vncproxy/common"
"github.com/amitbet/vncproxy/logger"
"io" "io"
"net" "net"
"unicode" "unicode"
"vncproxy/common"
"vncproxy/logger"
) )
// A ServerMessage implements a message sent from the server to the client. // A ServerMessage implements a message sent from the server to the client.
@ -146,7 +146,7 @@ func (c *ClientConn) CutText(text string) error {
for _, char := range text { for _, char := range text {
if char > unicode.MaxLatin1 { if char > unicode.MaxLatin1 {
return fmt.Errorf("Character '%s' is not valid Latin-1", char) return fmt.Errorf("Character '%v' is not valid Latin-1", char)
} }
if err := binary.Write(&buf, binary.BigEndian, uint8(char)); err != nil { if err := binary.Write(&buf, binary.BigEndian, uint8(char)); err != nil {
@ -474,6 +474,7 @@ func (c *ClientConn) mainLoop() {
new(MsgSetColorMapEntries), new(MsgSetColorMapEntries),
new(MsgBell), new(MsgBell),
new(MsgServerCutText), new(MsgServerCutText),
new(MsgServerFence),
} }
for _, msg := range defaultMessages { for _, msg := range defaultMessages {

View File

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
func readPixelFormat(r io.Reader, result *common.PixelFormat) error { func readPixelFormat(r io.Reader, result *common.PixelFormat) error {

View File

@ -6,9 +6,9 @@ import (
"fmt" "fmt"
"io" "io"
"strings" "strings"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/encodings"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
// MsgFramebufferUpdate consists of a sequence of rectangles of // MsgFramebufferUpdate consists of a sequence of rectangles of
@ -129,7 +129,7 @@ type MsgSetColorMapEntries struct {
} }
func (fbm *MsgSetColorMapEntries) CopyTo(r io.Reader, w io.Writer, c common.IClientConn) error { func (fbm *MsgSetColorMapEntries) CopyTo(r io.Reader, w io.Writer, c common.IClientConn) error {
reader := &common.RfbReadHelper{Reader: r} reader := common.NewRfbReadHelper(r)
writeTo := &WriteTo{w, "MsgSetColorMapEntries.CopyTo"} writeTo := &WriteTo{w, "MsgSetColorMapEntries.CopyTo"}
reader.Listeners.AddListener(writeTo) reader.Listeners.AddListener(writeTo)
_, err := fbm.Read(c, reader) _, err := fbm.Read(c, reader)

View File

@ -2,8 +2,8 @@ package client
import ( import (
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type WriteTo struct { type WriteTo struct {

View File

@ -5,7 +5,7 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"io" "io"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
var TightMinToCompress = 12 var TightMinToCompress = 12

View File

@ -3,7 +3,7 @@ package encodings
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type CopyRectEncoding struct { type CopyRectEncoding struct {

View File

@ -3,7 +3,7 @@ package encodings
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type CoRREEncoding struct { type CoRREEncoding struct {

View File

@ -3,7 +3,7 @@ package encodings
import ( import (
"io" "io"
"math" "math"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type EncCursorPseudo struct { type EncCursorPseudo struct {

View File

@ -2,8 +2,8 @@ package encodings
import ( import (
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
const ( const (

View File

@ -2,8 +2,8 @@ package encodings
import ( import (
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type EncLedStatePseudo struct { type EncLedStatePseudo struct {

View File

@ -2,7 +2,7 @@ package encodings
import ( import (
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type PseudoEncoding struct { type PseudoEncoding struct {

View File

@ -3,7 +3,7 @@ package encodings
import ( import (
"bytes" "bytes"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
// RawEncoding is raw pixel data sent by the server. // RawEncoding is raw pixel data sent by the server.

View File

@ -3,7 +3,7 @@ package encodings
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type RREEncoding struct { type RREEncoding struct {

View File

@ -4,8 +4,8 @@ import (
"bytes" "bytes"
"errors" "errors"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
var TightMinToCompress int = 12 var TightMinToCompress int = 12

View File

@ -3,8 +3,8 @@ package encodings
import ( import (
"fmt" "fmt"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type TightPngEncoding struct { type TightPngEncoding struct {

View File

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type ZLibEncoding struct { type ZLibEncoding struct {

View File

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type ZRLEEncoding struct { type ZRLEEncoding struct {

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/amitbet/vncproxy
require golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k=
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@ -4,11 +4,11 @@ import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/encodings"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"vncproxy/player" "github.com/amitbet/vncproxy/player"
"vncproxy/server" "github.com/amitbet/vncproxy/server"
) )
func main() { func main() {

View File

@ -5,10 +5,10 @@ import (
"io" "io"
"time" "time"
"vncproxy/client" "github.com/amitbet/vncproxy/client"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"vncproxy/server" "github.com/amitbet/vncproxy/server"
) )
type VncStreamFileReader interface { type VncStreamFileReader interface {

View File

@ -5,9 +5,9 @@ import (
"encoding/binary" "encoding/binary"
"io" "io"
"os" "os"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/encodings"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type FbsReader struct { type FbsReader struct {

View File

@ -3,14 +3,15 @@ package player
import ( import (
"testing" "testing"
"time" "time"
"vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/encodings"
"vncproxy/server" "github.com/amitbet/vncproxy/logger"
"github.com/amitbet/vncproxy/server"
) )
func TestServer(t *testing.T) { func TestServer(t *testing.T) {
t.Skip("this isn't an automated test, just an entrypoint for debugging")
//chServer := make(chan common.ClientMessage) //chServer := make(chan common.ClientMessage)
//chClient := make(chan common.ServerMessage) //chClient := make(chan common.ServerMessage)

View File

@ -1,9 +1,13 @@
package main package main
import "vncproxy/proxy" import (
import "flag" "flag"
import "vncproxy/logger" "os"
import "os" "path/filepath"
"github.com/amitbet/vncproxy/logger"
vncproxy "github.com/amitbet/vncproxy/proxy"
)
func main() { func main() {
//create default session if required //create default session if required
@ -11,8 +15,9 @@ func main() {
var wsPort = flag.String("wsPort", "", "websocket port") var wsPort = flag.String("wsPort", "", "websocket port")
var vncPass = flag.String("vncPass", "", "password on incoming vnc connections to the proxy, defaults to no password") var vncPass = flag.String("vncPass", "", "password on incoming vnc connections to the proxy, defaults to no password")
var recordDir = flag.String("recDir", "", "path to save FBS recordings WILL NOT RECORD if not defined.") var recordDir = flag.String("recDir", "", "path to save FBS recordings WILL NOT RECORD if not defined.")
var targetVncPort = flag.String("targPort", "", "target vnc server port") var targetVnc = flag.String("target", "", "target vnc server (host:port or /path/to/unix.socket)")
var targetVncHost = flag.String("targHost", "", "target vnc server host") var targetVncPort = flag.String("targPort", "", "target vnc server port (deprecated, use -target)")
var targetVncHost = flag.String("targHost", "", "target vnc server host (deprecated, use -target)")
var targetVncPass = flag.String("targPass", "", "target vnc password") var targetVncPass = flag.String("targPass", "", "target vnc password")
var logLevel = flag.String("logLevel", "info", "change logging level") var logLevel = flag.String("logLevel", "info", "change logging level")
@ -25,8 +30,8 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if *targetVncPort == "" { if *targetVnc == "" && *targetVncPort == "" {
logger.Error("no target vnc server port defined") logger.Error("no target vnc server host/port or socket defined")
flag.Usage() flag.Usage()
os.Exit(1) os.Exit(1)
} }
@ -34,30 +39,42 @@ func main() {
if *vncPass == "" { if *vncPass == "" {
logger.Warn("proxy will have no password") logger.Warn("proxy will have no password")
} }
if *recordDir == "" {
logger.Warn("FBS recording is turned off")
}
tcpUrl := "" tcpURL := ""
if *tcpPort != "" { if *tcpPort != "" {
tcpUrl = ":" + string(*tcpPort) tcpURL = ":" + string(*tcpPort)
} }
wsURL := ""
proxy := &proxy.VncProxy{ if *wsPort != "" {
WsListeningUrl: "http://0.0.0.0:" + string(*wsPort) + "/", // empty = not listening on ws wsURL = "http://0.0.0.0:" + string(*wsPort) + "/"
RecordingDir: *recordDir, //"/Users/amitbet/vncRec", // empty = no recording }
TcpListeningUrl: tcpUrl, proxy := &vncproxy.VncProxy{
WsListeningURL: wsURL, // empty = not listening on ws
TCPListeningURL: tcpURL,
ProxyVncPassword: *vncPass, //empty = no auth ProxyVncPassword: *vncPass, //empty = no auth
SingleSession: &proxy.VncSession{ SingleSession: &vncproxy.VncSession{
Target: *targetVnc,
TargetHostname: *targetVncHost, TargetHostname: *targetVncHost,
TargetPort: *targetVncPort, TargetPort: *targetVncPort,
TargetPassword: *targetVncPass, //"vncPass", TargetPassword: *targetVncPass, //"vncPass",
ID: "dummySession", ID: "dummySession",
Status: proxy.SessionStatusInit, Status: vncproxy.SessionStatusInit,
Type: proxy.SessionTypeRecordingProxy, Type: vncproxy.SessionTypeProxyPass,
}, // to be used when not using sessions }, // to be used when not using sessions
UsingSessions: false, //false = single session - defined in the var above UsingSessions: false, //false = single session - defined in the var above
} }
if *recordDir != "" {
fullPath, err := filepath.Abs(*recordDir)
if err != nil {
logger.Error("bad recording path: ", err)
}
logger.Info("FBS recording is turned on, writing to dir: ", fullPath)
proxy.RecordingDir = fullPath
proxy.SingleSession.Type = vncproxy.SessionTypeRecordingProxy
} else {
logger.Info("FBS recording is turned off")
}
proxy.StartListening() proxy.StartListening()
} }

View File

@ -1,10 +1,10 @@
package proxy package proxy
import ( import (
"vncproxy/client" "github.com/amitbet/vncproxy/client"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"vncproxy/server" "github.com/amitbet/vncproxy/server"
) )
type ClientUpdater struct { type ClientUpdater struct {

View File

@ -5,18 +5,19 @@ import (
"path" "path"
"strconv" "strconv"
"time" "time"
"vncproxy/client"
"vncproxy/common" "github.com/amitbet/vncproxy/client"
"vncproxy/encodings" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/encodings"
"vncproxy/player" "github.com/amitbet/vncproxy/logger"
listeners "vncproxy/recorder" "github.com/amitbet/vncproxy/player"
"vncproxy/server" listeners "github.com/amitbet/vncproxy/recorder"
"github.com/amitbet/vncproxy/server"
) )
type VncProxy struct { type VncProxy struct {
TcpListeningUrl string // empty = not listening on tcp TCPListeningURL string // empty = not listening on tcp
WsListeningUrl string // empty = not listening on ws WsListeningURL string // empty = not listening on ws
RecordingDir string // empty = no recording RecordingDir string // empty = no recording
ProxyVncPassword string //empty = no auth ProxyVncPassword string //empty = no auth
SingleSession *VncSession // to be used when not using sessions SingleSession *VncSession // to be used when not using sessions
@ -24,8 +25,17 @@ type VncProxy struct {
sessionManager *SessionManager sessionManager *SessionManager
} }
func (vp *VncProxy) createClientConnection(targetServerUrl string, vncPass string) (*client.ClientConn, error) { func (vp *VncProxy) createClientConnection(target string, vncPass string) (*client.ClientConn, error) {
nc, err := net.Dial("tcp", targetServerUrl) var (
nc net.Conn
err error
)
if target[0] == '/' {
nc, err = net.Dial("unix", target)
} else {
nc, err = net.Dial("tcp", target)
}
if err != nil { if err != nil {
logger.Errorf("error connecting to vnc server: %s", err) logger.Errorf("error connecting to vnc server: %s", err)
@ -85,7 +95,12 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
session.Status = SessionStatusInit session.Status = SessionStatusInit
if session.Type == SessionTypeProxyPass || session.Type == SessionTypeRecordingProxy { if session.Type == SessionTypeProxyPass || session.Type == SessionTypeRecordingProxy {
cconn, err := vp.createClientConnection(session.TargetHostname+":"+session.TargetPort, session.TargetPassword) target := session.Target
if session.TargetHostname != "" && session.TargetPort != "" {
target = session.TargetHostname + ":" + session.TargetPort
}
cconn, err := vp.createClientConnection(target, session.TargetPassword)
if err != nil { if err != nil {
session.Status = SessionStatusError session.Status = SessionStatusError
logger.Errorf("Proxy.newServerConnHandler error creating connection: %s", err) logger.Errorf("Proxy.newServerConnHandler error creating connection: %s", err)
@ -171,19 +186,19 @@ func (vp *VncProxy) StartListening() {
UseDummySession: !vp.UsingSessions, UseDummySession: !vp.UsingSessions,
} }
if vp.TcpListeningUrl != "" && vp.WsListeningUrl != "" { if vp.TCPListeningURL != "" && vp.WsListeningURL != "" {
logger.Infof("running two listeners: tcp port: %s, ws url: %s", vp.TcpListeningUrl, vp.WsListeningUrl) logger.Infof("running two listeners: tcp port: %s, ws url: %s", vp.TCPListeningURL, vp.WsListeningURL)
go server.WsServe(vp.WsListeningUrl, cfg) go server.WsServe(vp.WsListeningURL, cfg)
server.TcpServe(vp.TcpListeningUrl, cfg) server.TcpServe(vp.TCPListeningURL, cfg)
} }
if vp.WsListeningUrl != "" { if vp.WsListeningURL != "" {
logger.Infof("running ws listener url: %s", vp.WsListeningUrl) logger.Infof("running ws listener url: %s", vp.WsListeningURL)
server.WsServe(vp.WsListeningUrl, cfg) server.WsServe(vp.WsListeningURL, cfg)
} }
if vp.TcpListeningUrl != "" { if vp.TCPListeningURL != "" {
logger.Infof("running tcp listener on port: %s", vp.TcpListeningUrl) logger.Infof("running tcp listener on port: %s", vp.TCPListeningURL)
server.TcpServe(":"+vp.TcpListeningUrl, cfg) server.TcpServe(vp.TCPListeningURL, cfg)
} }
} }

View File

@ -4,11 +4,12 @@ import "testing"
func TestProxy(t *testing.T) { func TestProxy(t *testing.T) {
//create default session if required //create default session if required
t.Skip("this isn't an automated test, just an entrypoint for debugging")
proxy := &VncProxy{ proxy := &VncProxy{
WsListeningUrl: "http://0.0.0.0:7778/", // empty = not listening on ws WsListeningURL: "http://0.0.0.0:7778/", // empty = not listening on ws
RecordingDir: "d:\\", // empty = no recording RecordingDir: "d:\\", // empty = no recording
TcpListeningUrl: ":5904", TCPListeningURL: ":5904",
//RecordingDir: "C:\\vncRec", // empty = no recording //RecordingDir: "C:\\vncRec", // empty = no recording
ProxyVncPassword: "1234", //empty = no auth ProxyVncPassword: "1234", //empty = no auth
SingleSession: &VncSession{ SingleSession: &VncSession{

View File

@ -16,6 +16,7 @@ const (
) )
type VncSession struct { type VncSession struct {
Target string
TargetHostname string TargetHostname string
TargetPort string TargetPort string
TargetPassword string TargetPassword string

View File

@ -5,11 +5,11 @@ import (
"net" "net"
"os" "os"
"time" "time"
"vncproxy/client" "github.com/amitbet/vncproxy/client"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/encodings"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"vncproxy/recorder" "github.com/amitbet/vncproxy/recorder"
) )
func main() { func main() {

View File

@ -5,9 +5,9 @@ import (
"encoding/binary" "encoding/binary"
"os" "os"
"time" "time"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"vncproxy/server" "github.com/amitbet/vncproxy/server"
) )
type Recorder struct { type Recorder struct {

View File

@ -2,9 +2,9 @@ package recorder
import ( import (
"time" "time"
"vncproxy/client" "github.com/amitbet/vncproxy/client"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type RfbRequester struct { type RfbRequester struct {

View File

@ -3,7 +3,7 @@ package server
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
// Key represents a VNC key press. // Key represents a VNC key press.

View File

@ -3,10 +3,10 @@ package server
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"io" "io"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
const ProtoVersionLength = 12 const ProtoVersionLength = 12

View File

@ -6,7 +6,7 @@ import (
"crypto/rand" "crypto/rand"
"errors" "errors"
"log" "log"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
type SecurityType uint8 type SecurityType uint8

View File

@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"io" "io"
"sync" "sync"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
) )
type ServerConn struct { type ServerConn struct {

View File

@ -5,7 +5,7 @@ import (
"io" "io"
"log" "log"
"net" "net"
"vncproxy/common" "github.com/amitbet/vncproxy/common"
) )
var DefaultClientMessages = []common.ClientMessage{ var DefaultClientMessages = []common.ClientMessage{

View File

@ -3,8 +3,9 @@ package server
import ( import (
"log" "log"
"testing" "testing"
"vncproxy/common"
"vncproxy/encodings" "github.com/amitbet/vncproxy/common"
"github.com/amitbet/vncproxy/encodings"
) )
func newServerConnHandler(cfg *ServerConfig, conn *ServerConn) error { func newServerConnHandler(cfg *ServerConfig, conn *ServerConn) error {
@ -13,6 +14,7 @@ func newServerConnHandler(cfg *ServerConfig, conn *ServerConn) error {
} }
func TestServer(t *testing.T) { func TestServer(t *testing.T) {
t.Skip("this isn't an automated test, just an entrypoint for debugging")
//chServer := make(chan common.ClientMessage) //chServer := make(chan common.ClientMessage)
chClient := make(chan common.ServerMessage) chClient := make(chan common.ServerMessage)

View File

@ -4,7 +4,7 @@ import (
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
"vncproxy/logger" "github.com/amitbet/vncproxy/logger"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
) )