mirror of
https://github.com/amitbet/vncproxy.git
synced 2025-04-30 03:53:22 +00:00
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ea8f9b5109 | ||
|
faa9021021 | ||
|
1c052273de | ||
|
f07be04814 | ||
|
55cf83519a | ||
|
92ee157817 | ||
|
f635a73757 | ||
|
149e26b6f7 | ||
|
3d42d4fa5f | ||
|
f66f550c77 | ||
|
c7ac36d15f | ||
|
0ba10fab76 | ||
|
76299f1bc3 | ||
|
a9dce0e6c6 | ||
|
fa416220ea | ||
|
efc5741057 | ||
|
82e1549c4f | ||
|
33be77dedc | ||
|
11b1d45ce9 | ||
|
42873297d2 | ||
|
f00e2c33e7 | ||
|
9a52a433ea | ||
|
06e555775f | ||
|
3e882d6140 | ||
|
5a488bcd0f |
129
.circleci/config.yml
Normal file
129
.circleci/config.yml
Normal 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
|
@ -1,9 +1,10 @@
|
|||||||
# VncProxy
|
# VncProxy [](https://circleci.com/gh/amitbet/vncproxy/tree/master) [](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=@!@!@!
|
||||||
|
|
||||||
|
2
build.sh
2
build.sh
@ -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=""
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 (
|
||||||
|
@ -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 {
|
||||||
|
@ -2,7 +2,7 @@ package encodings
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"vncproxy/common"
|
"github.com/amitbet/vncproxy/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PseudoEncoding struct {
|
type PseudoEncoding struct {
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
3
go.mod
Normal 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
2
go.sum
Normal 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=
|
@ -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() {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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{
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user