zprocess 2.23.0__tar.gz → 2.24.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {zprocess-2.23.0/zprocess.egg-info → zprocess-2.24.0}/PKG-INFO +1 -1
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/security.py +82 -17
- {zprocess-2.23.0 → zprocess-2.24.0/zprocess.egg-info}/PKG-INFO +1 -1
- {zprocess-2.23.0 → zprocess-2.24.0}/.coveragerc +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/.github/workflows/release.yml +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/.gitignore +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/.travis.yml +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/LICENSE.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/README.md +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/doc/Makefile +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/doc/conf.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/doc/index.rst +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/doc/requirements.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/pyproject.toml +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/requirements.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/run_tests.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/setup.cfg +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/setup.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/GUI_output_redirection.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/output_redirection.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/test_remote.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/test_zlock_server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/test_zlog_server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/tests/tests.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/__version__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/clientserver.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/cryptoproxy.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/examples/example_child.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/examples/example_parent.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/examples/processclass_example.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/examples/processclass_remote_example.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/locking/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/locking/__main__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/makesecret.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/process_class_wrapper.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/process_tree.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/remote/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/remote/__main__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/remote/curses_server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/remote/server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/socks/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/socks/server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/tasks.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/utils.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlock/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlock/__main__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlock/server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlog/__init__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlog/__main__.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess/zlog/server.py +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess.egg-info/SOURCES.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess.egg-info/dependency_links.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess.egg-info/not-zip-safe +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess.egg-info/requires.txt +0 -0
- {zprocess-2.23.0 → zprocess-2.24.0}/zprocess.egg-info/top_level.txt +0 -0
|
@@ -3,6 +3,7 @@ import sys
|
|
|
3
3
|
import base64
|
|
4
4
|
import weakref
|
|
5
5
|
import os
|
|
6
|
+
import threading
|
|
6
7
|
import ipaddress
|
|
7
8
|
import zmq
|
|
8
9
|
import zmq.auth.thread
|
|
@@ -24,6 +25,7 @@ if sys.version_info[0] == 2:
|
|
|
24
25
|
else:
|
|
25
26
|
from time import monotonic
|
|
26
27
|
|
|
28
|
+
PYZMQ_VER_MAJOR = int(zmq.__version__.split('.')[0])
|
|
27
29
|
|
|
28
30
|
_bundle_warning = """zprocess warning: pyzmq is using bundled libzmq, which on Windows
|
|
29
31
|
is not built with the cryptography library libsodium. Encryption/decryption will be
|
|
@@ -165,9 +167,10 @@ class SecureSocket(zmq.Socket):
|
|
|
165
167
|
are a server or not"""
|
|
166
168
|
orig_server = self.curve_server
|
|
167
169
|
if server:
|
|
170
|
+
self.curve_server = True
|
|
171
|
+
self.zap_domain = self.context.zap_domain
|
|
168
172
|
self.curve_publickey = self.context.server_publickey
|
|
169
173
|
self.curve_secretkey = self.context.server_secretkey
|
|
170
|
-
self.curve_server = True
|
|
171
174
|
else:
|
|
172
175
|
self.curve_server = False
|
|
173
176
|
self.curve_publickey = self.context.client_publickey
|
|
@@ -306,6 +309,72 @@ class SecureSocket(zmq.Socket):
|
|
|
306
309
|
return msg
|
|
307
310
|
|
|
308
311
|
|
|
312
|
+
class _ThreadAuthenticator:
|
|
313
|
+
# We roll our own thread authenticator (just implementing what we need) since a)
|
|
314
|
+
# zmq.auth.thread.ThreadAuthenticator uses asyncio, and we do not want to express an
|
|
315
|
+
# opinion on the kerfuffle that is Windows asyncio selectors (see:
|
|
316
|
+
# https://github.com/zeromq/pyzmq/issues/1423) and impose it on the rest of the
|
|
317
|
+
# interpreter, when we're not even using async stuff ourself and b)
|
|
318
|
+
# zmq.auth.thread.ThreadAuthenticator spawns a non-daemon thread which is difficult
|
|
319
|
+
# to ensure gets shut down at interpreter shutdown, and otherwise holds the
|
|
320
|
+
# interpreter open.
|
|
321
|
+
def __init__(self, ctx, zap_domain, allowed_clients):
|
|
322
|
+
if PYZMQ_VER_MAJOR >= 25:
|
|
323
|
+
self.zap_socket = ctx.socket(zmq.REP, socket_class=zmq.Socket)
|
|
324
|
+
else:
|
|
325
|
+
self.zap_socket = ctx.socket(zmq.REP)
|
|
326
|
+
self.zap_socket.linger = 1
|
|
327
|
+
self.zap_socket.bind("inproc://zeromq.zap.01")
|
|
328
|
+
|
|
329
|
+
# Note: we hold a reference to the zap socket, since if the thread crashes, we
|
|
330
|
+
# don't want the socket to be cleaned up and closed - that would have zmq
|
|
331
|
+
# (stupidly and dangerously) fall back to its default authentication method,
|
|
332
|
+
# which is to allow all.
|
|
333
|
+
self.thread = threading.Thread(
|
|
334
|
+
target=self.run,
|
|
335
|
+
args=(self.zap_socket, zap_domain, allowed_clients),
|
|
336
|
+
daemon=True,
|
|
337
|
+
)
|
|
338
|
+
self.started = threading.Event()
|
|
339
|
+
self.thread.start()
|
|
340
|
+
|
|
341
|
+
def run(self, zap_socket, zap_domain, allowed_clients):
|
|
342
|
+
VERSION = b'1.0'
|
|
343
|
+
MECHANISM = b'CURVE'
|
|
344
|
+
while True:
|
|
345
|
+
try:
|
|
346
|
+
msg = zap_socket.recv_multipart()
|
|
347
|
+
except zmq.error.ContextTerminated:
|
|
348
|
+
zap_socket.close()
|
|
349
|
+
return
|
|
350
|
+
version, request_id, domain, address, identity, mechanism = msg[:6]
|
|
351
|
+
credentials = msg[6:]
|
|
352
|
+
if version != VERSION:
|
|
353
|
+
status_code = b"400"
|
|
354
|
+
status_text = b"Invalid version"
|
|
355
|
+
user_id = b""
|
|
356
|
+
elif mechanism != MECHANISM:
|
|
357
|
+
status_code = b"400"
|
|
358
|
+
status_text = b"Security mechanism not supported"
|
|
359
|
+
user_id = b""
|
|
360
|
+
elif domain != zap_domain:
|
|
361
|
+
status_code = b"400"
|
|
362
|
+
status_text = b"Unknown domain"
|
|
363
|
+
user_id = b""
|
|
364
|
+
else:
|
|
365
|
+
key = zmq.utils.z85.encode(credentials[0])
|
|
366
|
+
if key in allowed_clients:
|
|
367
|
+
status_code = b"200"
|
|
368
|
+
status_text = b"OK"
|
|
369
|
+
user_id = key
|
|
370
|
+
else:
|
|
371
|
+
status_code = b"400"
|
|
372
|
+
status_text = b"Unknown key"
|
|
373
|
+
user_id = b""
|
|
374
|
+
response = [VERSION, request_id, status_code, status_text, user_id, b""]
|
|
375
|
+
zap_socket.send_multipart(response)
|
|
376
|
+
|
|
377
|
+
|
|
309
378
|
class SecureContext(zmq.Context):
|
|
310
379
|
"""A ZeroMQ Context with SecureContext.socket() returning a
|
|
311
380
|
SecureSocket(), which can authenticate and communicate securely with all
|
|
@@ -315,7 +384,10 @@ class SecureContext(zmq.Context):
|
|
|
315
384
|
|
|
316
385
|
_socket_class = SecureSocket
|
|
317
386
|
_instances = weakref.WeakValueDictionary()
|
|
387
|
+
zap_domain = b"zprocess"
|
|
388
|
+
|
|
318
389
|
# Dummy class attrs to distinguish from zmq options:
|
|
390
|
+
auth = None
|
|
319
391
|
secure = False
|
|
320
392
|
client_publickey = None
|
|
321
393
|
client_secretkey = None
|
|
@@ -331,22 +403,15 @@ class SecureContext(zmq.Context):
|
|
|
331
403
|
self.client_publickey = zmq.curve_public(self.client_secretkey)
|
|
332
404
|
self.server_publickey = zmq.curve_public(self.server_secretkey)
|
|
333
405
|
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
#
|
|
337
|
-
#
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if auth.thread.authenticator is auth:
|
|
345
|
-
auth.thread.authenticator = weakref.proxy(auth)
|
|
346
|
-
|
|
347
|
-
# Allow only clients who have the client public key:
|
|
348
|
-
auth.allow_any = False
|
|
349
|
-
auth.certs['*'] = {self.client_publickey: True}
|
|
406
|
+
# Note: it is crucial we hold a reference to the authenticator, so that in
|
|
407
|
+
# the case the zap authentication thread crashes, the zap socket does not
|
|
408
|
+
# get cleaned up and closed - zmq will interpret that situation as us not
|
|
409
|
+
# requiring any authentication.
|
|
410
|
+
self.auth = _ThreadAuthenticator(
|
|
411
|
+
self,
|
|
412
|
+
zap_domain=self.zap_domain,
|
|
413
|
+
allowed_clients=[self.client_publickey],
|
|
414
|
+
)
|
|
350
415
|
self.secure = True
|
|
351
416
|
|
|
352
417
|
@classmethod
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|