Exemple #1
0
def update_configuration(lineagename, archive_dir, target, cli_config):
    """Modifies lineagename's config to contain the specified values.

    :param str lineagename: Name of the lineage being modified
    :param str archive_dir: Absolute path to the archive directory
    :param dict target: Maps ALL_FOUR to their symlink paths
    :param .NamespaceConfig cli_config: parsed command line
        arguments

    :returns: Configuration object for the updated config file
    :rtype: configobj.ConfigObj

    """
    config_filename = renewal_filename_for_lineagename(cli_config, lineagename)
    temp_filename = config_filename + ".new"

    # If an existing tempfile exists, delete it
    if os.path.exists(temp_filename):
        os.unlink(temp_filename)

    # Save only the config items that are relevant to renewal
    values = relevant_values(vars(cli_config.namespace))
    write_renewal_config(config_filename, temp_filename, archive_dir, target, values)
    misc.os_rename(temp_filename, config_filename)

    return configobj.ConfigObj(config_filename)
Exemple #2
0
    def _update_link_to(self, kind, version):
        """Make the specified item point at the specified version.

        (Note that this method doesn't verify that the specified version
        exists.)

        :param str kind: the lineage member item ("cert", "privkey",
            "chain", or "fullchain")
        :param int version: the desired version

        """
        if kind not in ALL_FOUR:
            raise errors.CertStorageError("unknown kind of item")
        link = getattr(self, kind)
        filename = "{0}{1}.pem".format(kind, version)
        # Relative rather than absolute target directory
        target_directory = os.path.dirname(os.readlink(link))
        # TODO: it could be safer to make the link first under a temporary
        #       filename, then unlink the old link, then rename the new link
        #       to the old link; this ensures that this process is able to
        #       create symlinks.
        # TODO: we might also want to check consistency of related links
        #       for the other corresponding items
        os.unlink(link)
        os.symlink(os.path.join(target_directory, filename), link)
Exemple #3
0
 def test_current_version(self):
     for ver in (1, 5, 10, 20):
         self._write_out_kind("cert", ver)
     os.unlink(self.test_rc.cert)
     os.symlink(os.path.join("..", "..", "archive", "example.org",
                             "cert10.pem"), self.test_rc.cert)
     self.assertEqual(self.test_rc.current_version("cert"), 10)
Exemple #4
0
def update_configuration(lineagename, archive_dir, target, cli_config):
    """Modifies lineagename's config to contain the specified values.

    :param str lineagename: Name of the lineage being modified
    :param str archive_dir: Absolute path to the archive directory
    :param dict target: Maps ALL_FOUR to their symlink paths
    :param .NamespaceConfig cli_config: parsed command line
        arguments

    :returns: Configuration object for the updated config file
    :rtype: configobj.ConfigObj

    """
    config_filename = renewal_filename_for_lineagename(cli_config, lineagename)
    temp_filename = config_filename + ".new"

    # If an existing tempfile exists, delete it
    if os.path.exists(temp_filename):
        os.unlink(temp_filename)

    # Save only the config items that are relevant to renewal
    values = relevant_values(vars(cli_config.namespace))
    write_renewal_config(config_filename, temp_filename, archive_dir, target,
                         values)
    filesystem.replace(temp_filename, config_filename)

    return configobj.ConfigObj(config_filename)
Exemple #5
0
    def _update_link_to(self, kind, version):
        """Make the specified item point at the specified version.

        (Note that this method doesn't verify that the specified version
        exists.)

        :param str kind: the lineage member item ("cert", "privkey",
            "chain", or "fullchain")
        :param int version: the desired version

        """
        if kind not in ALL_FOUR:
            raise errors.CertStorageError("unknown kind of item")
        link = getattr(self, kind)
        filename = "{0}{1}.pem".format(kind, version)
        # Relative rather than absolute target directory
        target_directory = os.path.dirname(filesystem.readlink(link))
        # TODO: it could be safer to make the link first under a temporary
        #       filename, then unlink the old link, then rename the new link
        #       to the old link; this ensures that this process is able to
        #       create symlinks.
        # TODO: we might also want to check consistency of related links
        #       for the other corresponding items
        os.unlink(link)
        os.symlink(os.path.join(target_directory, filename), link)
