[Notes] [Git][BuildStream/buildstream][dp0/513/cas-cache-client-certs] Support dynamic client certificates for CAS cache



Title: GitLab

Daniel Playle pushed to branch dp0/513/cas-cache-client-certs at BuildStream / buildstream

Commits:

1 changed file:

Changes:

  • buildstream/_artifactcache/casserver.py
    ... ... @@ -72,6 +72,56 @@ def create_server(repo, *, enable_push):
    72 72
         return server
    
    73 73
     
    
    74 74
     
    
    75
    +class _SSLServerCredentialsCallable:
    
    76
    +
    
    77
    +    def __init__(self, server_key, server_cert, client_certs):
    
    78
    +        self.server_key = server_key
    
    79
    +        self.server_cert = server_cert
    
    80
    +        self.client_certs = client_certs
    
    81
    +        self.client_certs_stat = None
    
    82
    +        self.load_server_key()
    
    83
    +        self.load_server_cert()
    
    84
    +        self.load_client_certs()
    
    85
    +
    
    86
    +    def load_server_key(self):
    
    87
    +        with open(self.server_key, 'rb') as f:
    
    88
    +            self.server_key_bytes = f.read()
    
    89
    +
    
    90
    +    def load_server_cert(self):
    
    91
    +        with open(self.server_cert, 'rb') as f:
    
    92
    +            self.server_cert_bytes = f.read()
    
    93
    +
    
    94
    +    def load_client_certs(self):
    
    95
    +        if self.client_certs:
    
    96
    +            with open(self.client_certs, 'rb') as f:
    
    97
    +                stat = os.fstat(f.fileno())
    
    98
    +                if stat != self.client_certs_stat:
    
    99
    +                    # The stat is different. We need to reload the client certs
    
    100
    +                    self.client_certs_bytes = f.read()
    
    101
    +                    self.client_certs_stat = stat
    
    102
    +                    return True
    
    103
    +                return False
    
    104
    +        else:
    
    105
    +            self.client_certs_stat = None
    
    106
    +            self.client_certs_bytes = None
    
    107
    +            # Nothing has been loaded
    
    108
    +            return False
    
    109
    +
    
    110
    +    def get_ssl_server_credentials(self):
    
    111
    +        return grpc.ssl_server_certificate_configuration(
    
    112
    +            private_key_certificate_chain_pairs=[(self.server_key_bytes, self.server_cert_bytes)],
    
    113
    +            root_certificates=self.client_certs_bytes,
    
    114
    +        )
    
    115
    +
    
    116
    +    def __call__(self):
    
    117
    +        if self.load_client_certs():
    
    118
    +            # We performed a reload
    
    119
    +            return self.get_ssl_server_credentials()
    
    120
    +        else:
    
    121
    +            # Nothing changed
    
    122
    +            return None
    
    123
    +
    
    124
    +
    
    75 125
     @click.command(short_help="CAS Artifact Server")
    
    76 126
     @click.option('--port', '-p', type=click.INT, required=True, help="Port number")
    
    77 127
     @click.option('--server-key', help="Private server key for TLS (PEM-encoded)")
    
    ... ... @@ -94,22 +144,13 @@ def server_main(repo, port, server_key, server_cert, client_certs, enable_push):
    94 144
             sys.exit(-1)
    
    95 145
     
    
    96 146
         if use_tls:
    
    97
    -        # Read public/private key pair
    
    98
    -        with open(server_key, 'rb') as f:
    
    99
    -            server_key_bytes = f.read()
    
    100
    -        with open(server_cert, 'rb') as f:
    
    101
    -            server_cert_bytes = f.read()
    
    102
    -
    
    103
    -        if client_certs:
    
    104
    -            with open(client_certs, 'rb') as f:
    
    105
    -                client_certs_bytes = f.read()
    
    106
    -        else:
    
    107
    -            client_certs_bytes = None
    
    108
    -
    
    109
    -        credentials = grpc.ssl_server_credentials([(server_key_bytes, server_cert_bytes)],
    
    110
    -                                                  root_certificates=client_certs_bytes,
    
    111
    -                                                  require_client_auth=bool(client_certs))
    
    112
    -        server.add_secure_port('[::]:{}'.format(port), credentials)
    
    147
    +        credentials_gen = _SSLServerCredentialsCallable(server_key, server_cert, client_certs)
    
    148
    +        initial_credentials = credentials_gen.get_ssl_server_credentials()
    
    149
    +        dynamic_credentials = grpc.dynamic_ssl_server_credentials(
    
    150
    +            initial_certificate_configuration=initial_credentials,
    
    151
    +            certificate_configuration_fetcher=credentials_gen,
    
    152
    +            require_client_authentication=bool(client_certs))
    
    153
    +        server.add_secure_port('[::]:{}'.format(port), dynamic_credentials)
    
    113 154
         else:
    
    114 155
             server.add_insecure_port('[::]:{}'.format(port))
    
    115 156
     
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]