diff options
author | Giang Nguyen <cauthu@dropbox.com> | 2017-10-30 10:19:17 -0500 |
---|---|---|
committer | Giang Nguyen <cauthu@dropbox.com> | 2017-11-20 23:09:56 +0000 |
commit | bcf083fa9099e5c919f1bdbc7694705665468d3c (patch) | |
tree | 19814695e47cec1f2aca73b589af7674e4e77603 /src/python/grpcio/grpc/__init__.py | |
parent | 555b84506e22ecd5bc5cea0f2d3dcae3a1d8c108 (diff) |
Add Python support for server SSL cert reloading
Previously, a secure server is configured with SSL credentials during
initialization, and those credentials will be used for the lifetime of
the server. If the user wants the server to use new credentials, the
user has to restart the server, resulting in server downtime. This
change enables the user to optionally configure the server with a
"certificiate config fetcher," such that on every new client
connection, the server will call the config fetcher before performing
the handshake, allowing the user application to optionally specify new
certificate configuration for the server to use (the fetcher can
return a "no change" and the server continues to use its current
certificate configuration).
Diffstat (limited to 'src/python/grpcio/grpc/__init__.py')
-rw-r--r-- | src/python/grpcio/grpc/__init__.py | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index c9f9ac27d9..70558a699a 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -424,6 +424,19 @@ class ServerCredentials(object): self._credentials = credentials +class ServerCertificateConfig(object): + """A certificate config for use with an SSL-enabled Server, e.g., can + be returned in the certificate config fetching callback. + + This class has no supported interface -- it exists to define the + type of its instances and its instances exist to be passed to + other functions. + """ + + def __init__(self, cert_config): + self._cert_config = cert_config + + ######################## Multi-Callable Interfaces ########################### @@ -1252,6 +1265,60 @@ def ssl_server_credentials(private_key_certificate_chain_pairs, ], require_client_auth)) +def ssl_server_certificate_config(private_key_certificate_chain_pairs, + root_certificates=None): + """Creates a ServerCertificateConfig for use with an SSL-enabled Server. + + Args: + private_key_certificate_chain_pairs: A collection of pairs of + the form [PEM-encoded private key, PEM-encoded certificate + chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + + Returns: + A ServerCertificateConfig that can be returned in the certificate config + fetching callback. + """ + if len(private_key_certificate_chain_pairs) == 0: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + else: + return ServerCertificateConfig( + _cygrpc.server_certificate_config_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ])) + + +def ssl_server_credentials_dynamic_cert_config(initial_cert_config, + cert_config_fetcher, + require_client_auth=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + initial_cert_config (ServerCertificateConfig): the certificate + config with which the server will be initialized. + cert_config_fetcher (callable): a callable that takes no + arguments and should return a ServerCertificateConfig to + replace the server's current cert, or None for no change + (i.e., the server will continue its current certificate + config). The library will call this callback on *every* new + client connection before starting the TLS handshake with the + client, thus allowing the user application to optionally + return a new ServerCertificateConfig that the server will then + use for the handshake. + require_client_auth: A boolean indicating whether or not to + require clients to be authenticated. + + Returns: + A ServerCredentials. + """ + return ServerCredentials( + _cygrpc.server_credentials_ssl_dynamic_cert_config( + initial_cert_config, cert_config_fetcher, require_client_auth)) + + def channel_ready_future(channel): """Creates a Future that tracks when a Channel is ready. @@ -1334,18 +1401,20 @@ __all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future', 'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext', 'Call', 'ChannelCredentials', 'CallCredentials', 'AuthMetadataContext', 'AuthMetadataPluginCallback', - 'AuthMetadataPlugin', 'ServerCredentials', 'UnaryUnaryMultiCallable', - 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable', - 'StreamStreamMultiCallable', 'Channel', 'ServicerContext', - 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler', - 'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler', - 'unary_stream_rpc_method_handler', 'stream_unary_rpc_method_handler', + 'AuthMetadataPlugin', 'ServerCertificateConfig', 'ServerCredentials', + 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', + 'StreamUnaryMultiCallable', 'StreamStreamMultiCallable', 'Channel', + 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails', + 'GenericRpcHandler', 'ServiceRpcHandler', 'Server', + 'unary_unary_rpc_method_handler', 'unary_stream_rpc_method_handler', + 'stream_unary_rpc_method_handler', 'stream_stream_rpc_method_handler', 'method_handlers_generic_handler', 'ssl_channel_credentials', 'metadata_call_credentials', 'access_token_call_credentials', 'composite_call_credentials', 'composite_channel_credentials', - 'ssl_server_credentials', 'channel_ready_future', 'insecure_channel', - 'secure_channel', 'server',) + 'ssl_server_credentials', 'ssl_server_certificate_config', + 'ssl_server_credentials_dynamic_cert_config', 'channel_ready_future', + 'insecure_channel', 'secure_channel', 'server',) ############################### Extension Shims ################################ |