Giter Site home page Giter Site logo

vadimpronin / guacamole-lite Goto Github PK

View Code? Open in Web Editor NEW
223.0 15.0 76.0 113 KB

Node.js library for creating Guacamole-compatible servers. Guacamole is a RDP/VNC/SSH/Telnet client for HTML5 browsers.

License: Apache License 2.0

JavaScript 100.00%
guacamole rdp vnc

guacamole-lite's Introduction

guacamole-lite

Introduction

What is guacamole-lite?

guacamole-lite is a lightweight Node.js library designed to create servers compatible with the Guacamole protocol.

What is Guacamole?

Apache Guacamole is a HTML5 web client for remote desktop environments using protocols such as VNC, RDP, SSH or Telnet.

Why use guacamole-lite?

Unlike the Java-based original guacamole-client, which is a full-featured client with its own user and host management system, guacamole-lite is tailored for integration into existing applications. It is particularly suitable for systems that already have user, host, and credential management in place, offering a more streamlined approach to adopting the Guacamole protocol.

The main differences between guacamole-lite and the Java-based guacamole-client are:

  • Integration-Friendly: guacamole-lite is built to be easily integrated into existing applications, allowing developers to leverage their own systems for managing users, hosts, and credentials. In contrast, guacamole-client comes with a comprehensive suite of features, including its own database for user and host management, which can make integration into existing systems more challenging.

  • Node.js Based: The library is written in Node.js, which provides a more accessible and flexible development experience compared to the Java-based guacamole-client. This makes guacamole-lite easier to extend, modify, and integrate into modern web applications.

  • Resource Efficiency: guacamole-lite is less resource-intensive, making it a more efficient choice for environments where resource optimization is crucial.

By focusing on these key areas, guacamole-lite offers a compelling option for developers looking to implement remote desktop capabilities within their Node.js applications.

Architecture Overview

guacamole-lite is designed to seamlessly fit into the broader Guacamole ecosystem, providing an efficient way to develop Guacamole-compatible servers in Node.js. The following diagram illustrates the typical architecture of a Guacamole deployment and how guacamole-lite integrates within it:

arch

The diagram shows the following components:

  1. HTML5 Browser (guacamole-common-js): This is the user's interface, a HTML5 application that runs in the browser. The user interacts with this layer to get access to remote desktop sessions. The application uses guacamole-common-js, a library that provides the Guacamole protocol implementation in JavaScript.

  2. Guacamole protocol: This communication protocol is used by guacamole-common-js to interact with guacd via guacamole-lite, acting as a proxy. Check out the Guacamole protocol documentation for more details.

  3. Node.js application: A Node.js application that integrates guacamole-lite package. It provides the configuration to guacamole-lite and handles business logic, such as session management.

  4. guacamole-lite package: As the Node.js application component, guacamole-lite implements handshaking of the Guacamole protocol and further forwarding of Guacamole protocol instructions between guacamole-common-js (over WebSockets) and guacd (over TCP or Unix socket).

  5. guacd: A core component of the Guacamole infrastructure, guacd translates the Guacamole protocol instructions into native remote desktop protocol commands. See the Guacamole architecture documentation for more details.

  6. Guacamole Server: A server that hosts Node.js application with guacamole-lite package and guacd. These components are typically deployed together, but they can also be separated into different machines.

  7. Remote Desktop Protocols: The bottommost layer includes the various protocols handled by guacd:

    • RDP (Remote Desktop Protocol): Primarily used for connecting to Windows machines.
    • VNC (Virtual Network Computing): Connects to various operating systems, including Windows, Mac, and Linux.
    • SSH (Secure Shell): Used for secure command-line access to Linux and Unix-like systems.

Overall Data Flow:

  • A user initiates a remote desktop session from their browser.
  • The browser communicates with guacamole-lite via WebSockets.
  • guacamole-lite forwards the instructions to guacd using the Guacamole protocol.
  • guacd interacts with the remote desktop system using the appropriate protocol (RDP, VNC, or SSH).
  • The remote system responds back through the chain: from guacd to guacamole-lite, through WebSockets, and finally to the user's browser, allowing the user to see and control the remote desktop.

The entire process is encapsulated within the "Guacamole server" setup, indicating that both guacamole-lite and guacd are integral parts of the server infrastructure. This architecture allows guacamole-lite to provide a lightweight and flexible solution for integrating remote desktop capabilities into Node.js applications.

Installation

To install guacamole-lite in your Node.js project, run the following command:

npm install guacamole-lite --save

This will add guacamole-lite as a dependency to your package.json file and download it to the node_modules directory.

Before You Start

Before you start, make sure you have guacd installed and running on your server. The easiest way to run guacd is to use the official Docker image:

docker run --name guacd -d -p 4822:4822 guacamole/guacd

Alternatively, you can install guacd from source. For more details, refer to the official documentation on Installing guacamole-server or guacamole-server README on github.

Quick Start Guide

To get started with guacamole-lite and create a Guacamole-compatible server, follow the basic example below. For advanced configuration options, please refer to the relevant sections of the advanced configuration documentation.

Basic guacamole-lite Server Setup

Here's a minimal example to set up a guacamole-lite server:

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // WebSocket server port
};

const guacdOptions = {
    port: 4822 // guacd server port
};

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12' // Use a secure key
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

This code will start a WebSocket server that interfaces with the Guacamole daemon (guacd) and handles client connections securely.

Connecting to the Server

To connect to the server, your application needs to create a WebSocket connection and pass the connection parameters to the server. The connection parameters are passed in an encrypted token in the query string of the WebSocket URL.

ws://your-guacamole-server:8080/?token=token

The encrypted token is a JSON object that is base64-encoded and encrypted. It contains the necessary parameters for establishing a remote desktop like in the example below:

const crypto = require('crypto');

const CIPHER = 'aes-256-cbc';
const SECRET_KEY = 'MySuperSecretKeyForParamsToken12';

const tokenObject = {
    connection: {
        type: "rdp",
        settings: {
            "hostname": "10.0.0.12",
            "username": "Administrator",
            "password": "pAsSwOrD",
            "enable-drive": true,
            "create-drive-path": true,
            "security": "any",
            "ignore-cert": true,
            "enable-wallpaper": false
        }
    }
};

