vadimpronin / guacamole-lite

Node.js library for creating Guacamole-compatible servers. Guacamole is a RDP/VNC/SSH/Telnet client for HTML5 browsers.
Apache License 2.0
250 stars 78 forks source link

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

Closed peererror closed 7 years ago

peererror commented 7 years ago

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

vadimpronin commented 7 years ago

Could you please do the following:

  1. Enable verbose logging in your guac-lite app by adding property log to clientOptions like this:

    const clientOptions = {
    log: {
        verbose: true
    },
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
    };
  2. Try to establish connection through guacamole-lite

  3. Post your guacamole-lite output here.

peererror commented 7 years ago

here are the logs but the same code is working for rdp

[2017-05-26 02:42:54] [Connection 1]  Client connection open
[2017-05-26 02:42:54] [Connection 1]  Opening guacd connection
[2017-05-26 02:42:54] [Connection 1]  guacd connection open
[2017-05-26 02:42:54] [Connection 1]  Selecting connection type: vnc
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 6.select,3.vnc;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 6.select,3.vnc;***
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 4.size,9.undefined,9.undefined,9.undefined;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 4.size,9.undefined,9.undefined,9.undefined;***
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 5.audio;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 5.audio;***
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 5.video;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 5.video;***
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 5.image;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 5.image;***
[2017-05-26 02:42:54] [Connection 1]  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,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
[2017-05-26 02:42:54] [Connection 1]  Sending opCode: 0.,0.,0.,0.,0.,8.pAsSwOrD,0.,0.,0.,0.,0.,9.10.0.0.12,4.5901,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.;
[2017-05-26 02:42:54] [Connection 1]  <<<W2G< 0.,0.,0.,0.,0.,8.pAsSwOrD,0.,0.,0.,0.,0.,9.10.0.0.12,4.5901,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.;***
[2017-05-26 02:42:54] [Connection 1]  Closing guacd connection
[2017-05-26 02:42:54] [Connection 1]  Client connection closed
vadimpronin commented 7 years ago

Ok. One part of the problem was that guacamole-lite didn't have any default connection parameters for VNC protocol (like height, width, dpi, port, etc). I've fixed that in 0.4.4 so please update and see if it works.

Another part is that you haven't configured hostname and port in your connection settings. Instead you have dest-host and dest-port which are only used if you have vnc repeater.

These are the arguments that guacamole-lite is actually sending to your guacd (as per your log):

     "args" => "",
     "hostname" => "",
     "port" => "",
     "read-only" => "",
     "encodings" => "",
     "password" => "pAsSwOrD",
     "swap-red-blue" => "",
     "color-depth" => "",
     "cursor" => "",
     "autoretry" => "",
     "clipboard-encoding" => "",
     "dest-host" => "10.0.0.12",
     "dest-port" => "5901",
     "reverse-connect" => "",
     "listen-timeout" => "",
     "enable-sftp" => "",
     "sftp-hostname" => "",
     "sftp-port" => "",
     "sftp-username" => "",
     "sftp-password" => "",
     "sftp-private-key" => "",
     "sftp-passphrase" => "",
     "sftp-directory" => "",

As you see hostname and port are empty, but they mustn't be.

Let me know if the update to 0.4.4 and fixing the parameters will work for you

vadimpronin commented 7 years ago

No reply, so I'm closing the issue. Feel free to reopen if needed

vnydev commented 2 years ago

Hi @vadimpronin ,

I would like to reopen this 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;