Esempio n. 1
0
    def __init__(self, *args, **kwargs):
        """Initialize connection to database

        :param host: string (ex: vulture-node1:9091) or tuple
        (ex: ('vulture-node1',9091))
        :return:
        """
        super(DataBaseClient, self).__init__(*args, **kwargs)
        if kwargs.get('host') is not None:
            host = kwargs.get('host')
            if isinstance(host, tuple):
                host = '{}:{}'.format(host[0], host[1])
            self.connection_uri = 'mongodb://{}'.format(host)
            #a.connection['local']['system.replset'].find_one()
        else:
            self.connection_uri = self.get_mongodb_connection_uri()
        try:
            c = MongoClient(host=self.connection_uri,
                            ssl=True,
                            ssl_certfile=ssl_utils.get_pem_path(),
                            ssl_ca_certs=ssl_utils.get_ca_cert_path(),
                            read_preference=ReadPreference.SECONDARY_PREFERRED)

            self.hosts = list()
            self.primary_host = None
            self.connection = c
        except Exception as e:
            raise Exception("Database connection failed")
    def __init__(self, *args, **kwargs):
        """Initialize connection to database

        :return:
        """
        super(ReplicaSetClient, self).__init__(*args, **kwargs)
        self.connection_uri = self.get_mongodb_connection_uri()

        self.ipv6 = False
        if kwargs:
            self.ipv6 = kwargs.get('ipv6', False)
        if not self.ipv6:
            try:
                from gui.models.system_settings import Cluster
                node = Cluster.objects.get().get_current_node()
                manag_listener = node.get_management_listener()
                try:
                    ipaddress.IPv4Address(manag_listener.ip)
                    self.ipv6 = False
                except:
                    try:
                        ipaddress.IPv6Address(manag_listener.ip)
                        self.ipv6 = True
                    except:
                        self.ipv6 = False

            except:
                self.ipv6 = False

        try:
            c = connect('vulture',
                        host=self.connection_uri,
                        replicaSet='Vulture',
                        ssl=True,
                        ssl_certfile=ssl_utils.get_pem_path(),
                        ssl_ca_certs=ssl_utils.get_ca_cert_path(),
                        read_preference=ReadPreference.SECONDARY_PREFERRED)

            self.logger.debug("ReplicaSet hosts are : {}".format(c.hosts))
            self.hosts = c.nodes
            self.logger.debug("Primary host is : {}".format(c.primary))
            self.primary_host = c.primary
            self.connection = c

        except Exception as e:
            if 'Port number must be an integer' in str(e):
                self.logger.warning("No configuration available")
                pass  # we need to pass, if didn't we can't create conf
            elif 'is not a member of replica set' in str(e):
                self.logger.error(
                    "Oups, this node is not a member of replicaset")
                self.logger.error(
                    "Need to do rs.add (\"<this_member>:9091\") on the PRIMARY member"
                )
                pass
            else:
                self.logger.error("Unable to connect to the database : " +
                                  str(e))
                raise ReplicaConnectionFailure("Database connection failed, "
                                               "error: {}".format(e))