function encryptToken(value) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(CIPHER, Buffer.from(SECRET_KEY), iv);

    let encrypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
    encrypted += cipher.final('base64');

    const data = {
        iv: iv.toString('base64'),
        value: encrypted
    };

    const json = JSON.stringify(data);
    return Buffer.from(json).toString('base64');
}

const token = encryptToken(tokenObject);

console.log("Websockets URL:");
console.log(`ws://localhost:8080/?token=${encodeURIComponent(token)}`);

The token is encrypted for security reasons because it contains sensitive information, such as login credentials to the remote host and to prevent tampering with the parameters which could lead to using the server as a proxy for malicious purposes (see Security Considerations). For details on how to structure the parameters and implement encryption, refer to the Client Options section in the advanced configuration documentation.

For practical examples of how to encrypt the token in different programming languages, check out to the examples directory:

Security Considerations

Unlike the full guacamole-client, guacamole-lite does not maintain its own database for managing users, remote hosts, and credentials. Instead, it relies on the integrating application to supply these parameters. Since the transmission of these parameters occurs through potentially insecure channels, such as the client's browser, it is crucial to ensure their security and integrity. To address these concerns, guacamole-lite employs encrypted tokens to pass connection details.

An encrypted token is a secure method of transmitting information where the data is first converted into a ciphertext using an encryption algorithm and a secret key. This process ensures two critical aspects:

  • Authentication: The encrypted token verifies that the connection parameters were indeed generated by the application and have not been forged or tampered with by any third party.

  • Confidentiality: Sensitive information, such as login credentials to the remote host, remains concealed from the client. Only guacamole-lite and the application that generated the token can decrypt and access the contained information.

For more detailed security guidelines and best practices, please refer to the Encryption and Security section in the advanced configuration documentation.

Advanced Configuration

Most likely you will need to customize guacamole-lite beyond the basic setup. The advanced configuration options allow for fine-tuning of the WebSocket server, guacd communication, default connection settings, and more. Below is an outline of the advanced configuration topics covered in the documentation:

Each section provides detailed information and examples to help you tailor guacamole-lite to your specific needs. Whether you're integrating with existing Node.js frameworks, handling complex logging requirements, or setting up custom callbacks and events, the advanced configuration guide has you covered.

Testing

guacamole-lite comes with a test suite to ensure the stability and reliability of the library. To run the tests:

npm test

Contributing

Contributions to guacamole-lite are welcome! If you're interested in contributing, you can:

  • Report issues or suggest features by submitting an issue on GitHub.
  • Contribute code by forking the repository, making your changes, and creating a pull request.

Acknowledgements

Special thanks to the Guacamole team for creating the original Guacamole project and making it available under the Apache-2.0 license. I want to acknowledge all individual contributors to the project, who have invested their time and effort into improving guacamole-lite.

License

guacamole-lite is made available under the Apache License, Version 2.0 (Apache-2.0), the same license as the original Apache Guacamole project. This license is a permissive open-source license that allows for broad freedom in usage and distribution.

For more details about the Apache-2.0 license and your rights under it, please see the LICENSE file included in the repository.

guacamole-lite's People

Contributors

dependabot[bot] avatar dnapier avatar dngadelha avatar fredericosilva avatar luiso1979 avatar thelamer avatar vadimpronin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

guacamole-lite's Issues

Node.js token generation example

Hello, congrats about the README it would have saved me some time :)

On my usage I had to generate the token from node.js.

const crypto = require('crypto');
const encrypt = data => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(clientOptions.cypher, clientOptions.key, iv);

    let crypted = cipher.update(JSON.stringify(data), 'utf8', 'base64');
    crypted += cipher.final('base64');

    const c = {
        iv: iv.toString('base64')
      , value: crypted
    };

    return new Buffer(JSON.stringify(c)).toString('base64');
};

What do you think about adding it on README?

Potential issue in process exiting

When the node process is aborted (ctrl+c) it hangs permanently at Closing all connections and exiting...

To fix I added process.exit() to the close method. Is this a known issue?

No typescritp support

In order to make guacamole more TS friendly we've created the following declaration file based on how the guacamole-lite app has been built.

// guacamole-lite.d.ts

// See: https://stackoverflow.com/a/49936686/7931540
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends Array<infer U>
    ? Array<DeepPartial<U>>
    : T[P] extends ReadonlyArray<infer U>
    ? ReadonlyArray<DeepPartial<U>>
    : DeepPartial<T[P]>;
};

declare module "guacamole-lite" {
  // See packages/client/models/guacamole.ts for other guacamole related types which should be served by "guacamole-lite"

  /**
   * This should have next type structure: https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback [1]
   * But guacamole-lite is using a really old version(1.1.2) of ws(now 8.13.0)
   */
  export interface WsServerOptions {
    port?: number;
  }

  /*
   * This configuration object is used inside the guacamole-lite server to establish the connection with the guacd using the following overload of `Net.connect`
   * function connect(port: number, host?: string, connectionListener?: () => void): Socket;
   * See: https://github.com/vadimpronin/guacamole-lite/blob/d2f4ce1ec1847781ca3667066c9e286624d8e432/lib/GuacdClient.js#L23
   */
  export interface GuacdConnectOptions {
    port?: number;
    host?: string;
  }

  enum GuacamoleLogLevel {
    QUIET = 0,
    ERRORS = 10,
    NORMAL = 20,
    VERBOSE = 30,
    DEBUG = 40,
  }

  /**
   * This configuration object comes from this lines of code used inside the Server.js
   * See: https://github.com/vadimpronin/guacamole-lite/blob/d2f4ce1ec1847781ca3667066c9e286624d8e432/lib/Server.js#L34-L107
   */
  interface __GuacamoleClientOptions {
    maxInactivityTime: number;
    log: {
      level: GuacamoleLogLevel;
      stdLog: typeof console.log;
      errorLog: typeof console.error;
    };

    crypt: {
      cypher: string;
    };

    connectionDefaultSettings: {
      rdp: {
        args: string;
        port: string;
        width: number;
        height: number;
        dpi: number;
      };
      vnc: {
        args: string;
        port: string;
        width: number;
        height: number;
        dpi: number;
      };
      ssh: {
        args: string;
        port: number;
        width: number;
        height: number;
        dpi: number;
      };
      telnet: {
        args: string;
        port: number;
        width: number;
        height: number;
        dpi: number;
      };
    };

