예제 #1
0
    def remove_cert(self, cn):
        """Removes certificates and index entries for a specified client

        Args:
            cn (str): The common name of the client (defaults to None)
        """
        cn = zencode.encode(cn)

        for entry in self.list_certs(cn):
            self._try_remove(
                path.join(self.easyrsa_pki, 'certs_by_serial',
                          entry.serial + '.pem'))

        self._try_remove(path.join(self.easyrsa_pki, 'issued', cn + '.crt'))
        self._try_remove(path.join(self.easyrsa_pki, 'private', cn + '.key'))
        self._try_remove(path.join(self.easyrsa_pki, 'reqs', cn + '.req'))

        new_index_lines = []
        with open(path.join(self.easyrsa_pki, 'index.txt')) as index_file:
            for line in index_file:
                entry = CertificateListing.parse(line)
                if entry is not None and entry.cn != cn:
                    new_index_lines.append(line)

        with open(path.join(self.easyrsa_pki, 'index.txt'), 'w') as index_file:
            index_file.write(''.join(new_index_lines))
예제 #2
0
    def list_certs(self, cn=None):
        """Returns all certificates information, or for a particular client

        Args:
            cn (str): The common name of the client (defaults to None)

        Returns:
            list[CertificateListing]: The certificate information for all certificates on the challenge, or for a specific client if specified
        """
        if cn:
            cn = zencode.encode(cn)

        listing = list()

        with open(path.join(self.easyrsa_pki, 'index.txt')) as index_file:
            for line in index_file:
                entry = CertificateListing.parse(line)
                if entry is not None and (cn is None or entry.cn == cn):
                    try:
                        entry.cn = zencode.decode(entry.cn)
                    except ValueError:
                        pass  # This is not an encoded name

                    listing.append(entry)

        return listing
예제 #3
0
    def revoke_cert(self, cn):
        """Revokes the certificates for a client

        Args:
            cn (str): The common name of the client
        """
        cn = zencode.encode(cn)

        def revoke_error_handler(e):
            if e.returncode == 1:
                if EASYRSA_ALREADY_REVOKED_MSG in e.stderr:
                    return True
                if EASYRSA_NONEXIST_REVOKE_MSG in e.stderr:
                    raise EntryNotFoundError(cn)
            return False

        proc = self._run(
            [self.easyrsa, 'revoke', cn],
            revoke_error_handler,
            input=b'yes',
        )
        if proc:
            logging.info("Revoked certificate for '{}'".format(cn))
        else:
            logging.info("Already revoked certificate for '{}'".format(cn))

            self._run([self.easyrsa, 'gen-crl'], )
예제 #4
0
    def add_cert(self, cn):
        """Creates certificates for a client

        Args:
            cn (str): The common name of the client
        """
        cn = zencode.encode(cn)

        proc = self._run(
            [self.easyrsa, 'build-client-full', cn, 'nopass'],
            lambda e: e.returncode == 1 and EASYRSA_ALREADY_EXISTS_MSG in e.
            stderr,
        )
        if proc:
            logging.info("Using existing certs for {0}".format(cn))
        else:
            logging.info("Built new certs for {0}".format(cn))
예제 #5
0
    def get_config(self, cn):
        """Returns the confgiuration file text for an OpenvVPN client

        Args:
            cn (str): The common name of the client

        Returns:
            str: The file text for the client's OpenVPN client
        """
        cn = zencode.encode(cn)

        def get_error_handler(e):
            if e.returncode == 1:
                if EASYRSA_NONEXIST_GET_MSG in e.stderr:
                    raise EntryNotFoundError(cn)
            return False

        config = self._run([getclient, cn],
                           get_error_handler).stdout.decode('utf-8')

        logging.info("Compiled configuration file for '{}'".format(cn))
        return config