Esempio n. 3
0
    def create_certificate(self):
        """ Create Node certificate from Cluster CA authority

        """
        if self.certificate is None:
            # Get PKI next serial number
            cluster = Cluster.objects.get()
            serial = cluster.ca_serial
            serial += 1

            crt, key = ssl_utils.mk_signed_cert(ssl_utils.get_ca_cert_path(),
                                                ssl_utils.get_ca_key_path(),
                                                self.name, 'FR', '', '', '',
                                                '', serial)

            # TODO: Error handling
            # Save serial number
            cluster.ca_serial = serial
            cluster.save()

            # Store the certificate
            certificate = SSLCertificate()
            certificate.name = str(crt.get_subject())
            certificate.cn = str(self.name)
            certificate.o = 'FR'
            certificate.cert = crt.as_pem().decode('utf8')
            certificate.key = key.as_pem(cipher=None).decode('utf8')
            certificate.status = 'V'
            certificate.issuer = str(crt.get_issuer())
            certificate.validfrom = str(crt.get_not_before().get_datetime())
            certificate.validtill = str(crt.get_not_after().get_datetime())
            certificate.serial = str(serial)
            certificate.is_ca = False

            internal = cluster.ca_certificate
            certificate.chain = str(internal.cert)

            certificate.save()
            self.certificate = certificate
            self.save()
    def write_MongoCert (self):
        """Save the certificate/key and associated ca on disk for use in mongoDB connection
        MongoDB requires that certificate and key are in the same file

        :return: certificate_path, chain_path
        """
        file_tmp = None
        try:
            file_tmp = open("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".pem", "r")
        except Exception as e:
            pass

        # If the file does not exists yet, create it
        if file_tmp is None:
            file = open("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".pem", "w")
            file.write(self.cert)
            if self.key:
                file.write("\n")
                #FIXME: Encrypt Key
                file.write(self.key)
            file.close()

            file = open("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".key", "w")
            if self.key:
                #FIXME: Encrypt Key
                file.write(self.key)
            file.close()

            file = open("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".crt", "w")
            file.write(self.cert)
            file.close()

            # Set permissions to this file
            os.chmod("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".pem", 660)
            os.chmod("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".key", 660)
            os.chmod("/home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".crt", 660)
            os.system("/usr/bin/chgrp vlt-web /home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".pem")
            os.system("/usr/bin/chgrp vlt-web /home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".key")
            os.system("/usr/bin/chgrp vlt-web /home/vlt-sys/Engine/conf/cert-" + str(self.id) + ".crt")
        else:
            file_tmp.close()

        # If the file already exists, nothing to do
        file_tmp = None
        try:
            file_tmp = open("/home/vlt-sys/Engine/conf/ca-" + str(self.id) + ".pem", "r")
        except Exception as e:
            pass

        if file_tmp is None:
            #Always add the local CA Cert in chain file
            ca_path = get_ca_cert_path()
            file = open(ca_path, "r")
            ca = file.read()
            file.close()

            file = open("/home/vlt-sys/Engine/conf/ca-" + str(self.id) + ".pem", "w")
            file.write(ca)
            file.write("\n")
            file.write(self.chain)
            file.close()

            # Set permissions to this file
            try:
                os.chmod("/home/vlt-sys/Engine/conf/ca-" + str(self.id) + ".pem", 660)
                os.system("/usr/bin/chgrp vlt-web /home/vlt-sys/Engine/conf/ca-" + str(self.id) + ".pem")
            except Exception as e:
                pass
        else:
            file_tmp.close()

        return "/home/vlt-sys/Engine/conf/cert-"+str(self.id)+".pem", "/home/vlt-sys/Engine/conf/ca-" + str(self.id) + ".pem",
Esempio n. 5
0
sys.path.append('/home/vlt-gui/vulture')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'vulture.settings')

import django
django.setup()

from gui.models.system_settings import Cluster
from gui.models.modssl_settings import ModSSL
from vulture_toolkit.system import ssl_utils

from M2Crypto import X509

if __name__ == '__main__':

    ca_cert = X509.load_cert(ssl_utils.get_ca_cert_path())

    C = ""
    ST = ""
    L = ""
    O = ""
    OU = ""
    for i in ca_cert.get_subject().as_text().split(','):
        i = i.strip()
        print(i)
        if i[:2] == "C=":
            C = i[2:]
        elif i[:3] == "ST=":
            ST = i[3:]
        elif i[:2] == "L=":
            L = i[2:]
    def execute_command(self, cmd, host=None, database="test"):
        """Connect to a mongodb instance using mongo client,to execute a command

        :param cmd: command to execute
        :param host: Target host, if not defined primary host is used
        :return:
        """
        if host is not None:
            hostname = host[0]
            port = str(host[1])
        else:
            hostname = self.primary_host[0]
            port = str(self.primary_host[1])
        """ Send mongo command """
        if not self.ipv6:
            params_cmd = [
                "/usr/local/bin/mongo", "--quiet", "--ssl", "--sslPEMKeyFile",
                ssl_utils.get_pem_path(), "--sslCAFile",
                ssl_utils.get_ca_cert_path(),
                "{}:{}/{}".format(hostname, port, database), "--eval", cmd
            ]

        else:
            params_cmd = [
                "/usr/local/bin/mongo", "--quiet", "--ipv6", "--ssl",
                "--sslPEMKeyFile",
                ssl_utils.get_pem_path(), "--sslCAFile",
                ssl_utils.get_ca_cert_path(),
                "{}:{}/{}".format(hostname, port, database), "--eval", cmd
            ]

        proc = subprocess.Popen(params_cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        res = proc.communicate()
        success = res[0]
        error = res[1]
        if success:
            """Extracting response from entire string 
            """
            raw_response = success.replace(b"\t", b"").replace(b"\n",
                                                               b"").replace(
                                                                   b"\r", b"")
            try:
                response = json.loads(raw_response)
            except ValueError:
                pattern = re.compile(
                    b".*reconnected to server after rs command "
                    b"\(which is normal\).*", re.S)
                """We can encounter an error when executing command, it's normal
                we just need to retry command"""
                if pattern.match(raw_response):
                    response, error = self.execute_command(
                        cmd, host)  #TODO Care to infinite loops
                    return response, error
                else:
                    response = None
                    self.logger.error(
                        "Unexpected error : {}".format(raw_response))
                    self.logger.error("Command was: {}".format(cmd))
        else:
            self.logger.error(error)
        return response, error
Esempio n. 7
0
def create(request):
    """ View dedicated to certificate creation
    :param request: Django request object
    """

    form = CertForm(request.POST or None)

    # Saving information into database and redirect to certificate list
    if request.method == 'POST' and form.is_valid():
        cert = form.save(commit=False)

        # We want to create a Let's Encrypt certificate...
        if request.POST.get("cert-type") == "acme-client":

            # Call acme-client to generate the Let's Encrypt challenge
            proc = subprocess.Popen(
                [
                    '/usr/local/bin/sudo', '-u', 'vlt-sys',
                    '/usr/local/bin/sudo', '/usr/local/bin/sudo',
                    '/usr/local/sbin/acme.sh', '--issue', '-d', cert.cn,
                    '--webroot', '/home/vlt-sys/Engine/conf', '--cert-home',
                    '/usr/local/etc/ssl/acme'
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                env={
                    'PATH':
                    "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
                })
            success, error = proc.communicate()

            if error:
                logger.error("Let's encrypt Error: {}".format(error))
                return render_to_response(
                    'cert_create.html', {
                        'form': form,
                        'error': error
                    },
                    context_instance=RequestContext(request))
            else:
                logger.info(
                    "Let's encrypt certificate was issued for '{}".format(
                        cert.cn))
                """ At this point, the certificate is ondisk: We need to store it into MongoDB """
                proc = subprocess.Popen([
                    '/usr/local/bin/sudo', '-u', 'vlt-sys',
                    '/usr/local/bin/sudo', '/usr/local/bin/sudo', '/bin/cat',
                    '/usr/local/etc/ssl/acme/{}/{}.key'.format(
                        cert.cn, cert.cn)
                ],
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                private_key, error = proc.communicate()
                if error:
                    logger.error(
                        "Let's encrypt Error: Unable to read private key")
                    return render_to_response(
                        'cert_create.html', {
                            'form': form,
                            'error': 'Unable to read private key'
                        },
                        context_instance=RequestContext(request))

                proc = subprocess.Popen([
                    '/usr/local/bin/sudo', '-u', 'vlt-sys',
                    '/usr/local/bin/sudo', '/usr/local/bin/sudo', '/bin/cat',
                    '/usr/local/etc/ssl/acme/{}/ca.cer'.format(cert.cn)
                ],
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                ca, error = proc.communicate()
                if error:
                    logger.error("Let's encrypt Error: Unable to read CA")
                    return render_to_response(
                        'cert_create.html', {
                            'form': form,
                            'error': 'Unable to read CA'
                        },
                        context_instance=RequestContext(request))

                proc = subprocess.Popen([
                    '/usr/local/bin/sudo', '-u', 'vlt-sys',
                    '/usr/local/bin/sudo', '/usr/local/bin/sudo', '/bin/cat',
                    '/usr/local/etc/ssl/acme/{}/{}.cer'.format(
                        cert.cn, cert.cn)
                ],
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                certificate, error = proc.communicate()
                if error:
                    logger.error(
                        "Let's encrypt Error: Unable to read certificate")
                    return render_to_response(
                        'cert_create.html', {
                            'form': form,
                            'error': 'Unable to read certificate'
                        },
                        context_instance=RequestContext(request))

                # Store the certificate
                x509Cert = X509.load_cert_string(certificate)

                cert.cert = str(certificate.decode('utf8'))
                cert.key = str(private_key.decode('utf8'))
                cert.name = str(x509Cert.get_subject())
                cert.status = 'V'
                cert.issuer = str("LET'S ENCRYPT")
                cert.validfrom = str(x509Cert.get_not_before().get_datetime())
                cert.validtill = str(x509Cert.get_not_after().get_datetime())
                if x509Cert.check_ca():
                    cert.is_ca = True
                else:
                    cert.is_ca = False
                cert.serial = str(x509Cert.get_serial_number())
                cert.chain = str(ca.decode('utf8'))
                cert.save()

                return HttpResponseRedirect('/system/cert/')

        # Get PKI next serial number
        cluster = Cluster.objects.get()
        serial = cluster.ca_serial
        serial = serial + 1

        # Create a certificate
        ca_cert_file = get_ca_cert_path()
        ca_key_file = get_ca_key_path()

        crt, pk2 = mk_signed_cert(ca_cert_file, ca_key_file, cert.cn, cert.c,
                                  cert.st, cert.l, cert.o, cert.ou, serial)

        # Save serial number
        cluster.ca_serial = serial
        cluster.save()

        internal = cluster.ca_certificate

        # Store the certificate
        cert.cert = crt.as_pem().decode('utf8')
        cert.key = pk2.as_pem(cipher=None).decode('utf8')
        cert.name = str(crt.get_subject())
        cert.status = 'V'
        cert.issuer = str(internal.issuer)
        cert.validfrom = str(crt.get_not_before().get_datetime())
        cert.validtill = str(crt.get_not_after().get_datetime())
        cert.is_ca = False
        cert.serial = str(serial)
        cert.chain = str(internal.cert)
        cert.save()

        return HttpResponseRedirect('/system/cert/')

    return render_to_response('cert_create.html', {
        'form': form,
    },
                              context_instance=RequestContext(request))