    allowedUnencryptedConnectionSettings: {
      rdp: string[];
      vnc: string[];
      ssh: string[];
      telnet: string[];
    };
  }

  export type GuacamoleClientOptions = DeepPartial<__GuacamoleClientOptions> & {
    crypt: {
      key: string;
    };
  };

  export default class GuacamoleLite {
    constructor(
      websocketOptions: WsServerOptions,
      guacdOptions: GuacdConnectOptions,
      clientOptions: GuacamoleClientOptions
    );
  }
}

Decrypt method in Crypt.js fails

I was always getting a failure in the Decrypt method due to character issues. I had to replace one line to get it to work.

This:
let encoded = JSON.parse(this.constructor.base64decode(encodedString));

Became this:
let tempJSON = this.constructor.base64decode(encodedString) let encoded = JSON.parse(tempJSON.substr(0, tempJSON.indexOf('}')+1));

About size of screen

Hi:
When I try to resize the picture, but it not works. My params is ws://192.168.1.115:8081/?token=token&width=1080&height=1920&dpi=32. I can see the picture but can't resize it.
thank you.

Audio input unsupported

Hello,

I got this error on log. I am using guacamole-lite v0.7.1 and guacamole-common.js v1.4.0.

 [Connection 2]  <<<W2G< 5.audio,1.1,31.audio/L16;rate=44100,channels=2;***
 [Connection 2]  >>>G2W> 3.ack,1.1,23.Audio input unsupported,3.256;4.sync,11.10696423475;###

I added GUAC_AUDIO parameter (GUAC_AUDIO=audio/L8&GUAC_AUDIO=audio/L16) on token. So, output audio works.
Does anyone know how to authorize access to the microphone?

Any help would be appreciated.

How-to debug a WS connection

I find this project to be exceptionally fascinating, exemplifying an impressive achievement in engineering.

I've attempted to use it, but, truth be told, I've only succeeded in establishing an SSH connection. However, after a short period or upon pressing the enter key, the WebSocket connection terminates, accompanied by a server-launched message: "disconnect."

I'm curious to know if you're currently utilizing it and, if so, whether it's functioning well for you. If it is, could you please share the remote desktop servers you're using and the versions of guacd and guacamole-common-js?

Lastly, could someone provide some guidance on debugging the unexpected closure of websockets?

How to use guacamole-lite from the frontend ?

I'm trying to use this from my angular app , running on port 4200 in order to connect to an external desktop running on a given IP address. Here's the code I could achieve for that purpose so far :

import { Component, OnInit } from '@angular/core';
import { RemoteDesktopManager } from '@illgrenoble/ngx-remote-desktop';
import { WebSocketTunnel } from '@illgrenoble/guacamole-common-js';
import { Guacamole } from 'guacamole-common-js';
import { GuacamoleLite } from 'guacamole-lite';
  @Component({
   selector: 'app-rdp',
   templateUrl: './rdp.component.html',
   styleUrls: ['./rdp.component.scss']
   })
  export class RDPComponent implements OnInit {

  private manager: RemoteDesktopManager;
  ngOnInit() {
    // Setup tunnel. The tunnel can be either: WebsocketTunnel, HTTPTunnel or ChainedTunnel
    const tunnel = new WebSocketTunnel('ws://localhost:4200');
    const client = new Guacamole.Client(tunnel);
    document.body.appendChild(client.getDisplay().getElement());
    /**
     *  Create an instance of the remote desktop manager by 
     *  passing in the tunnel and parameters
     */
    this.manager = new RemoteDesktopManager(tunnel);
          // URL parameters (image, audio and other query parameters you want to send to the tunnel.)
    const parameters = {
        ip: '120.160.10.149',
        port : 5000,
        type: 'rdp',
        image: 'image/png',
        width: window.screen.width,
        height: window.screen.height,
        username:'username',
        password :'0000'

    };
    this.manager.connect(parameters);
    console.log('tunnel state'+this.manager.getState());
    console.log('Disconnected state'+RemoteDesktopManager.STATE.DISCONNECTED);
}

}

In my console I keep getting this error :
eror

I'm new to this and I don't know what am I missing . any help provided will be good. thank you

Logs in production

Can you disable log when NODE_ENV=production? Or console.log can be replaced to debug module?

Thank you.

Whene I set config "enable-sftp":true,an error has occured

When I try to upload files and add parameters. Here are the logs:

[2018-05-28 18:27:18] [Connection 24]  Client connection open
[2018-05-28 18:27:18] [Connection 24]  Opening guacd connection
[2018-05-28 18:27:18] [Connection 24]  guacd connection open
[2018-05-28 18:27:18] [Connection 24]  Selecting connection type: vnc
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 6.select,3.vnc;
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 4.size,4.1850,3.850,2.96;
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 5.audio;
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 5.video;
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 5.image;
[2018-05-28 18:27:18] [Connection 24]  Server sent handshake: 4.args,8.hostname,4.port,9.read-only,9.encodings,8.password,13.swap-red-blue,11.color-depth,6.cursor,9.autoretry,18.clipboard-encoding,9.dest-host,9.dest-port,12.enable-audio,16.audio-servername,15.reverse-connect,14.listen-timeout,11.enable-sftp,13.sftp-hostname,9.sftp-port,13.sftp-username,13.sftp-password,16.sftp-private-key,15.sftp-passphrase,14.sftp-directory,19.sftp-root-directory,26.sftp-server-alive-interval,14.recording-path,14.recording-name,21.create-recording-path
[2018-05-28 18:27:18] [Connection 24]  Sending opCode: 7.connect,12.10.244.1.225,4.5901,0.,0.,6.123456,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,4.true,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.;
[2018-05-28 18:27:18] [Connection 24]  Closing connection with error:  1006
[2018-05-28 18:27:18] [Connection 24]  Closing guacd connection
[2018-05-28 18:27:18] [Connection 24]  Client connection closed

Thank you!

crypto token

I'm a bit confused regarding the use of the token.

I'm passing a json token to the guacamole-lite server listening at port 8080 from the client side javascript using guacamole-common-js.

It needs to be encrypted with the crypto package but the crypto package is only available on node (server side). The crypto example you gave is for encrypting the token to send to the guacamole-lite server, correct?

What am I missing here?

TightVNC viewer and this server

