Xpra: Ticket #1504: delay SSL socket wrapping

This would allow us to peek at the packet data and decide how to handle the client connection better, partially solving ticket:1213#comment:5.

We would then know if we're dealing with a browser / websocket request or with a plain SSL + TCP client connection.

The ssl=MODE option could then be used for bind-ssl sockets.

The difficulty with this is to ensure that we always eventually wrap the socket with an SSL layer if the user selected bind-ssl and not allow plain TCP / HTTP.

Tue, 20 Jun 2017 16:18:32 GMT - Antoine Martin: priority, status changed

Having to choose which client protocols will be able to handle SSL is annoying. Raising.

Wed, 02 Aug 2017 08:14:20 GMT - Antoine Martin: attachment set

work in progress patch - also adds bind-ws and bind-wss options

Wed, 02 Aug 2017 13:06:50 GMT - Antoine Martin: attachment set

better patch - works in almost all cases (just not wss connect to upgradable tcp)

Thu, 03 Aug 2017 10:13:30 GMT - Antoine Martin:

Merged in r16599. Starting a server with:

xpra start --ssl=auto --ssl-cert=self.pem -d network,http \
    --bind-tcp= \
    --bind-ssl= \
    --bind-ws= \

Then connecting to each port with all the possible connection strings (ie: tcp:localhost:10000, ssl:localhost:10001, ...)

Target Server Port
Client Connection TCP SSL WS WSS
WSS error: upgraded to SSL but not http / websocket error: not upgraded to http / websocket OK (upgraded) OK

With html=off, it becomes impossible to connect to TCP sockets using WS. With ssl=www, it becomes possible to connect to SSL ports using WSS. With ssl=www and html=on, it becomes possible to connect to TCP sockets using WSS. (socket is upgraded to SSL and then websockets)

The problem with WSS connections not being upgraded to http / websocket is that the socket peek data we get before wrapping the socket with SSL doesn't have any distinguishable HTTP header data in it. (and we still cannot peak at SSL sockets - silly python API limitation)

Maybe we could workaround that: read from the ssl socket before constructing the protocol object, inspect it then wrap it and re-inject the data. (would mean wrapping the whole ssl socket object since we can't override socket.recv) It might be easier to modify websockify's recv_frames (re-submit the split-out patches and check for method support at runtime), or just override that method completely.

Fri, 04 Aug 2017 08:40:36 GMT - Antoine Martin: owner, status changed

Helped by the information from Subclassing and built-in methods in Python, r16607 overrides the recv socket method to inject peek support. This allows us to detect HTTP headers in SSL packets, which means that the two error cases from comment:2 are now fixed:

There is a small cost associated with the extra socket.recv call we intercept, but since this is on an IO function I don't think this matters.

@maxmylin: something to be aware of, feel free to just close.

Fri, 04 Aug 2017 16:59:17 GMT - J. Max Mena: status changed; resolution set

Noted and closing.

(btw it's maxmylyn with two ys. Not sure what my dad was thinking but he sure did come up with a creative spelling.)

Sun, 10 Sep 2017 12:27:36 GMT - Antoine Martin:

See also #1636, r27656

Sat, 23 Jan 2021 05:26:06 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1504