Commit Graph

52 Commits

Author SHA1 Message Date
Pierre Ossman 3d20cabf40 Fix handling of closed proxy socket
Regression caused by a29946e9. We were no longer detecting a cleanly
closed proxy socket. This is not a WebSocket, but an ordinary one,
so we should be checking for "" rather that None.
2018-01-25 15:46:41 +01:00
Pierre Ossman 6b1d42e643 Merge branch 'empty-message' of https://github.com/andersk/websockify 2017-11-13 10:44:57 +01:00
Anders Kaseorg a29946e978 Do not confuse an empty message with a closed connection
Fixes #312.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2017-11-10 06:26:48 -05:00
Anders Kaseorg 3c1655322d Do not use base except: clauses
https://docs.python.org/2/howto/doanddont.html#except

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2017-11-10 05:48:20 -05:00
Hermann Höhne 914609fb5f Added SSL-certificate-based client authentication.
* Incorporates #190 without breaking compatibility towards old Python versions.
* A new plugin allows authenticating clients by the "common name" defined in their certificate.
* Added manual for certificate-based client authentication, including hints to which Python versions allow client certificate authentication.
* Adjusted test to work with new ssl.create_default_context.
2017-10-26 15:17:11 +02:00
Michal Srb 867cb21ba0 Add support for inetd.
With the --inetd parameter, websockify doesn't require the source_addr and
source_port paramters and it expects that stdin is already opened and listening
socket.

This way websockify can be used with (x)inetd or as a systemd socket-activated
service.
2017-08-14 16:59:54 +02:00
Pierre Ossman 94783ea0cd Remove --auto-pong argument
The underlying code has been removed, so remove the argument
as well.
2017-02-07 15:38:07 +01:00
Pierre Ossman e47591f4aa Split out basic WebSocket server template 2017-02-01 08:33:07 +01:00
Pierre Ossman 8a69762249 Separate out raw WebSocket protocol handling 2017-02-01 08:22:27 +01:00
Pierre Ossman 4099949984 Remove Base64 support
This is an older protocol used before browsers got native
support for Websockets.
2017-02-01 08:09:53 +01:00
Solly Ross 72ce5c1ae8 Merge pull request #228 from jrziviani/master
Enable unix socket to work with token plugin
2016-06-30 16:54:35 -04:00
samhed f23780eb42 Disable Nagle for proxied connections
Most of the proxy stuff will be latency sensitive traffic so we
disable Nagle because it introduces delays.
2016-06-02 14:45:51 +02:00
Jose Ricardo Ziviani 7f8baf54e1 Enable unix socket to work with token plugin
This commit adds support to unix sockets in the token plugin, thus it is
possible to have a token files like:

  token: unix_socket:/path/to/socket_file

A single websockify instance will be able to handle multiple sockets.

Signed-off-by: Jose Ricardo Ziviani <jose@ziviani.net>
2016-02-16 13:51:13 -02:00
Miguel Xavier Penha Neto d947fb6e30 Add support for log files
Override log_message in websocket.py so messages from send_error are properly saved into the log files

Closes #204
2015-12-01 15:25:17 -02:00
Solly Ross 1e2b5c2256 Rework Auth Plugins to Support HTTP Auth
This commit reworks auth plugins slightly to enable
support for HTTP authentication.  By raising an
AuthenticationError, auth plugins can now return
HTTP responses to the upgrade request (such as 401).

Related to kanaka/noVNC#522
2015-08-25 17:52:20 -04:00
Bennett Kanuka 1f960d9f3c Catch interrupted system call
Closes #166
2015-05-13 16:15:25 -04:00
Solly Ross d5216c3166 Process plugin parameters in main
Previously, we just passed the values of '--*-plugin' and
'--*-source' directly to `LibProxyServer` and `WebSocketProxy`,
which handled turning that into an instance of the plugin class.
Now, that's done in main, and the classes receive an instance
directly.
2015-05-13 16:03:56 -04:00
Solly Ross df10501615 Introduce Auth Plugins
Auth plugins provide a generic interface for authenticating requests.

The plugin name is specified using the '--auth-plugin' option, and
may either be the name of a class from `websockify.auth_plugins`,
or a fully qualified python path to the auth plugin class (see below).

An optional plugin parameter can be specified using the '--auth-source'
option (a value of `None` will be used if no '--auth-source' option is
specified).

Auth plugins should inherit from `websockify.auth_plugins.BasePlugin`,
and should implement the `authenticate(headers, target_host, target_port)`
method.  The value of the '--auth-source' option is available as
`self.source`.

One plugin is currently included: `ExpectOrigin`.  The `ExpectOrigin`
plugin checks that the 'Origin' header is an expected value.  The list
of acceptable origins is passed using the plugin source, as a
space-separated list.
2015-05-13 16:03:37 -04:00
Aric Stewart 52adf957b3 Add ping heartbeat option
With this option we will ping the client with a heartbeat.
Helpful for connection through firewalls that may disable inactive
connections.
2015-04-14 16:09:26 -05:00
Aric Stewart 731fd20796 Add option to turn on auto-pong
This allows the websockify server to respond to heart beat ping
messages sent by clients
2015-04-13 14:57:24 -05:00
Solly Ross 52c2e62535 Fix bug in token_plugin/target_cfg support
Previously, if no `target_cfg` flag was used, the `target_cfg` option
would not get removed from the opts dict, causing an error when it got
passed through to `WebSocketProxy`.  Now we always remove it.

