You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@guacamole.apache.org by Veetz <al...@wrk.com> on 2021/05/20 22:52:43 UTC

Embedding RDP Connection in Custom Website

Hello, I'm new to Guacamole and as the title states, I am trying to embed an
RDP connection inside of a custom website. 

First, I wonder if there is a tutorial or docs somewhere that clearly
outline the process? I couldn't find much info anywhere that clearly outline
the steps that are required and instead, I find myself trying to reverse
engineer the front end AngularJS code for the Guacamole Web Server UI that
is able to provide such an RDP connection inside of the HTML.

Next, the area where I am currently stuck is creating the Guacamole client
using a WebSocket tunnel. For context, the Guacamole Web Server and website
that I want to embed the RDP connection are on completely different domains
/ urls, so when I pass the `tunnelUrl` parameter, I am giving full path. 

Here is my code: 

            let tunnel;
            if (window.WebSocket) {
                const authToken = localStorage.getItem('authToken');
                const connectUrl =
`ws://localhost:8080/guacamole/websocket-tunnel?token=${encodeURIComponent(authToken)}&GUAC_DATA_SOURCE=mysql&GUAC_ID=5&GUAC_TYPE=c&GUAC_WIDTH=1007&GUAC_HEIGHT=981&GUAC_DPI=96&GUAC_TIMEZONE=America%2FVancouver&GUAC_AUDIO=audio%2FL8&GUAC_AUDIO=audio%2FL16&GUAC_IMAGE=image%2Fjpeg&GUAC_IMAGE=image%2Fpng&GUAC_IMAGE=image%2Fwebp`
                tunnel = new Guacamole.ChainedTunnel(
                    new Guacamole.WebSocketTunnel(connectUrl),
                )
            }
            const client = new Guacamole.Client(tunnel);


The result is a request which does not succeed in the same way that it does
for the Guac Web Server UI when performing RDP connection. There is an extra
`?undefined` at the end as you can see here:

Request URL:
ws://localhost:8080/guacamole/websocket-tunnel?token=0B1AB7A2B98659851D3681F5F63BA328D34A4D802295656F148DB232B395D0E8&GUAC_DATA_SOURCE=mysql&GUAC_ID=5&GUAC_TYPE=c&GUAC_WIDTH=1007&GUAC_HEIGHT=981?undefined

I do not get a status code of `101` like I do in the Guac Server UI. 


Any help appreciated.



--
Sent from: http://apache-guacamole-general-user-mailing-list.2363388.n4.nabble.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@guacamole.apache.org
For additional commands, e-mail: user-help@guacamole.apache.org


Re: Embedding RDP Connection in Custom Website

Posted by Mike Jumper <mi...@glyptodon.com>.
On Mon, May 24, 2021 at 11:34 AM Veetz <al...@wrk.com> wrote:

> Ok nevermind, figured it out.
>
> There is a `connect` method part of the HTTPTunnel class which is used for
> updating the connection string data:
>
>             const httpTunnel = new Guacamole.HTTPTunnel(httpConnectUrl2,
> true, {
>                 data: JSON.stringify({
>                     GUAC_ID: 5
>                 })
>             });
>
>
> httpTunnel.connect(`GUAC_ID=5&GUAC_TYPE=c&GUAC_DATA_SOURCE=mysql&token=${authToken}`)
>

Yes, but to clarify:

"GUAC_ID", "GUAC_TYPE", the auth token, etc. are all parameters specific to
the tunnel implementations provided by the mainline Guacamole webapp. A
third-party web application leveraging guacamole-common and
guacamole-common-js is free to use whatever parameters it likes. Those are
the parameters we chose when implementing Guacamole. They may not be the
parameters you need for your use case for your web application.

For example, take a look at the "guacamole-example" web application
demonstrating basic use of guacamole-common and guacamole-common-js:

https://github.com/apache/guacamole-client/tree/master/doc/guacamole-example

Its tunnel doesn't use any parameters *at all*:

https://github.com/apache/guacamole-client/blob/c431e9e22d63c24b87d3274db2bd411c8b864a78/doc/guacamole-example/src/main/java/org/apache/guacamole/net/example/DummyGuacamoleTunnelServlet.java
https://github.com/apache/guacamole-client/blob/c431e9e22d63c24b87d3274db2bd411c8b864a78/doc/guacamole-example/src/main/webapp/index.html#L55-L56

The mainline web application uses its own "GUAC_ID", "GUAC_TYPE", etc.
parameters to pull connection data that it then uses to drive the
parameters shipped off to guacd. A third-party webapp could do the same, or
could determine this information dynamically, or could pull this
information from the user's session, or could retrieve this information
from an internal service ... it's entirely up to you. The core Guacamole
APIs provide the core remote desktop functionality and cross-browser event
handling, while the rest of the user experience is up to the webapp using
those APIs.

Michael Jumper
CEO, Lead Developer
Glyptodon Inc <https://glyp.to/>.

Re: Embedding RDP Connection in Custom Website

Posted by Veetz <al...@wrk.com>.
Ok nevermind, figured it out. 

There is a `connect` method part of the HTTPTunnel class which is used for
updating the connection string data:

            const httpTunnel = new Guacamole.HTTPTunnel(httpConnectUrl2,
true, {
                data: JSON.stringify({
                    GUAC_ID: 5
                })
            });
           
httpTunnel.connect(`GUAC_ID=5&GUAC_TYPE=c&GUAC_DATA_SOURCE=mysql&token=${authToken}`)



--
Sent from: http://apache-guacamole-general-user-mailing-list.2363388.n4.nabble.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@guacamole.apache.org
For additional commands, e-mail: user-help@guacamole.apache.org


Re: Embedding RDP Connection in Custom Website