Hello should I be able to just start this repo then connect for example by TightVNC by typing ip_address:port ?

I opened this repo in Visual code then installed node modules and did nodemon ./index.js

Guacamole protocol violation. Perhaps the version of guacamole-client is incompatible with this version of guacd?

I am having above error when connecting to gucamole .I am trying to connect using vnc protcol and flowing is my setup

`const GuacamoleLite = require('guacamole-lite');
 
const websocketOptions = {
    port: 8080 // we will accept connections to this port 
};
 
const guacdOptions = {
    port: 4822 // port of guacd 
};
 
const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
};
 
const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions); `

and for web service

var express = require('express');
var app = express();
app.use('/', express.static(__dirname + '/public')); // โ† adjust
var fs = require("fs");
var url = require('url');


app.get('/control', function (req, res) {
   var id = req.query.username;
   res.sendfile("guac_control.html");
})


app.get('/listUsers', function (req, res) {
   var id = req.query.username;

	/*{
    	"connection": {
        "type": "rdp",
        "settings": {
            "hostname": "10.0.0.12",
            "username": "Administrator",
            "password": "pAsSwOrD",
            "enable-drive": true,
            "create-drive-path": true,
            "security": "any",
            "ignore-cert": true,
            "enable-wallpaper": false
        }
    }
}
     config.setProtocol("vnc");
	        config.setParameter("hostname", UserIP);
	        config.setParameter("port", UserPort);
	        config.setParameter("password", "23213");
		 
	
	      //config.setParameter("reverse-connect", "true");
	       config.setParameter("password", "123123");
	        config.setParameter("color-depth", "32");
	       // config.setParameter("encodings", "zrle");
	        //nearly 5 mins
	        //config.setParameter("listen-timeout", "50000");
*/
   var clientConnection= {
    	connection : {
         type: "vnc",
         settings : {
             hostname: "127.0.0.1",
	     username :  "root",
             password : "root123"
        }
    }
}
    
   res.send(encrypt(clientConnection));
})

const crypto = require('crypto');

const clientOptions = {
    cypher: 'AES-256-CBC',
    key: 'MySuperSecretKeyForParamsToken12'
}

const encrypt = (value) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(clientOptions.cypher, clientOptions.key, iv);

    let crypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
    crypted += cipher.final('base64');

    const data = {
        iv: iv.toString('base64'),
        value: crypted
    };

    return new Buffer(JSON.stringify(data)).toString('base64');
};