Exemple #6
0
 def test_current_version(self):
     for ver in (1, 5, 10, 20):
         self._write_out_kind("cert", ver)
     os.unlink(self.test_rc.cert)
     os.symlink(os.path.join("..", "..", "archive", "example.org",
                             "cert10.pem"), self.test_rc.cert)
     self.assertEqual(self.test_rc.current_version("cert"), 10)
Exemple #7
0
 def _symlink_to_accounts_dir(self, prev_server_path, server_path):
     accounts_dir = self.config.accounts_dir_for_server_path(server_path)
     if os.path.islink(accounts_dir):
         os.unlink(accounts_dir)
     else:
         os.rmdir(accounts_dir)
     prev_account_dir = self.config.accounts_dir_for_server_path(prev_server_path)
     os.symlink(prev_account_dir, accounts_dir)
Exemple #8
0
 def _symlink_to_accounts_dir(self, prev_server_path, server_path):
     accounts_dir = self.config.accounts_dir_for_server_path(server_path)
     if os.path.islink(accounts_dir):
         os.unlink(accounts_dir)
     else:
         os.rmdir(accounts_dir)
     prev_account_dir = self.config.accounts_dir_for_server_path(prev_server_path)
     os.symlink(prev_account_dir, accounts_dir)
Exemple #9
0
    def _update_symlinks(self):
        """Updates symlinks to use archive_dir"""
        for kind in ALL_FOUR:
            link = getattr(self, kind)
            previous_link = get_link_target(link)
            new_link = os.path.join(self.relative_archive_dir(link),
                os.path.basename(previous_link))

            os.unlink(link)
            os.symlink(new_link, link)
Exemple #10
0
    def _update_symlinks(self):
        """Updates symlinks to use archive_dir"""
        for kind in ALL_FOUR:
            link = getattr(self, kind)
            previous_link = get_link_target(link)
            new_link = os.path.join(self.relative_archive_dir(link),
                                    os.path.basename(previous_link))

            os.unlink(link)
            os.symlink(new_link, link)
Exemple #11
0
    def test_names(self):
        # Trying the current version
        self._write_out_kind("cert", 12, test_util.load_vector("cert-san_512.pem"))

        self.assertEqual(self.test_rc.names(),
                         ["example.com", "www.example.com"])

        # Trying missing cert
        os.unlink(self.test_rc.cert)
        self.assertRaises(errors.CertStorageError, self.test_rc.names)
Exemple #12
0
 def _write_out_kind(self, kind, ver, value=None):
     link = getattr(self.test_rc, kind)
     if os.path.lexists(link):
         os.unlink(link)
     os.symlink(os.path.join(os.path.pardir, os.path.pardir, "archive",
                             "example.org", "{0}{1}.pem".format(kind, ver)),
                link)
     with open(link, "wb") as f:
         f.write(kind.encode('ascii') if value is None else value)
     if kind == "privkey":
         os.chmod(link, 0o600)
Exemple #13
0
 def _write_out_kind(self, kind, ver, value=None):
     link = getattr(self.test_rc, kind)
     if os.path.lexists(link):
         os.unlink(link)
     os.symlink(
         os.path.join(os.path.pardir, os.path.pardir, "archive",
                      "example.org", "{0}{1}.pem".format(kind, ver)), link)
     with open(link, "wb") as f:
         f.write(kind.encode('ascii') if value is None else value)
     if kind == "privkey":
         filesystem.chmod(link, 0o600)
Exemple #14
0
    def test_renewal_bad_config(self):
        """Test that the RenewableCert constructor will complain if
        the renewal configuration file doesn't end in ".conf"

        """
        from certbot._internal import storage
        broken = os.path.join(self.config.config_dir, "broken.conf")
        with open(broken, "w") as f:
            f.write("[No closing bracket for you!")
        self.assertRaises(errors.CertStorageError, storage.RenewableCert,
                          broken, self.config)
        os.unlink(broken)
        self.assertRaises(errors.CertStorageError, storage.RenewableCert,
                          "fun", self.config)