Posted by Veetz <al...@wrk.com>.
> The above walks through creating a web application that uses the HTTP
tunnel only. The Java side of the WebSocket tunnel is trickier (the standard
Java API for WebSocket is entirely different from the Java Servlet API), and
your best example for how the WebSocket tunnel can be used is still the
mainline Guacamole webapp.

Ok, I will start trying to use HTTP tunnel only for the time being and can
revisit web socket after.

In the example you linked, it seems to describe setting up the tunnel on the
same domain / host as the Guacamole Java Server, I want to set up this
connection in a cross origin type manner, so I tried to do the following:

            const httpConnectUrl = `http://localhost:8080/guacamole/tunnel`
            const httpTunnel = new Guacamole.HTTPTunnel(httpConnectUrl,
true);
            const client = new Guacamole.Client(httpTunnel);

The generated HTTP request from above looks like this:

curl 'http://localhost:8080/guacamole/tunnel?connect' \
  -X 'POST' \
  -H 'Connection: keep-alive' \
  -H 'Content-Length: 0' \
  -H 'sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google
Chrome";v="90"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/90.0.4430.212 Safari/537.36' \
  -H 'Content-type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Accept: */*' \
  -H 'Sec-Fetch-Site: same-site' \
  -H 'Sec-Fetch-Mode: cors' \
  -H 'Sec-Fetch-Dest: empty' \
  -H 'Referer: http://localhost:3000/' \
  -H 'Accept-Language: en-GB,en-US;q=0.9,en;q=0.8' \
  -H 'Cookie: io=-FmdbVjhauviIG8JAAE4' \
  --compressed

I see a response status of `400` and a response header of:
`Guacamole-Error-Message: Parameter "GUAC_ID" is required.`

How can I add this `GUAC_ID` to the request? I see that when attempting to
create an HTTP tunnel via `new Guacamole.HTTPTunnel(...)`, there is a
parameter of `?connect=` appended to the end of the URL, but I don't see how
to add query string parameters to this `?connect` param.. so even if I do:

        const httpTunnel = new
Guacamole.HTTPTunnel("http://localhost:8080/guacamole/tunnel?GUAC_ID=5,
true);

The resulting URL will be
`"http://localhost:8080/guacamole/tunnel?GUAC_ID=5?connect"` .. which I
don't believe is a valid URL.





--
Sent from: http://apache-guacamole-general-user-mailing-list.2363388.n4.nabble.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@guacamole.apache.org
For additional commands, e-mail: user-help@guacamole.apache.org


Re: Embedding RDP Connection in Custom Website

Posted by Mike Jumper <mi...@glyptodon.com>.
On Thu, May 20, 2021 at 3:52 PM Veetz <al...@wrk.com> wrote:

> Hello, I'm new to Guacamole and as the title states, I am trying to embed
> an
> RDP connection inside of a custom website.
>
> First, I wonder if there is a tutorial or docs somewhere that clearly
> outline the process? I couldn't find much info anywhere that clearly
> outline
> the steps that are required and instead, I find myself trying to reverse
> engineer the front end AngularJS code for the Guacamole Web Server UI that
> is able to provide such an RDP connection inside of the HTML.
>

Depending on exactly what you're trying to achieve, integrating the full
mainline webapp may be overkill. You can implement your own, stripped-down
web application that establishes connections however you like and be in
full control:

http://guacamole.apache.org/doc/gug/writing-you-own-guacamole-app.html

The above walks through creating a web application that uses the HTTP
tunnel only. The Java side of the WebSocket tunnel is trickier (the
standard Java API for WebSocket is entirely different from the Java Servlet
API), and your best example for how the WebSocket tunnel can be used is
still the mainline Guacamole webapp.

Next, the area where I am currently stuck is creating the Guacamole client
> using a WebSocket tunnel. For context, the Guacamole Web Server and website
> that I want to embed the RDP connection are on completely different domains
> / urls, so when I pass the `tunnelUrl` parameter, I am giving full path.
>
> Here is my code:
>
>             let tunnel;
>             if (window.WebSocket) {
>                 const authToken = localStorage.getItem('authToken');
>                 const connectUrl =
>
> `ws://localhost:8080/guacamole/websocket-tunnel?token=${encodeURIComponent(authToken)}&GUAC_DATA_SOURCE=mysql&GUAC_ID=5&GUAC_TYPE=c&GUAC_WIDTH=1007&GUAC_HEIGHT=981&GUAC_DPI=96&GUAC_TIMEZONE=America%2FVancouver&GUAC_AUDIO=audio%2FL8&GUAC_AUDIO=audio%2FL16&GUAC_IMAGE=image%2Fjpeg&GUAC_IMAGE=image%2Fpng&GUAC_IMAGE=image%2Fwebp`
>                 tunnel = new Guacamole.ChainedTunnel(
>                     new Guacamole.WebSocketTunnel(connectUrl),
>                 )
>             }
>             const client = new Guacamole.Client(tunnel);
>
> The result is a request which does not succeed in the same way that it does
> for the Guac Web Server UI when performing RDP connection. There is an
> extra
> `?undefined` at the end as you can see here:
>
> Request URL:
>
> ws://localhost:8080/guacamole/websocket-tunnel?token=0B1AB7A2B98659851D3681F5F63BA328D34A4D802295656F148DB232B395D0E8&GUAC_DATA_SOURCE=mysql&GUAC_ID=5&GUAC_TYPE=c&GUAC_WIDTH=1007&GUAC_HEIGHT=981?undefined
>

What does your call to client.connect() look like?

I do not get a status code of `101` like I do in the Guac Server UI.
>

What status code do you get back and what is the content of the response,
if anything?

Michael Jumper
CEO, Lead Developer
Glyptodon Inc <https://glyp.to/>.