Fixes #168.
2015-04-09 11:43:20 -04:00
Solly Ross 69a8b928aa Introduce Token Plugins
Token plugins provide a generic interface for transforming a token
into a `(host, port)` tuple.

The plugin name is specified using the '--token-plugin' option,
and may either be the name of a class from `websockify.token_plugins`,
or a fully qualified python path to the token plugin class (see below).

An optional plugin parameter can be specified using the '--token-source'
option (a value of `None` will be used if no '--token-source' option is
passed).

Token plugins should inherit from `websockify.token_plugins.BasePlugin`,
and should implement the `lookup(token)` method.  The value of the
'--token-source' option is available as `self.source`.

Several plugins are included by default.  The `ReadOnlyTokenFile`
and `TokenFile` plugins implement functionality from '--target-config'
(with the former only reading the file(s) once, and the latter reading
them every time).  The 'BaseTokenAPI' plugin fetches the value from
an API, returning the result of `process_result(response_object)`.
By default, `process_result` simply returns the text of the response,
but may be overriden.  The `JSONTokenAPI` does just this, returning
the 'host' and 'port' values from the response JSON object.

The old '--target-config' option is now deprecated, and maps to the
`TokenFile` plugin under the hood.

Also-Authored-By: James Portman (@james-portman)

Closes #157
2015-03-26 16:21:25 -04:00
Solly Ross acd276e1a2 Don't use implicit relative imports
Implicit relative imports don't work in Python 3.  This converts
implicit relative imports into absolute imports
(e.g. `import websocket` becomes `from websockify import websocket`).

Fixes #154
2015-02-03 16:52:29 -05:00
Radek Podgorny 303a71310c python3 compatibility fixes 2014-10-02 11:42:17 +02:00
samhed 6c1a2e9032 Avoid using the %-operator, URL-escaped strings can contain extra %'s which can cause bugs. 2014-03-18 15:21:13 +01:00
Peter Åstrand (astrand) 6de6933819 Minor whitespace and layout tweaks, to reduce diff against
upstream/master.
2013-12-17 14:20:14 +01:00
Peter Åstrand (astrand) 131f9ea645 Merge commit '477dce6cf86d61b20a394f3cbf3170e60d199658'
* commit '477dce6cf86d61b20a394f3cbf3170e60d199658':
  websocket: use python logging module
  websocket: fix exception statement introduced by comment 903e3f06ee557

Adapted to new standard SocketServer RequestHandler design. For
example, this means that self.i_am_client is not needed.
2013-11-28 09:05:24 +01:00
Peter Åstrand (astrand) 611da86353 Merge commit 'a7fa97f0e14926cc4433483fcb7581e0b3782140'
* commit 'a7fa97f0e14926cc4433483fcb7581e0b3782140':
  WebSocketProxy: support non path target_cfg
2013-11-27 13:41:00 +01:00
Peter Åstrand (astrand) 08d37e0deb Merge commit 'f30ad05c70ab2a43c9078e2f79da40f1dc0c60ec'
* commit 'f30ad05c70ab2a43c9078e2f79da40f1dc0c60ec':
  Fix #97: rebind.so not found when installed
2013-11-27 13:33:30 +01:00
Alon Bar-Lev 8a0a47223d websocket: use python logging module
WebSocketServer is a library module, as such, it cannot assume it can
write output to process stdout.

Python logging module is designed in order to allow subscribers to
handle the output out of modules. It is simple and generic mechanism to
separate between data producer and data handling.

Python logging API also has the nature of log level, so the verbose
parameter can probably be obsoleted in favor of logging level. And of
course the logging API has built in support for exception tracebacks, no
need for manual format.

Per upstream request a wrapper is created around python logging to
enable shorter statements and optional replacement.

Add --traffic parameter for traffic specific debug, this is required as
it uses direct unformatted stdout output.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-15 19:18:17 +03:00
Alon Bar-Lev 37e40a78f2 WebSocketProxy: support non path target_cfg
The WebSocketProxy class is usable for creating derived applications
with different logic, especially for the target validation.

Current code assumes that target is a path while in other implementation
it can be object that is loaded at initialization.