Exemple #15
0
    def test_renewal_bad_config(self):
        """Test that the RenewableCert constructor will complain if
        the renewal configuration file doesn't end in ".conf"

        """
        from certbot import storage
        broken = os.path.join(self.config.config_dir, "broken.conf")
        with open(broken, "w") as f:
            f.write("[No closing bracket for you!")
        self.assertRaises(errors.CertStorageError, storage.RenewableCert,
                          broken, self.config)
        os.unlink(broken)
        self.assertRaises(errors.CertStorageError, storage.RenewableCert,
                          "fun", self.config)
Exemple #16
0
    def update_all_links_to(self, version):
        """Change all member objects to point to the specified version.

        :param int version: the desired version

        """
        with error_handler.ErrorHandler(self._fix_symlinks):
            previous_links = self._previous_symlinks()
            for kind, link in previous_links:
                os.symlink(self.current_target(kind), link)

            for kind in ALL_FOUR:
                self._update_link_to(kind, version)

            for _, link in previous_links:
                os.unlink(link)
Exemple #17
0
    def update_all_links_to(self, version):
        """Change all member objects to point to the specified version.

        :param int version: the desired version

        """
        with error_handler.ErrorHandler(self._fix_symlinks):
            previous_links = self._previous_symlinks()
            for kind, link in previous_links:
                os.symlink(self.current_target(kind), link)

            for kind in ALL_FOUR:
                self._update_link_to(kind, version)

            for _, link in previous_links:
                os.unlink(link)
Exemple #18
0
 def test_current_target(self):
     # Relative path logic
     self._write_out_kind("cert", 17)
     self.assertTrue(os.path.samefile(self.test_rc.current_target("cert"),
                                      os.path.join(self.config.config_dir, "archive",
                                                   "example.org",
                                                   "cert17.pem")))
     # Absolute path logic
     os.unlink(self.test_rc.cert)
     os.symlink(os.path.join(self.config.config_dir, "archive", "example.org",
                             "cert17.pem"), self.test_rc.cert)
     with open(self.test_rc.cert, "w") as f:
         f.write("cert")
     self.assertTrue(os.path.samefile(self.test_rc.current_target("cert"),
                                      os.path.join(self.config.config_dir, "archive",
                                                   "example.org",
                                                   "cert17.pem")))
Exemple #19
0
 def test_current_target(self):
     # Relative path logic
     self._write_out_kind("cert", 17)
     self.assertTrue(os.path.samefile(self.test_rc.current_target("cert"),
                                      os.path.join(self.config.config_dir, "archive",
                                                   "example.org",
                                                   "cert17.pem")))
     # Absolute path logic
     os.unlink(self.test_rc.cert)
     os.symlink(os.path.join(self.config.config_dir, "archive", "example.org",
                             "cert17.pem"), self.test_rc.cert)
     with open(self.test_rc.cert, "w") as f:
         f.write("cert")
     self.assertTrue(os.path.samefile(self.test_rc.current_target("cert"),
                                      os.path.join(self.config.config_dir, "archive",
                                                   "example.org",
                                                   "cert17.pem")))
Exemple #20
0
    def _fix_symlinks(self):
        """Fixes symlinks in the event of an incomplete version update.

        If there is no problem with the current symlinks, this function
        has no effect.

        """
        previous_symlinks = self._previous_symlinks()
        if all(os.path.exists(link[1]) for link in previous_symlinks):
            for kind, previous_link in previous_symlinks:
                current_link = getattr(self, kind)
                if os.path.lexists(current_link):
                    os.unlink(current_link)
                os.symlink(filesystem.readlink(previous_link), current_link)

        for _, link in previous_symlinks:
            if os.path.exists(link):
                os.unlink(link)
Exemple #21
0
    def _fix_symlinks(self):
        """Fixes symlinks in the event of an incomplete version update.

        If there is no problem with the current symlinks, this function
        has no effect.

        """
        previous_symlinks = self._previous_symlinks()
        if all(os.path.exists(link[1]) for link in previous_symlinks):
            for kind, previous_link in previous_symlinks:
                current_link = getattr(self, kind)
                if os.path.lexists(current_link):
                    os.unlink(current_link)
                os.symlink(os.readlink(previous_link), current_link)

        for _, link in previous_symlinks:
            if os.path.exists(link):
                os.unlink(link)
Exemple #22
0
 def test_consistent(self):
     # pylint: disable=protected-access
     oldcert = self.test_rc.cert
     self.test_rc.cert = "relative/path"
     # Absolute path for item requirement
     self.assertFalse(self.test_rc._consistent())
     self.test_rc.cert = oldcert
     # Items must exist requirement
     self.assertFalse(self.test_rc._consistent())
     # Items must be symlinks requirements
     fill_with_sample_data(self.test_rc)
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to desired place if they are relative
     for kind in ALL_FOUR:
         os.symlink(os.path.join("..", kind + "17.pem"),
                    getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to desired place if they are absolute
     for kind in ALL_FOUR:
         os.symlink(os.path.join(self.config.config_dir, kind + "17.pem"),
                    getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to things that exist
     for kind in ALL_FOUR:
         os.symlink(
             os.path.join("..", "..", "archive", "example.org",
                          kind + "17.pem"), getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     # This version should work
     fill_with_sample_data(self.test_rc)
     self.assertTrue(self.test_rc._consistent())
     # Items must point to things that follow the naming convention
     os.unlink(self.test_rc.fullchain)
     os.symlink(
         os.path.join("..", "..", "archive", "example.org",
                      "fullchain_17.pem"), self.test_rc.fullchain)
     with open(self.test_rc.fullchain, "w") as f:
         f.write("wrongly-named fullchain")
     self.assertFalse(self.test_rc._consistent())
Exemple #23
0
 def test_consistent(self):
     # pylint: disable=too-many-statements,protected-access
     oldcert = self.test_rc.cert
     self.test_rc.cert = "relative/path"
     # Absolute path for item requirement
     self.assertFalse(self.test_rc._consistent())
     self.test_rc.cert = oldcert
     # Items must exist requirement
     self.assertFalse(self.test_rc._consistent())
     # Items must be symlinks requirements
     fill_with_sample_data(self.test_rc)
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to desired place if they are relative
     for kind in ALL_FOUR:
         os.symlink(os.path.join("..", kind + "17.pem"),
                    getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to desired place if they are absolute
     for kind in ALL_FOUR:
         os.symlink(os.path.join(self.config.config_dir, kind + "17.pem"),
                    getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     unlink_all(self.test_rc)
     # Items must point to things that exist
     for kind in ALL_FOUR:
         os.symlink(os.path.join("..", "..", "archive", "example.org",
                                 kind + "17.pem"),
                    getattr(self.test_rc, kind))
     self.assertFalse(self.test_rc._consistent())
     # This version should work
     fill_with_sample_data(self.test_rc)
     self.assertTrue(self.test_rc._consistent())
     # Items must point to things that follow the naming convention
     os.unlink(self.test_rc.fullchain)
     os.symlink(os.path.join("..", "..", "archive", "example.org",
                             "fullchain_17.pem"), self.test_rc.fullchain)
     with open(self.test_rc.fullchain, "w") as f:
         f.write("wrongly-named fullchain")
     self.assertFalse(self.test_rc._consistent())
Exemple #24
0
    def _delete_links_and_find_target_dir(
            self, server_path: str, link_func: Callable[[str], str]) -> str:
        """Delete symlinks and return the nonsymlinked directory path.

        :param str server_path: file path based on server
        :param callable link_func: callable that returns possible links
            given a server_path

        :returns: the final, non-symlinked target
        :rtype: str

        """
        dir_path = link_func(server_path)

        # does an appropriate directory link to me? if so, make sure that's gone
        reused_servers = {}
        for k, v in constants.LE_REUSE_SERVERS.items():
            reused_servers[v] = k

        # is there a next one up?
        possible_next_link = True
        while possible_next_link:
            possible_next_link = False
            if server_path in reused_servers:
                next_server_path = reused_servers[server_path]
                next_dir_path = link_func(next_server_path)
                if os.path.islink(next_dir_path) and filesystem.readlink(
                        next_dir_path) == dir_path:
                    possible_next_link = True
                    server_path = next_server_path
                    dir_path = next_dir_path

        # if there's not a next one up to delete, then delete me
        # and whatever I link to
        while os.path.islink(dir_path):
            target = filesystem.readlink(dir_path)
            os.unlink(dir_path)
            dir_path = target

        return dir_path
Exemple #25
0
    def _delete_links_and_find_target_dir(self, server_path, link_func):
        """Delete symlinks and return the nonsymlinked directory path.

        :param str server_path: file path based on server
        :param callable link_func: callable that returns possible links
            given a server_path

        :returns: the final, non-symlinked target
        :rtype: str

        """
        dir_path = link_func(server_path)

        # does an appropriate directory link to me? if so, make sure that's gone
        reused_servers = {}
        for k in constants.LE_REUSE_SERVERS:
            reused_servers[constants.LE_REUSE_SERVERS[k]] = k

        # is there a next one up?
        possible_next_link = True
        while possible_next_link:
            possible_next_link = False
            if server_path in reused_servers:
                next_server_path = reused_servers[server_path]
                next_dir_path = link_func(next_server_path)
                if os.path.islink(next_dir_path) and os.readlink(next_dir_path) == dir_path:
                    possible_next_link = True
                    server_path = next_server_path
                    dir_path = next_dir_path

        # if there's not a next one up to delete, then delete me
        # and whatever I link to
        while os.path.islink(dir_path):
            target = os.readlink(dir_path)
            os.unlink(dir_path)
            dir_path = target

        return dir_path
Exemple #26
0
    def test_names(self):
        # Trying the current version
        self._write_out_kind("cert", 12,
                             test_util.load_vector("cert-san_512.pem"))

        self.assertEqual(self.test_rc.names(),
                         ["example.com", "www.example.com"])

        # Trying a non-current version
        self._write_out_kind("cert", 15, test_util.load_vector("cert_512.pem"))

        self.assertEqual(self.test_rc.names(12),
                         ["example.com", "www.example.com"])

        # Testing common name is listed first
        self._write_out_kind("cert", 12,
                             test_util.load_vector("cert-5sans_512.pem"))

        self.assertEqual(self.test_rc.names(12), ["example.com"] +
                         ["{0}.example.com".format(c) for c in "abcd"])

        # Trying missing cert
        os.unlink(self.test_rc.cert)
        self.assertRaises(errors.CertStorageError, self.test_rc.names)
Exemple #27
0
    def test_names(self):
        # Trying the current version
        self._write_out_kind("cert", 12, test_util.load_vector("cert-san_512.pem"))

        self.assertEqual(self.test_rc.names(),
                         ["example.com", "www.example.com"])

        # Trying a non-current version
        self._write_out_kind("cert", 15, test_util.load_vector("cert_512.pem"))

        self.assertEqual(self.test_rc.names(12),
                         ["example.com", "www.example.com"])

        # Testing common name is listed first
        self._write_out_kind(
            "cert", 12, test_util.load_vector("cert-5sans_512.pem"))

        self.assertEqual(
            self.test_rc.names(12),
            ["example.com"] + ["{0}.example.com".format(c) for c in "abcd"])

        # Trying missing cert
        os.unlink(self.test_rc.cert)
        self.assertRaises(errors.CertStorageError, self.test_rc.names)
Exemple #28
0
def unlink_all(rc_object):
    """Unlink all four items associated with this RenewableCert."""
    for kind in ALL_FOUR:
        os.unlink(getattr(rc_object, kind))
Exemple #29
0
def unlink_all(rc_object):
    """Unlink all four items associated with this RenewableCert."""
    for kind in ALL_FOUR:
        os.unlink(getattr(rc_object, kind))