blob: 9be1cdeb1c98f8558b58946b43d82c70bfbce413 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import tempfile
import docker.types
import jks
from .Container import Container
from OpenSSL import crypto
from cryptography.hazmat.primitives.serialization import pkcs12, BestAvailableEncryption, load_pem_private_key
from cryptography import x509
from ssl_utils.SSL_cert_utils import make_server_cert
class MinifiC2ServerContainer(Container):
def __init__(self, feature_context, name, vols, network, image_store, command=None, ssl=False):
engine = "minifi-c2-server-ssl" if ssl else "minifi-c2-server"
super().__init__(feature_context, name, engine, vols, network, image_store, command)
self.ssl = ssl
if ssl:
c2_cert, c2_key = make_server_cert(f"minifi-c2-server-{feature_context.id}", feature_context.root_ca_cert, feature_context.root_ca_key)
pke = jks.PrivateKeyEntry.new('c2-server-cert', [crypto.dump_certificate(crypto.FILETYPE_ASN1, c2_cert)], crypto.dump_privatekey(crypto.FILETYPE_ASN1, c2_key), 'rsa_raw')
server_keystore = jks.KeyStore.new('jks', [pke])
self.server_keystore_file = tempfile.NamedTemporaryFile(delete=False)
server_keystore.save(self.server_keystore_file.name, 'abcdefgh')
os.chmod(self.server_keystore_file.name, 0o644)
self.server_truststore_file = tempfile.NamedTemporaryFile(delete=False)
private_key_pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, feature_context.root_ca_key)
private_key = load_pem_private_key(private_key_pem, password=None)
certificate_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, feature_context.root_ca_cert)
certificate = x509.load_pem_x509_certificate(certificate_pem)
pkcs12_data = pkcs12.serialize_key_and_certificates(
name=None,
key=private_key,
cert=certificate,
cas=None,
encryption_algorithm=BestAvailableEncryption(b'abcdefgh')
)
self.server_truststore_file.write(pkcs12_data)
self.server_truststore_file.close()
os.chmod(self.server_truststore_file.name, 0o644)
self.authorities_file = tempfile.NamedTemporaryFile(delete=False)
authorities_file_content = """
CN=minifi-cpp-flow-{feature_id}:
- CLASS_MINIFI_CPP
""".format(feature_id=self.feature_context.id)
self.authorities_file.write(authorities_file_content.encode())
self.authorities_file.close()
os.chmod(self.authorities_file.name, 0o644)
def get_startup_finished_log_entry(self):
return "Server Started"
def deploy(self):
if not self.set_deployed():
return
test_dir = os.environ['TEST_DIRECTORY'] # Based on DockerVerify.sh
mounts = [docker.types.Mount(
type='bind',
source=os.path.join(test_dir, "resources/minifi-c2-server/config.yml"),
target='/opt/minifi-c2/minifi-c2-current/files/minifi-test-class/config.text.yml.v1'
)]
if self.ssl:
mounts.append(docker.types.Mount(
type='bind',
source=self.authorities_file.name,
target='/opt/minifi-c2/minifi-c2-current/conf/authorities.yaml'
))
mounts.append(docker.types.Mount(
type='bind',
source=os.path.join(test_dir, "resources/minifi-c2-server/authorizations.yaml"),
target='/opt/minifi-c2/minifi-c2-current/conf/authorizations.yaml'
))
mounts.append(docker.types.Mount(
type='bind',
source=os.path.join(test_dir, "resources/minifi-c2-server/c2.properties"),
target='/opt/minifi-c2/minifi-c2-current/conf/c2.properties'
))
mounts.append(docker.types.Mount(
type='bind',
source=self.server_keystore_file.name,
target='/opt/minifi-c2/minifi-c2-current/certs/minifi-c2-server-keystore.jks'
))
mounts.append(docker.types.Mount(
type='bind',
source=self.server_truststore_file.name,
target='/opt/minifi-c2/minifi-c2-current/certs/minifi-c2-server-truststore.p12'
))
self.docker_container = self.client.containers.run(
image='apache/nifi-minifi-c2:1.27.0',
detach=True,
name=self.name,
network=self.network.name,
mounts=mounts,
entrypoint=self.command)