Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL based authentication #3575

Closed
fpom opened this issue Jul 12, 2022 · 8 comments
Closed

URL based authentication #3575

fpom opened this issue Jul 12, 2022 · 8 comments
Labels
authentication enhancement New feature or request

Comments

@fpom
Copy link

fpom commented Jul 12, 2022

I'd need a new authentication method, similar to what exists with ttyd: when started with option --base-path /random-token, ttyd's server only accepts requests rooted at path /random-token. This option allows the distribution of this path to remote clients that can directly connect without further authentication.

Could xpra have such a feature? I can easily imagine having --auth=base:root=/random-token in the CLI or something similar.

@fpom fpom added the enhancement New feature or request label Jul 12, 2022
@totaam
Copy link
Collaborator

totaam commented Jul 12, 2022

Would this be for the html5 client?
I don't really see how that's different than using a random password and specifying it as a URL argument.

@fpom
Copy link
Author

fpom commented Jul 12, 2022

Yes, that's indeed for the HTML5 client. The problem with the random password in the query string is that my Apache reverse proxy does not correctly forward it. I spawn xpra instances dynamically on different ports. Thus I would need to add dynamically a ProxyPass ws://localhost:20001 and ProxyPassReverse ws://localhost:20001 to Apache each time a new port is used, which is not possible.

@totaam
Copy link
Collaborator

totaam commented Jul 12, 2022

I don't really see how that helps solve the problem then.
Your servers still need to be listening on separate ports. How you map your URLs to those port numbers should be left to apache.

If it was me, I would look into using a UUID with --bind=/path/to/app.sock/UUID then mapping it with:

ProxyPass /ws/ unix:/path/to/app.sock/UUID

If that allows dynamic strings to be used? (assuming that this can also be done safely to prevent directory traversal and such)

@fpom
Copy link
Author

fpom commented Jul 12, 2022

Maybe I'm confused by having tried so many ways of doing it.

With ttyd, I use this configuration:

RewriteRule  ^/ttyd/(\d*)/([^/]*)/ws$   ws://localhost:$1/$2/ws [P,L]
RewriteRule  ^/ttyd/(\d*)/(.*)$         http://localhost:$1/$2  [P,L]

It works perfectly.

With xpra, I use:

RewriteRule  ^/xpra/(\d*)/([^/]*)/(.*)$  http://localhost:$1/$3?password=$2 [P,L]
RewriteCond  %{HTTP:UPGRADE}        ^WebSocket$ [NC]
RewriteCond  %{HTTP:CONNECTION}     ^Upgrade$   [NC]
RewriteRule  ^/xpra/(\d*)/([^/]*)/(.*)$  ws://localhost:$1/$3 [P,L]
ProxyPass         /xpra/\d*/[^/]*/   ws://localhost
ProxyPassReverse  /xpra/\d*/[^/]*/   ws://localhost
ProxyPass         /xpra/\d*/[^/]*/   http://localhost
ProxyPassReverse  /xpra/\d*/[^/]*/   http://localhost

Then I run: xpra start --daemon=no --mdns=no --exit-with-children=yes --exit-with-client=yes --dpi=96 --file-transfer=off --open-files=off --forward-xdg-open=off --idle-timeout=600 --system-tray=no --bell=no --webcam=no --tcp-auth=env --html=path-to-html5 --bind-tcp=0.0.0.0:PORT --start-child=COMMAND with XPRA_PASSWORD=PASSWD in the environment.

And the HTML5 client connects to /xpra/PORT/PASSWD/.

But authentication is refused. My understanding is that something related to authentication does not go through the websockets. Because as far as I've traced the requests and rewritings, everything looks OK. But maybe I'm entirely wrong.

I've also tried passing ?password=PASSWD directly from the HTML5 client, but it did not help.

EDIT: Apache does not allow dynamic strings in the ProxyPass.

@fpom
Copy link
Author

fpom commented Jul 13, 2022

After explaining this, I understood that I had to move my first RewriteRule at the end, and now everything works. Thank you for your prompt help, and sorry for the noise.

@totaam
Copy link
Collaborator

totaam commented Jul 13, 2022

There were other ways of doing this, but this solution turns out to be both simple to implement and quite useful / extensible.

The only commit you need is the second one, it contains a new authentication module, you can even just drop this new file into your existing installation as it should be compatible with older xpra server versions.


Example usage with debugging enabled and full options:

xpra start :20 --no-daemon --bind-tcp=0.0.0.0:10000,auth=capability:property=display,value=FOO --start=xterm --ssl-cert=./ssl

Or just:

xpra start :20 --bind-tcp=0.0.0.0:10000,auth=capability:value=FOO

Since property=display is the default value.

The client can then connect with:

xpra attach ws://localhost:10000/FOO

And only with FOO or FOO?extraparameters. Any other value will be rejected.

@fpom This should allow you to do what you want - please let me know if that works.

I will still have to update the documentation and man page.

totaam added a commit that referenced this issue Jul 13, 2022
@fpom
Copy link
Author

fpom commented Jul 28, 2022

I finally could have query string work, but it will be simpler this way. :)
Thanks!

totaam added a commit that referenced this issue Aug 27, 2022
@totaam
Copy link
Collaborator

totaam commented Sep 2, 2022

As of de46aa3, the URL attributes are correctly forwarded to the server. ie:

xpra attach "ws://localhost:10000/foo?hello=1&FOO=BAR"

Generates the following http request:

New http GET request received from 127.0.0.1:44254 for '/foo%3Fhello%3D1%26FOO%3DBAR'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
authentication enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants