From 530280ac6039336f80176635c2032abd41b36bde Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 2 Dec 2021 15:07:00 -0400 Subject: [PATCH] Fix allow function argument decoding error Avoids a utf-8 decoding error when accepting a connection with an allow function by properly wrapping the function in a version that passes pubkey as a `bytes`. --- setup.py | 2 +- src/oxenmq.cpp | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 7e7d60b..72bb0e3 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup # Available at setup time due to pyproject.toml from pybind11.setup_helpers import Pybind11Extension, build_ext -__version__ = "1.0.0" +__version__ = "1.0.1" # Note: # Sort input source files if you glob sources to ensure bit-for-bit diff --git a/src/oxenmq.cpp b/src/oxenmq.cpp index 1bd700d..fe4ef39 100644 --- a/src/oxenmq.cpp +++ b/src/oxenmq.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -436,8 +437,19 @@ Things you want to do before calling this: .def("listen", [](OxenMQ& self, std::string bind, bool curve, - OxenMQ::AllowFunc allow, + py::function pyallow, std::function on_bind) { + OxenMQ::AllowFunc allow; + if (!pyallow.is_none()) + // We need to wrap this to pass the pubkey as bytes (otherwise pybind tries to utf-8 + // encode it). + allow = [pyallow=std::move(pyallow)](std::string_view addr, std::string_view pubkey, bool sn) { + py::gil_scoped_acquire gil; + return py::cast( + pyallow(addr, py::bytes{pubkey.data(), pubkey.size()}, sn) + ); + }; + if (curve) self.listen_curve(bind, std::move(allow), std::move(on_bind)); else @@ -463,9 +475,12 @@ Parameters: - allow_connection function to call to determine whether to allow the connection and, if so, the authentication level it receives. The function is called with the remote's address, the remote's - 32-byte pubkey (only for curve; empty for plaintext), and whether the remote is recognized as a - service node (always False for plaintext; requires sn_lookup being configured in construction). - If omitted (or null) the default returns AuthLevel::none access for all incoming connections. + 32-byte pubkey as bytes (only for curve; empty for plaintext), and whether the remote is + recognized as a service node (always False for plaintext; requires sn_lookup being configured in + construction). + + The function must return a AuthLevel value to accept the connection, or AuthLevel.denied to refuse + it. If omitted (or null) the default returns AuthLevel.none access for all incoming connections. - on_bind a callback to invoke when the port has been successfully opened or failed to open, called with a single boolean argument of True for success, False for failure. For addresses set up