var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("web at http://%s:%s", host, port)

})`

And following are the logs

ay 25 14:47:00 ubuntu guacd[32881]: Protocol "vnc" selected May 25 14:47:00 ubuntu guacd[32881]: Guacamole protocol violation. Perhaps the version of guacamole-client is incompatible with this version of guacd? May 25 14:47:00 ubuntu guacd[32881]: Error reading "connect": Instruction read did not have expected opcode
Please help me .

Thank You

Linux machine renders bottom up

Greetings!
I am working with Ubuntu 22.04 with xrdp on it with security type changed to rdp.
And my gucomole settings are set to RDP. This makes a successful connect but client screen renders bottom up in every resizing action. Even application inside machine renders in bottom up.
How to fix this ?

RDP Audio Support

First off sorry for the wall of text.

Short and to the point question does anyone have a functional RDP client with audio support for guacamole-lite they could share?

On the surface I think maybe guacamole-lite might not be passing file/audio output and input streams from guacd to the javascript client through the websocket tunnel. Though I am not sure, thus why I am reaching out.

I have been trying to reverse engineer audio support from the stock java client, and as far as I can tell they do not do anything special and the base guacamole-common should negotiate the additional InputStream needed for the raw PCM audio supported by modern browsers.
In my custom app and the default java client I am using identical code for the client:
https://cdn.jsdelivr.net/npm/[email protected]/dist/guacamole-client.min.js

When negotiating the connection I am getting identical lines back from guacd with both my custom client/guacamole-lite and the stock java client, so I believe the audio= connectionstring parameters might be redundant as that happens regardless of if they are included or not:

guacd[8]: INFO:	Accepted format: 16-bit PCM with 2 channels at 44100 Hz
guacd[8]: INFO:	Accepted format: 16-bit PCM with 2 channels at 22050 Hz

From a debugging standpoint I have gone through and captured Guacamole.Tunnel.oninstruction events client side and have noticed that specifically there are no audio opcodes being sent to the client to process that are normally processed by this clientside:
https://github.com/apache/guacamole-client/blob/32b106b982dc74e71e1cbb3d2c5e0c5b9b9a8bab/guacamole-common-js/src/main/webapp/modules/Client.js#L884

From a due diligence standpoint I use Docker for development and deployment, if anyone is interested in helping out or debugging you can simply run this Docker container:

docker run --name taisun -d \
--restart always \
-p 3000:3000 \
-p 8000:8000 \
-v /var/run/docker.sock:/var/run/docker.sock \
taisun/webapp

If you hop on port 8000 the rdp client can be found under public/js/rdp.js

You can spinup an RDP client and a guacd instance from the web interface on port 3000 under VDI (no parameters are needed outside of the name)

Also just a side note I have functional audio in the VDI endpoints with xrdp and pulseaudio, I have tested them functional with multiple clients including stock guacamole client 1.0.0 and 1.1.0.

Another thing to mention is after this projects(guacamole-lite) inception Guacamole shifted all the audio tunneling code to raw PCM vs a mix of different mimetypes(ogg vorbis etc) in 0.9.9, not sure if that matters just bringing it up.

Guacamole Error: guacd was inactive for too long

Guacamole-lite and Guacamole-common-js Tunnel connection issue.

I am also facing the same issue ( Closing connection with error: Error: guacd was inactive for too long) . while connecting through WebSocket tunnel on the client side of application using Guacamole-common-js. I am exposing the WS endpoint using Guacamole -lite from Node-JS backend and trying to established the connection between client and WS so i can show the connected guacamole in side the web-application into the browsers.

Basically our requirement is to render the desktop applications of the user on the browser for that we are trying Guacamole RDP/SSH/VNC connection and want to display the respective connected remote server on the browsers to access desktop application.

Please help us its urgent.

Error => Logs

[GcLog] Starting guacamole-lite websocket server
ws guacamole runing on 4822
[GcLog] [2021-12-15 12:37:20] [Connection 1] Client connection open
[GcLog] [2021-12-15 12:37:20] [Connection 1] Opening guacd connection
[GcLog] [2021-12-15 12:37:20] [Connection 1] guacd connection open
[GcLog] [2021-12-15 12:37:20] [Connection 1] Selecting connection type: rdp
[GcLog] [2021-12-15 12:37:20] [Connection 1] Sending opCode: 6.select,3.rdp;
[GcError] [2021-12-15 12:37:30] [Connection 1] Closing connection with error: Error: guacd was inactive for too long
at GuacdClient.checkActivity (C:\Users\vsha8727\CNCX\coding\guacamole\bkgc\node_modules\guacamole-lite\lib\GuacdClient.js:35:41)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
[GcLog] [2021-12-15 12:37:30] [Connection 1] Closing guacd connection
[GcLog] [2021-12-15 12:37:30] [Connection 1] Client connection closed

Client Side Code ->
http://guacamole.incubator.apache.org/doc/gug/guacamole-common-js.html

import React from 'react';
import Guacamole from 'guacamole-common-js';
import { encrypt } from './service';

const connection = {
"connection": {
"type": "rdp",
"settings": {
port: use your port, // port of guacd
host: 'use your host',
username: 'use your username',
password: 'use your password',
}
}
}
const GuacamoleApp: React.FC = () => {
const openGc = async () => {
try {
const token = await encrypt(connection);
console.log("token", token)
const wsurl = ws://localhost:4822/guaclite?token=${token}&width=600&height:600px;
console.log("wsurl", wsurl)
const gc = await new Guacamole.Client(new Guacamole.WebSocketTunnel(wsurl));
console.log("gc", gc)
const display = document.getElementById('gcdisplay');
console.log("element", gc.getDisplay().getElement())
if (display) {
display?.appendChild(gc.getDisplay().getElement());
}

        gc.connect('');
        
    } catch (error: any) {
        console.log("GC Error", error);
    }
}
return <div style={{width: '100%'}}>
    <h1>Guacamole Connect RDP/SSH/VNC</h1>
    <button onClick={openGc}>Open Guacamole</button>
    
    <div id='gcdisplay' style={{minWidth: '800px', minHeight:'600px', backgroundColor:'grey'}}></div>
</div>

}
export default GuacamoleApp;

Backend Side Code ->

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const GuacamoleLite = require('guacamole-lite');
var app = express();
const http = require('http').Server(app);

const guacdOptions = {
port: 'use your port', // port of guacd
host: 'use your host',
username: 'use your username',
password: 'use your password',
};

const clientOptions = {
crypt: {
cypher: 'AES-256-CBC',
key: 'MySuperSecretKeyForParamsToken12'
},
connectionDefaultSetting: {
rdp: {
"security": "NLA (Network Level Authentication)",
"ignore-cert": true,
}
},
log: {
level: 'VERBOSE',
stdLog: (...args) => {
console.log('[GcLog]', ...args)
},
errorLog: (...args) => {
console.error('[GcError]', ...args)
}
}
};

const guacServer = new GuacamoleLite({server: http, path: '/guaclite'}, guacdOptions, clientOptions);

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

http.listen(4822, ()=> console.log('ws guacamole runing on 4822'));
module.exports = app;

Is file uploading provided in this lite client?

It's great to find this project, I'm implementing my own guacamole client, but stuck in file uploading.

I have no idea about how to upload files as described in guacamole-client docs, is it provided in guacamole-common-js or I have to write every thing myself?

Do you get file uploading works? How? Thanks very much.

Guacamole.WebSocketTunnel

Hello There !

I'm trying to use this module and I'm not able to establish the websocoket connection

var client = new Guacamole.Client(
	new Guacamole.WebSocketTunnel("tunnel"),
);
document.body.appendChild(client.getDisplay().getElement());
client.connect('token={{token}}')

This is how looks my json (decrypt token):

{ 
userId: 233, ( I don't know what to put here ?)
expires: 1597818775674,
connection:{ 
     type: 'vnc',
     settings: { 
        password: 'xxxxx',
        port: '5900',
        hostname: '26.0.0.203',
        autosize: 'false' 
} } }

guacd[2342]: ERROR: Guacamole protocol violation. Perhaps the version of guacamole-client is incompatible with this version of guacd?

My client options (I don't see any additional logs with verbose : true )

var clientOptions = {
    log: {
        verbose: true
    },
	crypt : {
		cypher	: 'AES-256-CBC',
		key		: 'MySuperSecretKeyForParamsToken12'
	}
}

I'm using guacd 1.0.0.

Is this module works with 1.0.0+ release?

I'm doing something wrong ?

Thanks for your help !

SSL support?

Does guacamole-lite have SSL support? Can the doc be updated with sample code for it. Thanks!

Is there any default location to put a file into remote server?

#9 In this issue, there is a function for uploading a file into a remote server working with type="input" but I could not see the location of the folder inside of the remote server? How can I declare a common path for such a purpose(also guacd user should have rwx right.) Or Am I missing something for uploading a file?

newConnection usage

Hi, I'm trying to understand when newConnection gets called, if ever. Being outside of the constructor, I'm looking for a call or callback for it, but can't find one. Does it get exported as an event through EventEmitter?

SSH

What about SSH? This connection type is not supported?

wss Error

Hi,

I have the following code --

I run this on the remote machine which I want to access using - VNC

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // we will accept connections to this port
};

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    log: {
        level: 'VERBOSE'
    },
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

And then

I try to connect to it using below code

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Page Title</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" href="">
        <style></style>

        <!-- Guacamole -->
        <script type="text/javascript"
            src="https://unpkg.com/browse/[email protected]/dist/guacamole-common.js"></script>
    </head>
    
    
    <body>
    
        <!-- Display -->
        <div id="display"></div>
    
        <!-- Init -->
        <script type="text/javascript"> /* <![CDATA[ */
    
            // Get display div from document
            var display = document.getElementById("display");
    
            // Instantiate client, using an HTTP tunnel for communications.
            var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://<PUBLIC_IP_OF_MACHINE>:8080")
            );
    
            // Add client to display div
            display.appendChild(guac.getDisplay().getElement());
            
            // Error handler
            guac.onerror = function(error) {
                console.log("Error :: ", error);
                alert(error);
            };
    
            // Connect
           guac.connect('token=<generated_token>');
                                
    
            // Disconnect on close
            window.onunload = function() {
                guac.disconnect();
            }
    
        /* ]]> */ </script>


        <!-- Init -->
        <script type="text/javascript"> /* <![CDATA[ */

            // Mouse
            var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());

            mouse.onmousedown = 
            mouse.onmouseup   =
            mouse.onmousemove = function(mouseState) {
                guac.sendMouseState(mouseState);
            };

            // Keyboard
            var keyboard = new Guacamole.Keyboard(document);

            keyboard.onkeydown = function (keysym) {
                guac.sendKeyEvent(1, keysym);
            };

            keyboard.onkeyup = function (keysym) {
                guac.sendKeyEvent(0, keysym);
            };

        /* ]]> */ </script>
    
    </body>

</html>

In above code - <PUBLIC_IP_OF_MACHINE> - this is public IP of the machine which I want to access using VNC
and - <generated_token> - this is a token generated using the below script ---

const crypto = require('crypto');

const clientOptions = {
    cypher: 'AES-256-CBC',
    key: 'MySuperSecretKeyForParamsToken12'
}

const encrypt = (value) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(clientOptions.cypher, clientOptions.key, iv);

    let crypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
    crypted += cipher.final('base64');

    const data = {
        iv: iv.toString('base64'),
        value: crypted
    };

    return new Buffer(JSON.stringify(data)).toString('base64');
};

console.log("Token : " + encrypt({
    "connection": {
        "type": "vnc",
        "settings": {
            "hostname": "<PUBLIC_IP_OF_MACHINE>",
            "port": "5900",
            "username": "pawan",
            "password": "pawan"           
        }
    }
}));

It works when -- above index.html file is served over http.

When I serve the above - index.html file over https and modify
this

            var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://<PUBLIC_IP_OF_MACHINE>:8080")
            );

as

            var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://<PUBLIC_IP_OF_MACHINE>:8080")
            );

I get the below error in Browser console -

wss -- guacamole-common.js:13108 WebSocket connection to 'wss://<PUBLIC_IP_OF_MACHINE>:8080/?token=<token>' failed: [email protected]:[email protected]:3336(anonymous)@?userId=9had87:50

Any help is much appreciated.

Express issues?

I am attempting to run the client using express but it seems that I am missing something. I am following your example to the letter and cannot get any connections established. Ive got an http server running on 8080; however, its not accepting connections. Can you help?

the desktop jam

When I copy text on the desktop of the RDP protocol, the desktop will jam.Have you ever met such a problem?Thank you!

File downloading broken?

I am unable to manipulate the InputStream from the onfile callback in the client. I do receive the mimetype and filename, but that's it. Has anyone had any luck downloading files (regardless of the method used)?

Send error code and message back to guacamole-common-js

I am currently using nodejs and gaucamole lite but i would like to send an error back to the client / browser where I initiate the connection from guacamole-common-js?

How can i send an error code / code and message back to the client?

ECONNREFUSED 127.0.0.1:4822

Hello there,

I just updated guacd to 1.4 and now I'm not able to connectu guacamole-lite to the guacd server.

Guacamole proxy daemon (guacd) version 1.4.0 started
guacd[16907]: INFO:     Listening on host ::1, port 4822
[Connection 1]  Closing connection with error:  { Error: connect ECONNREFUSED 127.0.0.1:4822

Any idea ?

Thanks for your help !

Guacamole-lite configuration and permission management

Hi Team,
I am looking to implement Guacamole-lite for one of my client requirements to modify Guacamole client UI in a permission-based system.
Can anyone please guide us for the implementation in node js and on the client side for either Angular or Reactjs?

Im too stupid to follow your guide =(

I managed to install and configure Guacamole server on my Rasberry Pi (using apt-get).
I want to use it as a RDP/VNC gateway in my Tesla Model S webbrowser (i want to play monkey island 2 while supercharging) and make a guide that everyone can follow to do the same.
The webbrowser in my car will not even open the first guacamole login page, just shows a white screen.
I had lots of luck with using the opensource Myrtille RDP proxy, but i really want a Linux gateway.
I think Java is the root of the problem and i therefore want to try my luck with Guacamole-light.

But how can i install it in the simplest manner posible? (i dont need any fancy authentication, im just using it in my LAN) Im terrible at programming (i can only make really basic c programs).

My guacamole install resides in: /usr/share/guacamole/guacamole
I downloaded guacamole-light from github and unzipped it to /usr/share/guacamole/guacamole/guacamole-lite-master
From there i ran: sudo npm install --save

And now im stuck in my own incompetence, i dont know how to proceed to replace the local Guacamole java based loginpage with the guacamole-light version.
Can you please help me, if not all the way, give me a push in the right direction?

Facing: guacd was inactive for too long

Hi,

We were successfully able to setup guacamole-lite and guacd, the RDP connection was also happening, Though today we are facing "guacd was inactive for too long".

This is the log:
Starting guacamole-lite websocket server
[2020-08-20 12:19:05] [Connection 1] Client connection open
[2020-08-20 12:19:05] [Connection 1] Opening guacd connection
[2020-08-20 12:19:05] [Connection 1] guacd connection open
[2020-08-20 12:19:05] [Connection 1] Selecting connection type: rdp
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 6.select,3.rdp;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 6.select,3.rdp;***
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 4.size,6.1100px,6.500px?,2.96;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 4.size,6.1100px,6.500px?,2.96;***
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 5.audio,9.audio/L16;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 5.audio,9.audio/L16;***
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 5.video;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 5.video;***
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 5.image;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 5.image;***
[2020-08-20 12:19:05] [Connection 1] Server sent handshake: .....
[2020-08-20 12:19:05] [Connection 1] Sending opCode: 7.......;
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 7.connect,...,0.,.....;***
[2020-08-20 12:19:05] [Connection 1] >>>G2W> 5.ready,37......;###
[2020-08-20 12:19:05] [Connection 1] <<<W2G< 3.ack,1.1,2.OK,1.0;***
[2020-08-20 12:19:09] [Connection 1] <<<W2G< 3.nop;***
[2020-08-20 12:19:14] [Connection 1] <<<W2G< 3.nop;***
[2020-08-20 12:19:16] [Connection 1] Closing connection with error: Error: guacd was inactive for too long
at GuacdClient.checkActivity (/home/ubuntu/node_modules/guacamole-lite/lib/GuacdClient.js:35:41)
at ontimeout (timers.js:482:11)
at tryOnTimeout (timers.js:317:5)
at Timer.listOnTimeout (timers.js:277:5)
[2020-08-20 12:19:16] [Connection 1] Closing guacd connection
[2020-08-20 12:19:16] [Connection 1] Client connection closed

I am passing all params as mentioned here #8, omitted them in logs. Already tried restarting guacd and reinstalling guacamole-lite, no luck so far. What am I missing here?

Getting Token validation failed, Closing connection with error: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined

@fredericosilva @luiso1979 @thelamer @vadimpronin @dnapier I am getting below error in backend code: node index.js
[MyLog] Starting guacamole-lite websocket server
[MyLog] [2021-11-29 09:57:27] [Connection 1] Client connection open
[MyLog] [2021-11-29 09:57:27] [Connection 1] Token validation failed
[MyLog] [2021-11-29 09:57:27] [Connection 1] Closing connection with error: TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
at Function.from (buffer.js:331:9)
at Function.base64decode (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/lib/Crypt.js:24:23)
at Crypt.decrypt (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/lib/Crypt.js:12:39)
at ClientConnection.decryptToken (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/lib/ClientConnection.js:62:22)
at new ClientConnection (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/lib/ClientConnection.js:25:44)
at Server.newConnection (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/lib/Server.js:149:59)
at WebSocketServer.emit (events.js:315:20)
at /Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/node_modules/ws/lib/WebSocketServer.js:91:14
at completeHybiUpgrade2 (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/node_modules/ws/lib/WebSocketServer.js:284:5)
at completeHybiUpgrade1 (/Users/manrajparmar/Documents/projects/alex/guacamole/server/node_modules/guacamole-lite/node_modules/ws/lib/WebSocketServer.js:306:13) {
code: 'ERR_INVALID_ARG_TYPE'
}
[MyLog] [2021-11-29 09:57:27] [Connection 1] Client connection closed

Backend code: ```const GuacamoleLite = require('guacamole-lite');
const express = require('express');
const http = require('http');
const app = express();
// const server = http.createServer(app);
const websocketOptions = {
port: 8080 // we will accept connections to this port
};

