Hello community, here is the log from the commit of package python-websockify for openSUSE:Factory checked in at 2019-02-24 17:05:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-websockify (Old) and /work/SRC/openSUSE:Factory/.python-websockify.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-websockify" Sun Feb 24 17:05:13 2019 rev:18 rq:674444 version:0.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-websockify/python-websockify.changes 2018-12-27 00:29:16.779668573 +0100 +++ /work/SRC/openSUSE:Factory/.python-websockify.new.28833/python-websockify.changes 2019-02-24 17:05:17.736626235 +0100 @@ -1,0 +2,16 @@ +Wed Feb 13 09:25:56 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Execute tests +- Switch to github tarball to get tests +- Add patch to fix tests on python 3.6+: + * fix-tests-py3.6.patch + +------------------------------------------------------------------- +Tue Feb 12 14:34:16 UTC 2019 - Cédric Bosdonnat <[email protected]> + +- Add JWT token plugin feature. + Added patches: + u_added_jwt_tokens_capability.patch + PyJWT-token-plugin.patch: fate#325762 + +------------------------------------------------------------------- Old: ---- websockify-0.8.0.tar.gz New: ---- PyJWT-token-plugin.patch fix-tests-py3.6.patch u_added_jwt_tokens_capability.patch v0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-websockify.spec ++++++ --- /var/tmp/diff_new_pack.HSp7hj/_old 2019-02-24 17:05:19.100625586 +0100 +++ /var/tmp/diff_new_pack.HSp7hj/_new 2019-02-24 17:05:19.104625584 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-websockify # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -23,22 +23,42 @@ Summary: WebSocket to TCP proxy/bridge License: LGPL-3.0-only AND MPL-2.0 AND BSD-2-Clause AND BSD-3-Clause Group: Development/Languages/Python -URL: https://github.com/kanaka/websockify -Source: https://files.pythonhosted.org/packages/source/w/websockify/websockify-%{version}.tar.gz +URL: https://github.com/novnc/websockify +Source: https://github.com/novnc/websockify/archive/v%{version}.tar.gz # PATCH-FEATURE-UPSTREAM u_Add-support-for-inetd.patch fate#323880 [email protected] -- https://github.com/novnc/websockify/pull/293 Patch1: u_Add-support-for-inetd.patch # PATCH-FEATURE-UPSTREAM u_Fix-inetd-mode-on-python-2.patch fate#323880 [email protected] -- https://github.com/novnc/websockify/pull/293 Patch2: u_Fix-inetd-mode-on-python-2.patch +# PATCH-FEATURE-ALMOST-UPSTREAM u_added_jwt_tokens_capability.patch fate#325762 [email protected] -- https://github.com/novnc/websockify/pull/372 +Patch3: u_added_jwt_tokens_capability.patch +# PATCH-FIX-OPENSUSE PyJWT-token-plugin.patch fate#325762 [email protected] -- use PyJWT if jwcrypto is missing +Patch4: PyJWT-token-plugin.patch +# PATCH-FROM-UPSTREAM: +Patch5: fix-tests-py3.6.patch +BuildRequires: %{python_module PyJWT} +BuildRequires: %{python_module cryptography} +BuildRequires: %{python_module mox3} +BuildRequires: %{python_module nose} +BuildRequires: %{python_module numpy} BuildRequires: %{python_module setuptools} +Requires: python-numpy +BuildRequires: fdupes BuildRequires: python-rpm-macros -BuildRequires: unzip Requires: python-setuptools Requires: python-websockify-common = %{version} Requires(post): update-alternatives Requires(postun): update-alternatives BuildArch: noarch %if 0%{?suse_version} -Recommends: python-numpy +# SLES 12 and up to 15SP1 doesn't have python-jwcrypto package and will fallback to +# the PyJWT implementation. However opensuse has jwcrypto since 42.3: use this one +# since it also provides support for JWE (encrypted JWT). +%if 0%{?sle_version} +Recommends: python-PyJWT +Recommends: python-cryptography +%else +Recommends: python-jwcrypto +%endif %endif %python_subpackages @@ -69,20 +89,28 @@ %prep %setup -q -n websockify-%{version} -%patch1 -p1 -%patch2 -p1 +%autopatch -p1 + # remove unwanted shebang sed -i '1 { /^#!/ d }' websockify/websocket*.py # drop unneeded executable bit chmod -x include/web-socket-js/web_socket.js +# fix mox3 import +sed -e 's:import stubout:from mox3 import stubout:g' \ + -i tests/test_websocketproxy.py \ + -i tests/test_websocket.py %build %python_build %install %python_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} %python_clone -a %{buildroot}%{_bindir}/websockify +%check +%python_exec setup.py nosetests + %post %python_install_alternative websockify ++++++ PyJWT-token-plugin.patch ++++++ >From cf2bd3930d8506dbb4db172c89a6a628134595aa Mon Sep 17 00:00:00 2001 From: UXabre <[email protected]> Date: Fri, 21 Dec 2018 03:21:29 -0500 Subject: [PATCH] Added JWT tokens capability --- setup.py | 2 +- tests/jwt.secret | 1 + tests/jwt_rsa | 27 ++++++++++++++++++ tests/jwt_rsa.pub | 1 + tests/test_websocketproxy.py | 54 ++++++++++++++++++++++++++++++++++++ websockify/token_plugins.py | 16 +++++++++++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/jwt.secret create mode 100644 tests/jwt_rsa create mode 100644 tests/jwt_rsa.pub Index: websockify-0.8.0/setup.py =================================================================== --- websockify-0.8.0.orig/setup.py +++ websockify-0.8.0/setup.py @@ -34,7 +34,7 @@ setup(name=name, packages=['websockify'], include_package_data=True, - install_requires=['numpy'], + install_requires=['numpy', 'PyJWT', 'cryptography'], zip_safe=False, entry_points={ 'console_scripts': [ Index: websockify-0.8.0/websockify/token_plugins.py =================================================================== --- websockify-0.8.0.orig/websockify/token_plugins.py +++ websockify-0.8.0/websockify/token_plugins.py @@ -125,5 +125,17 @@ class JWTTokenApi(BasePlugin): print >>sys.stderr, "Failed to parse token: %s" % (e) return None except ImportError as e: - print >>sys.stderr, "package jwcrypto not found, are you sure you've installed it correctly?" + try: + import jwt + + secret = open(self.source, 'rb').read() + parsed = jwt.decode(token, secret, algorithms=['RS256', 'RS384', 'RS512', 'HS256', 'HS384', 'HS512', 'ES256', 'ES384', 'ES512', 'PS256', 'PS384', 'PS512']) + + return (parsed['host'], parsed['port']) + except Exception as e: + print >>sys.stderr, "Failed to parse token: %s" % (e) + return None + except ImportError: + print >>sys.stderr, "neither package jwcrypto nor PyJWT found, are you sure you've installed one of them correctly?" + return None return None ++++++ fix-tests-py3.6.patch ++++++ Index: websockify-0.8.0+dfsg1/tests/test_websocket.py =================================================================== --- websockify-0.8.0+dfsg1.orig/tests/test_websocket.py +++ websockify-0.8.0+dfsg1/tests/test_websocket.py @@ -69,6 +69,9 @@ class FakeSocket(object): else: return StringIO(self._data.decode('latin_1')) + def sendall(self, data, flags=None): + return len(data) + class WebSocketRequestHandlerTestCase(unittest.TestCase): def setUp(self): ++++++ u_added_jwt_tokens_capability.patch ++++++ >From 6dc9005930798873ffa714d184312aafd0209503 Mon Sep 17 00:00:00 2001 From: UXabre <[email protected]> Date: Thu, 17 Jan 2019 08:53:01 -0500 Subject: [PATCH] Added JWT/JWS/JWE tokens capability --- test-requirements.txt | 1 + tests/fixtures/private.pem | 27 +++++++++++ tests/fixtures/public.pem | 9 ++++ tests/fixtures/symmetric.key | 1 + tests/test_websocketproxy.py | 90 ++++++++++++++++++++++++++++++++++++ websockify/token_plugins.py | 46 ++++++++++++++++++ 6 files changed, 174 insertions(+) create mode 100644 tests/fixtures/private.pem create mode 100644 tests/fixtures/public.pem create mode 100644 tests/fixtures/symmetric.key diff --git a/websockify/token_plugins.py b/websockify/token_plugins.py index e87dcd0..45e974c 100644 --- a/websockify/token_plugins.py +++ b/websockify/token_plugins.py @@ -87,3 +87,49 @@ class JSONTokenApi(BaseTokenAPI): def process_result(self, resp): resp_json = resp.json() return (resp_json['host'], resp_json['port']) + + +class JWTTokenApi(BasePlugin): + # source is a JWT-token, with hostname and port included + # Both JWS as JWE tokens are accepted. With regards to JWE tokens, the key is re-used for both validation and decryption. + + def lookup(self, token): + try: + from jwcrypto import jwt + import json + + key = jwt.JWK() + + try: + with open(self.source, 'rb') as key_file: + key_data = key_file.read() + except Exception as e: + print >>sys.stderr, "Error loading key file: %s" % (e) + return None + + try: + key.import_from_pem(key_data) + except: + try: + key.import_key(k=key_data,kty='oct') + except: + print >>sys.stderr, 'Failed to correctly parse key data!' + return None + + try: + token = jwt.JWT(key=key, jwt=token) + parsed_header = json.loads(token.header) + + if 'enc' in parsed_header: + # Token is encrypted, so we need to decrypt by passing the claims to a new instance + token = jwt.JWT(key=key, jwt=token.claims) + + parsed = json.loads(token.claims) + + return (parsed['host'], parsed['port']) + except Exception as e: + print >>sys.stderr, "Failed to parse token: %s" % (e) + return None + except ImportError as e: + print >>sys.stderr, "package jwcrypto not found, are you sure you've installed it correctly?" + return None
