utils.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # coding: utf-8
  2. """miscellaneous zmq_utils wrapping"""
  3. # Copyright (C) PyZMQ Developers
  4. # Distributed under the terms of the Modified BSD License.
  5. from errno import EINTR
  6. from ._cffi import ffi, C
  7. from zmq.error import ZMQError, InterruptedSystemCall, _check_rc, _check_version
  8. from zmq.utils.strtypes import unicode
  9. def has(capability):
  10. """Check for zmq capability by name (e.g. 'ipc', 'curve')
  11. .. versionadded:: libzmq-4.1
  12. .. versionadded:: 14.1
  13. """
  14. _check_version((4,1), 'zmq.has')
  15. if isinstance(capability, unicode):
  16. capability = capability.encode('utf8')
  17. return bool(C.zmq_has(capability))
  18. def curve_keypair():
  19. """generate a Z85 keypair for use with zmq.CURVE security
  20. Requires libzmq (≥ 4.0) to have been built with CURVE support.
  21. Returns
  22. -------
  23. (public, secret) : two bytestrings
  24. The public and private keypair as 40 byte z85-encoded bytestrings.
  25. """
  26. _check_version((3,2), "curve_keypair")
  27. public = ffi.new('char[64]')
  28. private = ffi.new('char[64]')
  29. rc = C.zmq_curve_keypair(public, private)
  30. _check_rc(rc)
  31. return ffi.buffer(public)[:40], ffi.buffer(private)[:40]
  32. def curve_public(private):
  33. """ Compute the public key corresponding to a private key for use
  34. with zmq.CURVE security
  35. Requires libzmq (≥ 4.2) to have been built with CURVE support.
  36. Parameters
  37. ----------
  38. private
  39. The private key as a 40 byte z85-encoded bytestring
  40. Returns
  41. -------
  42. bytestring
  43. The public key as a 40 byte z85-encoded bytestring.
  44. """
  45. if isinstance(private, unicode):
  46. private = private.encode('utf8')
  47. _check_version((4,2), "curve_public")
  48. public = ffi.new('char[64]')
  49. rc = C.zmq_curve_public(public, private)
  50. _check_rc(rc)
  51. return ffi.buffer(public)[:40]
  52. def _retry_sys_call(f, *args, **kwargs):
  53. """make a call, retrying if interrupted with EINTR"""
  54. while True:
  55. rc = f(*args)
  56. try:
  57. _check_rc(rc)
  58. except InterruptedSystemCall:
  59. continue
  60. else:
  61. break
  62. __all__ = ['has', 'curve_keypair', 'curve_public']