const guacdOptions = {
port: 4822 // port of guacd
};

const clientOptions = {
crypt: {
cypher: 'AES-256-CBC',
key: 'MySuperSecretKeyForParamsToken12'
},
log: {
level: 'DEBUG',
stdLog: (...args) => {
console.log('[MyLog]', ...args)
},
errorLog: (...args) => {
console.error('[MyLog]', ...args)
}
}
};

// const guacServer = new GuacamoleLite({server}, guacdOptions, clientOptions);
const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

guacServer.on('open', (clientConnection) => {
console.error("Guac Server call open on event");
// const url = 'http://our-backend-server/api/connection/open?userId=' + clientConnection.connectionSettings.userId
// Http.request(url).end();
});
guacServer.on('close', (clientConnection) => {
console.error("Guac Server call close on event");
// const url = 'http://our-backend-server/api/connection/close?userId=' + clientConnection.connectionSettings.userId
// Http.request(url).end();
});
guacServer.on('error', (clientConnection, error) => {
console.error("Guac Server error: ",clientConnection, error);
});

// var serverPort = process.env.YOUR_PORT || process.env.PORT || 5000;
// server.listen(serverPort, () => {
// console.log("Started on : "+ serverPort);
// })```

Frontend code: `import logo from './logo.svg';
import './App.css';
import Guacamole from "guacamole-common-js";
import { useEffect } from 'react';

function App() {
useEffect(() => {
let guaca = new Guacamole.Client(new Guacamole.WebSocketTunnel('ws://localhost:8080/?token=eyJjb25uZWN0aW9uIjp7InR5cGUiOiJyZHAiLCJzZXR0aW5ncyI6eyJob3N0bmFtZSI6ImxvY2FsaG9zdCIsInVzZXJuYW1lIjoiTWFucmFqIFBhcm1hciIsInBhc3N3b3JkIjoiMTIzNCIsImVuYWJsZS1kcml2ZSI6dHJ1ZSwiY3JlYXRlLWRyaXZlLXBhdGgiOnRydWUsInNlY3VyaXR5IjoiYW55IiwiaWdub3JlLWNlcnQiOnRydWUsImVuYWJsZS13YWxscGFwZXIiOmZhbHNlfX19&width=1024&height=768&dpi=32'));
// let guaca = new Guacamole.Client(new Guacamole.WebSocketTunnel(ws://localhost:8080?token=${JSON.stringify({"connection":{"type":"rdp","settings":{"hostname":"localhost","username":"Manraj Parmar","password":"1234","enable-drive":true,"create-drive-path":true,"security":"any","ignore-cert":true,"enable-wallpaper":false}}})}));
guaca.onerror = function (error) {
alert(error);
};
guaca.connect();
// Disconnect on close
window.onunload = function () {
guaca.disconnect();
}
let display = document.getElementById("display");
display.appendChild(guaca.getDisplay().getElement());
}, [])

return (


Test

);
}

export default App;
`
Can you please have a look and help me on it.
Might be only a small mistake in socket url in frontend code, something missing or wrong in token, so please check and help. please drop a comment.