This change moves the conversion to absolute path into main function, so
that the WebSocketProxy class will not make that assumption.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2013-10-14 20:31:24 +03:00
Joel Martin f30ad05c70 Fix #97: rebind.so not found when installed
This should fix the upstream Debian bug:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=719889
2013-09-27 07:42:57 -05:00
Peter Åstrand (astrand) ed109d7ec8 Fix Python3 compatibility when using --libserver. 2013-03-20 15:09:58 +01:00
Peter Åstrand (astrand) e964c1edff Let our ProxyRequestHandler be default. This allows you to inherit
from WebSocketProxy without having to specify handler class.
2013-03-20 11:34:46 +01:00
Peter Åstrand (astrand) f5e42ff6f4 Move WebSocketProxy class so that it is defined after the
requesthandler. Removed comments about above/below which does not make
sense any longer. No functional changes.
2013-03-20 11:30:38 +01:00
Peter Åstrand (astrand) f594d70daf Removed unused import of SimpleHTTPRequestHandler. 2013-03-20 11:00:34 +01:00
Peter Åstrand (astrand) b05b773bd7 Corrected last commit. 2013-03-18 13:25:53 +01:00
Peter Åstrand (astrand) debc926612 Renamed CustomProxyServer to WebSocketProxy; this was the earlier name.
Also, call the server instance "server", not "httpd", even when using
LibProxyServer.
2013-03-18 13:22:48 +01:00
Peter Åstrand (astrand) 7b3dd8a6f5 Try to solve https://github.com/kanaka/websockify/issues/71 by
refactoring. Basically, we are dividing WebSocketServer into two
classes: One request handler following the SocketServer Requesthandler
API, and one optional server engine. The standard Python SocketServer
engine can also be used.

websocketproxy.py has been updated to match the API change. I've also
added a new option --libserver in order to use the Python built in
server instead.

I've done a lot of testing with the new code. This includes: verbose,
daemon, run-once, timeout, idle-timeout, ssl, web, libserver. I've
tested both Python 2 and 3. I've also tested websocket.py in another
external service.

Code details follows:

* The new request handler class is called WebSocketRequestHandler,
  inheriting SimpleHTTPRequestHandler.

* The service engine is called WebSocketServer, just like before.

* do_websocket_handshake: Using send_header() etc, instead of manually
  sending HTTP response.

* A new method called handle_websocket() upgrades the connection to
  WebSocket, if requested. Otherwise, it returns False. A typical
  application use is:

    def do_GET(self):
        if not self.handle_websocket():
	   # handle normal requests

* new_client has been renamed to new_websocket_client, in order to
  have a better name in the SocketServer/HTTPServer request handler
  hierarchy.

* Note that in the request handler, configuration variables must be
  provided by the "server" object, ie self.server.target_host.
2013-03-14 16:07:40 +01:00
Peter Åstrand (astrand) 208f83b9a2 Prepare for fixing https://github.com/kanaka/websockify/issues/71:
* Move traffic_legend.

* Since websocket.WebSocketServer.socket is static, don't call it with
  self.socket.
2013-03-14 16:00:11 +01:00
Peter Åstrand (astrand) b9e1295f7a Prepare for solving https://github.com/kanaka/websockify/issues/71:
Rename self.client to self.request, since this is what standard
SocketServer request handlers are using.
2013-03-14 15:23:44 +01:00
Joel Martin 47fb367486 websocketproxy.py: fix for python2.4
Thanks to https://github.com/WhiteRavenTechnology for catching this.
2012-10-30 08:34:47 -05:00
Joel Martin 5e16b38524 websocketproxy.py: put client socket handling first.
Should at least mostly address this issue:
https://github.com/kanaka/websockify/issues/63

The problem is that the target in the test case often immediately
closed the target after sending the data. In this case the last data
received from the target is never sent to the client because the
client is not in the list of sockets being selected against (because
it is only added if their is pending data). By moving the client
conditionals first, we give the client socket a chance to be sent data
before the target is detected as close and we terminate the loop.
2012-10-29 18:12:54 -05:00
Joel Martin d1458d0063 websocketproxy.py: better missing token exception. 2012-10-29 17:05:23 -05:00
Joel Martin 471b504799 Merge branch 'master' of github.com:kanaka/websockify 2012-09-21 07:32:54 -05:00
Joel Martin b713acbeff Merge pull request #59 from dosht/master
--unix-target option breaks argument sanity check
2012-09-21 05:31:47 -07:00
Joel Martin ff736e9ad3 Fix issue #60: not all arguments converted
https://github.com/kanaka/websockify/issues/60

String formatting issue with wrapped cmds.
2012-09-21 07:28:08 -05:00
Joel Martin 384c2772fb Merge pull request #61 from vishvananda/fix-popen
Reset SIGPIPE handler when calling Popen

References:

http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html

http://bugs.python.org/issue1615376

http://bugs.python.org/issue1652
2012-09-21 05:24:50 -07:00
Joel Martin e6d8d8f242 Gracefully handle errors when popping kwargs.
https://github.com/kanaka/websockify/pull/53
2012-09-21 07:10:34 -05:00
Vishvananda Ishaya ca8efbf657 Reset SIGPIPE handler when calling Popen
Python ignores SIGPIPE on startup, because it prefers to check every
write and raise an IOError exception rather than taking the signal. Most
Unix subprocesses don't expect to work this way. This patch (adapted
from Colin Watson's post at http://tinyurl.com/2a7mzh5) sets SIGPIPE
back to the default action.
2012-09-20 07:46:04 -07:00