From fa6cad701c7993aa6e5746824931efbfca84ca24 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista <nathaniel@google.com> Date: Fri, 5 Feb 2016 21:26:54 +0000 Subject: [PATCH] grpc_set_ssl_roots_override_callback for Python --- setup.py | 6 +-- src/python/grpcio/.gitignore | 2 +- src/python/grpcio/grpc/_adapter/_low.py | 5 -- .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 11 +++- .../grpc/_cython/_cygrpc/security.pxd.pxi | 32 +++++++++++ .../grpc/_cython/_cygrpc/security.pyx.pxi | 44 +++++++++++++++ src/python/grpcio/grpc/_cython/cygrpc.pxd | 1 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 3 ++ .../tests/unit/beta/_implementations_test.py | 54 +++++++++++++++++++ 9 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi create mode 100644 src/python/grpcio/tests/unit/beta/_implementations_test.py diff --git a/setup.py b/setup.py index 720e4f75f6..9e1559e0d1 100644 --- a/setup.py +++ b/setup.py @@ -165,7 +165,7 @@ COMMAND_CLASS = { } # Ensure that package data is copied over before any commands have been run: -credentials_dir = os.path.join(PYTHON_STEM, 'grpc/_adapter/credentials') +credentials_dir = os.path.join(PYTHON_STEM, 'grpc/_cython/_credentials') try: os.mkdir(credentials_dir) except OSError: @@ -199,10 +199,8 @@ TEST_LOADER = 'tests:Loader' TEST_RUNNER = 'tests:Runner' PACKAGE_DATA = { - 'grpc._adapter': [ - 'credentials/roots.pem' - ], 'grpc._cython': [ + '_credentials/roots.pem', '_windows/grpc_c.32.python', '_windows/grpc_c.64.python', ], diff --git a/src/python/grpcio/.gitignore b/src/python/grpcio/.gitignore index 1d804e1ffc..6e5e65096c 100644 --- a/src/python/grpcio/.gitignore +++ b/src/python/grpcio/.gitignore @@ -14,4 +14,4 @@ nosetests.xml doc/ _grpcio_metadata.py htmlcov/ -grpc/_adapter/credentials +grpc/_cython/_credentials diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py index a850c57741..62fd52ab40 100644 --- a/src/python/grpcio/grpc/_adapter/_low.py +++ b/src/python/grpcio/grpc/_adapter/_low.py @@ -27,7 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import pkg_resources import threading from grpc import _grpcio_metadata @@ -35,7 +34,6 @@ from grpc._cython import cygrpc from grpc._adapter import _implementations from grpc._adapter import _types -_ROOT_CERTIFICATES_RESOURCE_PATH = 'credentials/roots.pem' _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__) ChannelCredentials = cygrpc.ChannelCredentials @@ -56,9 +54,6 @@ def channel_credentials_ssl( pair = None if private_key is not None or certificate_chain is not None: pair = cygrpc.SslPemKeyCertPair(private_key, certificate_chain) - if root_certificates is None: - root_certificates = pkg_resources.resource_string( - __name__, _ROOT_CERTIFICATES_RESOURCE_PATH) return cygrpc.channel_credentials_ssl(root_certificates, pair) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 9d6e017026..bbeed9ad40 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -100,6 +100,11 @@ cdef extern from "grpc/_cython/loader.h": GRPC_STATUS_DATA_LOSS GRPC_STATUS__DO_NOT_USE + ctypedef enum grpc_ssl_roots_override_result: + GRPC_SSL_ROOTS_OVERRIDE_OK + GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY + GRPC_SSL_ROOTS_OVERRIDE_FAILED + struct grpc_byte_buffer_reader: # We don't care about the internals pass @@ -338,6 +343,10 @@ cdef extern from "grpc/_cython/loader.h": # We don't care about the internals (and in fact don't know them) pass + ctypedef void (*grpc_ssl_roots_override_callback)(char **pem_root_certs) + + void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) + grpc_channel_credentials *grpc_google_default_credentials_create() grpc_channel_credentials *grpc_ssl_credentials_create( const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi new file mode 100644 index 0000000000..3a952ca309 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/security.pxd.pxi @@ -0,0 +1,32 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +cdef grpc_ssl_roots_override_result ssl_roots_override_callback( + char **pem_root_certs) with gil diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi new file mode 100644 index 0000000000..23cee7bd6e --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi @@ -0,0 +1,44 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from libc.string cimport memcpy + +import pkg_resources + + +cdef grpc_ssl_roots_override_result ssl_roots_override_callback( + char **pem_root_certs) with gil: + temporary_pem_root_certs = pkg_resources.resource_string( + 'grpc._cython', '_credentials/roots.pem') + pem_root_certs[0] = <char *>gpr_malloc(len(temporary_pem_root_certs) + 1) + memcpy( + pem_root_certs[0], <char *>temporary_pem_root_certs, + len(temporary_pem_root_certs)) + pem_root_certs[0][len(temporary_pem_root_certs)] = '\0' + return GRPC_SSL_ROOTS_OVERRIDE_OK diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index f22346c4f3..61b0fa788f 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -34,4 +34,5 @@ include "grpc/_cython/_cygrpc/channel.pxd.pxi" include "grpc/_cython/_cygrpc/credentials.pxd.pxi" include "grpc/_cython/_cygrpc/completion_queue.pxd.pxi" include "grpc/_cython/_cygrpc/records.pxd.pxi" +include "grpc/_cython/_cygrpc/security.pxd.pxi" include "grpc/_cython/_cygrpc/server.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 579bac7b8a..f4b96ccd31 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -40,6 +40,7 @@ include "grpc/_cython/_cygrpc/channel.pyx.pxi" include "grpc/_cython/_cygrpc/credentials.pyx.pxi" include "grpc/_cython/_cygrpc/completion_queue.pyx.pxi" include "grpc/_cython/_cygrpc/records.pyx.pxi" +include "grpc/_cython/_cygrpc/security.pyx.pxi" include "grpc/_cython/_cygrpc/server.pyx.pxi" # @@ -58,6 +59,8 @@ cdef class _ModuleState: raise ImportError('failed to load core gRPC library') grpc_init() self.is_loaded = True + grpc_set_ssl_roots_override_callback( + <grpc_ssl_roots_override_callback>ssl_roots_override_callback) def __dealloc__(self): if self.is_loaded: diff --git a/src/python/grpcio/tests/unit/beta/_implementations_test.py b/src/python/grpcio/tests/unit/beta/_implementations_test.py new file mode 100644 index 0000000000..6b32305af7 --- /dev/null +++ b/src/python/grpcio/tests/unit/beta/_implementations_test.py @@ -0,0 +1,54 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests the implementations module of the gRPC Python Beta API.""" + +import unittest + +from grpc.beta import implementations +from tests.unit import resources + + +class ChannelCredentialsTest(unittest.TestCase): + + def test_runtime_provided_root_certificates(self): + channel_credentials = implementations.ssl_channel_credentials( + None, None, None) + self.assertIsInstance( + channel_credentials, implementations.ChannelCredentials) + + def test_application_provided_root_certificates(self): + channel_credentials = implementations.ssl_channel_credentials( + resources.test_root_certificates(), None, None) + self.assertIsInstance( + channel_credentials, implementations.ChannelCredentials) + + +if __name__ == '__main__': + unittest.main(verbosity=2) -- GitLab