Unhandled Exception during errors in clientconnection.js

First off, awesome library. Love it.

I'm getting unhanded exceptions and crashing when (I think) users with high latency disconnect (I think). From what I can tell this occurs if the websocket is already disconnected before clientconnection.error fires a server.emit. Handling this would look something like:

ClientConnection.js:

...
error(error) {
        try {
            this.server.emit('error', this, error);
        } catch (err) {
            this.log(this.server.LOGLEVEL.ERRORS, 'Failed to send error to client: ', error);
        }
        this.close(error);
    }
...

I have not been able to reproduce this myself, but am working off stack traces and believe this to be the issue. Can you take a look at this and perhaps add in some catching/validating at this stage?

Not able to connect to VNC | Closing connection with error: Error: not opened

I am having above error when connecting to gucamole .I am trying to connect using vnc protcol and flowing is my setup

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // we will accept connections to this port
};

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    log: {
        verbose: true
    },
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

To generate the Token I am using a script -

const crypto = require('crypto');

const clientOptions = {
    cypher: 'AES-256-CBC',
    key: 'MySuperSecretKeyForParamsToken12'
}

const encrypt = (value) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(clientOptions.cypher, clientOptions.key, iv);

    let crypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
    crypted += cipher.final('base64');

    const data = {
        iv: iv.toString('base64'),
        value: crypted
    };

    return new Buffer(JSON.stringify(data)).toString('base64');
};

