Xpra-org / xpra

Persistent remote applications for X11; screen sharing for X11, MacOS and MSWindows.
https://xpra.org/
GNU General Public License v2.0
1.91k stars 164 forks source link

http / websockify ssl support #1213

Closed totaam closed 8 years ago

totaam commented 8 years ago

Split from #1136, see 1136/web-ssl.patch

Could be related to #1211, there's something fishy going on with non-blocking sockets (they're blocking).

totaam commented 8 years ago

Worth revisiting now that #1252 is done.

totaam commented 8 years ago

2016-09-01 05:28:35: antoine uploaded file websockify-ssl.patch (6.6 KiB)

attempts at passing an ssl socket to websockify after we have read from it

totaam commented 8 years ago

AFAICT, the big problem with SSL sockets (#1252) is that we cannot peek at the data:

ValueError: non-zero flags not allowed in calls to recv() on <class 'ssl.SSLSocket'>

That's unfortunate since openssl does have a:

/usr/include/openssl/ssl.h:int SSL_peek(SSL *ssl, void *buf, int num);

And pyOpenSSL does have support for it: Add support for SSL_peek. But this is not exposed in the python ssl module, and we cannot access the underlying SSL object to use via ctypes. So we cannot decide immediately if the SSL socket is being used by the client for xpra's protocol or for https / wss, we have to read some data from the socket by starting the IO protocol threads first.

If the SSL connection is for xpra's protocol, all is well and we just process it like normal socket data. For https / wss traffic, we have to re-inject the data we've already written into the socket buffers somehow so that websockify and the python http server can process it.

totaam commented 8 years ago

2016-09-01 07:25:40: antoine uploaded file https.patch (9.1 KiB)

very hackish patch which sort of works for https but not for wss

totaam commented 8 years ago

Also a blocker for wss client support: #1271#comment:4.

totaam commented 8 years ago

2016-09-08 09:34:45: antoine commented


Workaround in r13606: we look for the protocol string in the ssl header and wrap it again with websockify if we find "http/1.1". r13610 + r13612 also makes it possible to specify what type of ssl traffic we want to handle, for the cases where the initial ssl header does not contain enough information to decide what to do with it, as is the case with the websocket client (#1271).


Examples based on the self signed CA from Encryption SSL: The server is started with (replace MODE):

xpra start --start=xterm --bind-tcp=0.0.0.0:10000 \
    --ssl-cert=`pwd`/server.crt --ssl-key=`pwd`/server.key --ssl=MODE

Clients can then connect with: ||# Connection||# Example Command|| || ssl ||xpra attach ssl:127.0.0.1:10000 --ssl-ca-cert=./ca.crt || || tcp ||xpra attach tcp:127.0.0.1:10000 || || ws ||xpra attach ws:127.0.0.1:10000 || || wss ||xpra attach ws:127.0.0.1:10000 --ssl-ca-cert=./ca.crt || || http ||xdg-open http://127.0.0.1:10000 || || https ||xdg-open https://127.0.0.1:10000 || (with the self signed CA, the browser will complain when opening with https unless you add the ca.crt to your list of certificates)

Results for each MODE:

  • auto: all work except for wss (as we cannot determine from the ssl header that the connection is websocket / https traffic)
  • tcp: only tcp and ssl connections can be used, for the other connection types the server shows an error, ie for ws: Error: tcp connection failed: invalid packet header, HTTP GET request
  • www: all work except for ssl (both the client and server log a large error message)
totaam commented 8 years ago

2016-09-16 02:48:06: afarr commented


Tested with 1.0 r13673 win32 client against 1.0 r13742 fedora 23 server.

Installed a self-signed cert per instructions at [| wiki/Encryption/SSL], then grabbed the generated ca.crt to my client windows machine (and ran the wizard to install, just in case).

Server starts as expected with the command line specified there

 xpra --no-daemon --bind-tcp=0.0.0.0:1203 --start-child=xterm --start-child=xterm --mdns=no --start-new-commands=yes --ssl=on --ssl-cert=/home/jimador/ticket-land/ticket1213/server.crt --ssl-key=/home/jimador/ticket-land/ticket1213/server.key start :13

... and the client errors as expected if not using --ssl-server-verify-mode=none when using the ssl:[IP]:[port]

xpra_cmd.exe attach ssl:10.0.32.134:1203 --ssl-ca-cert=\Users\hassenpfeffer\Desktop\random-ticket-info-repository\ca.crt

...

  • Starting the server with MODE=auto or MODE=tcp, and connecting the client with the same --ssl-ca-cert= file path, however, works as expected.
xpra --no-daemon --bind-tcp=0.0.0.0:1203 --start-child=xterm --start-child=xterm --mdns=no --start-new-commands=yes --ssl=on --ssl-cert=/home/jimador/ticket-land/ticket1213/server.crt --ssl-key=/home/jimador/ticket-land/ticket1213/server.key start :13 --ssl=tcp
xpra_cmd.exe attach tcp:10.0.32.134:1203 --ssl-ca-cert=\Users\hassenpfeffer\Desktop\random-ticket-info-repository\ca.crt

As does using ssl:[IP]:[port] client side with the --ssl-server-verify-mode=none flag, though using the ssl:[IP]:[port] with the file path still errors out.

  • As you mentioned, with MODE=www I am able to connect with the tcp:[IP]:[port] with the cert file path, but the ssl:[IP]:[port] fails with a large error message even when trying to use the --ssl-server-verify-mode=none flag (and with the same behavior when trying to pass the cert path on the client).

  • Likewise, I was able to easily enough connect with http, though I think I bungled the signature as far as https in a browser is concerned (chrome might be mad that it was not generated as a sha-1 or sha-256 or something... I'll pursue a little more later).

Looks like everything's working as expected so far though. I'll pass back to you to take a look and see if there's anything else you need tested.

totaam commented 8 years ago

SSL closed at last. Thanks!

As for sha1, see https://security.googleblog.com/2014/09/gradually-sunsetting-sha-1.html - I believe the encryption documentation edit solves this.

totaam commented 7 years ago

Follow up in #1504

See also r27656