console.log("Token : " + encrypt({
    "connection": {
        "type": "vnc",
        "settings": {
            "hostname": "192.168.43.158",
            "port": "5900",
            "username": "pawan",
            "password": "pawan"           
        }
    }
}));

And my client side app looks like this --

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Page Title</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="stylesheet" href="">
        <style></style>

        <!-- Guacamole -->
        <script type="text/javascript"
            src="https://unpkg.com/browse/[email protected]/dist/guacamole-common.js"></script>

        <script type="text/javascript"
        src="/index.js"></script>

    </head>
    
    
    <body>
    
        <!-- Display -->
        <div id="display"></div>
    
        <!-- Init -->
        <script type="text/javascript"> /* <![CDATA[ */
    
            // Get display div from document
            var display = document.getElementById("display");
    
            // Instantiate client, using an HTTP tunnel for communications.
            var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://192.168.43.158:8080?token=eyJpdiI6IjRXamp4VXl1ZTZMZ1BpUHVydjhzM1E9PSIsInZhbHVlIjoiV2QyQVVTbnF1Zk01eW1ERWlQYnNZUnFNK3FrNERFS05XNjkyZC9yM0c1MndxZXZBb3NGNVNqdUVFSUZkR0xOYXVoS2dJVkV6UHlUaXlvZWdoSG90dy9NQ0tFVWtJYWxEanEzRmlCQVFUaHZWRUpVTXhlVjZDRktwV3Q2WVVIeXIrME1kL3lXN2RFN2FwTHMweENjM2pIMU5xTWh1c3crRFNzNTh4Z0xNalJVPSJ9")
            );
    
            // Add client to display div
            display.appendChild(guac.getDisplay().getElement());
            
            // Error handler
            guac.onerror = function(error) {
                console.log("Error :: ", error);
                alert(error);
            };
    
            // Connect
            guac.connect('');
    
            // Disconnect on close
            window.onunload = function() {
                guac.disconnect();
            }
    
        /* ]]> */ </script>
    
    </body>

</html>

I have attached the logs from Server side --

`
[2022-03-08 17:20:23] [Connection 1] Client connection open
[2022-03-08 17:20:23] [Connection 1] Opening guacd connection
[2022-03-08 17:20:23] [Connection 1] guacd connection open
[2022-03-08 17:20:23] [Connection 1] Selecting connection type: vnc
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 6.select,3.vnc;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 6.select,3.vnc;***
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 4.size,4.1024,3.768,2.96;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 4.size,4.1024,3.768,2.96;***
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 5.audio;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 5.audio;***
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 5.video;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 5.video;***
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 5.image;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 5.image;***
[2022-03-08 17:20:23] [Connection 1] Server sent handshake: 4.args,13.VERSION_1_3_0,8.hostname,4.port,9.read-only,9.encodings,8.username,8.password,13.swap-red-blue,11.color-depth,6.cursor,9.autoretry,18.clipboard-encoding,9.dest-host,9.dest-port,12.enable-audio,16.audio-servername,15.reverse-connect,14.listen-timeout,11.enable-sftp,13.sftp-hostname,13.sftp-host-key,9.sftp-port,13.sftp-username,13.sftp-password,16.sftp-private-key,15.sftp-passphrase,14.sftp-directory,19.sftp-root-directory,26.sftp-server-alive-interval,21.sftp-disable-download,19.sftp-disable-upload,14.recording-path,14.recording-name,24.recording-exclude-output,23.recording-exclude-mouse,22.recording-include-keys,21.create-recording-path,12.disable-copy,13.disable-paste,15.wol-send-packet,12.wol-mac-addr,18.wol-broadcast-addr,12.wol-udp-port,13.wol-wait-time,14.force-lossless
[2022-03-08 17:20:23] [Connection 1] Sending opCode: 7.connect,0.,14.192.168.43.158,4.5900,0.,0.,6.pawan,6.pawan,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.;
[2022-03-08 17:20:23] [Connection 1] <<<W2G< 7.connect,0.,14.192.168.43.158,4.5900,0.,0.,6.pawan,6.pawan,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.;***
[2022-03-08 17:20:23] [Connection 1] >>>G2W> 5.ready,37.$44c5724e-15d2-43ab-81b3-038379222a50;5.error,18.Aborted. See logs.,3.519;###
[2022-03-08 17:20:24] [Connection 1] <<<W2G< 10.disconnect;***
[2022-03-08 17:20:24] [Connection 1] >>>G2W> 10.disconnect;###
[2022-03-08 17:20:24] [Connection 1] Closing connection with error: Error: not opened
at WebSocket.send (/home/pawansingh/projects/guacamole/node_modules/ws/lib/WebSocket.js:218:38)
at ClientConnection.send (/home/pawansingh/projects/guacamole/node_modules/guacamole-lite/lib/ClientConnection.js:130:24)
at GuacdClient.sendBufferToWebSocket (/home/pawansingh/projects/guacamole/node_modules/guacamole-lite/lib/GuacdClient.js:172:35)
at GuacdClient.processReceivedData (/home/pawansingh/projects/guacamole/node_modules/guacamole-lite/lib/GuacdClient.js:163:14)
at Socket.emit (node:events:390:28)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9)
at Socket.Readable.push (node:internal/streams/readable:228:10)
at TCP.onStreamRead (node:internal/stream_base_commons:199:23)
[2022-03-08 17:20:24] [Connection 1] Closing guacd connection
[2022-03-08 17:20:24] [Connection 1] Client connection closed

`

Can somebody please help me to understand what I am doing wrong here?
Is My novnc connection param Wrong?
{ "connection": { "type": "vnc", "settings": { "hostname": "192.168.43.158", "port": "5900", "username": "pawan", "password": "pawan" } } }

CC: @vadimpronin / @luiso1979 Don't mean to spam you guys, just a bit desperate for a solution.
Any help is much appreciated!

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.