def _prog(shell_cmd): """Extract the program run by a shell command. :param str shell_cmd: command to be executed :returns: basename of command or None if the command isn't found :rtype: str or None """ if not util.exe_exists(shell_cmd): plug_util.path_surgery(shell_cmd) if not util.exe_exists(shell_cmd): return None return os.path.basename(shell_cmd)
def set_up(): """Prepare tests to be run. Logging is set up and temporary directories are set up to contain a basic Certbot and Nginx configuration. The directories are returned in the order they should be locked by Certbot. If the Nginx plugin is expected to work on the system, the Nginx directory is included, otherwise, it is not. A Certbot command is also created that uses the temporary directories. The returned command can be used to test different subcommands by appending the desired command to the end. :returns: directories and command :rtype: `tuple` of `list` """ logging.basicConfig(format='%(message)s', level=logging.INFO) config_dir, logs_dir, work_dir, nginx_dir = set_up_dirs() command = set_up_command(config_dir, logs_dir, work_dir, nginx_dir) dirs = [logs_dir, config_dir, work_dir] # If Nginx is installed, do the test, otherwise skip it. # Issue https://github.com/certbot/certbot/issues/8121 tracks the work to remove this control. if util.exe_exists('nginx'): dirs.append(nginx_dir) else: logger.warning('Skipping Nginx lock tests') return dirs, command
def path_surgery(restart_cmd): """Attempt to perform PATH surgery to find restart_cmd Mitigates https://github.com/certbot/certbot/issues/1833 :param str restart_cmd: the command that is being searched for in the PATH :returns: True if the operation succeeded, False otherwise """ dirs = ("/usr/sbin", "/usr/local/bin", "/usr/local/sbin") path = os.environ["PATH"] added = [] for d in dirs: if d not in path: path += os.pathsep + d added.append(d) if any(added): logger.debug("Can't find %s, attempting PATH mitigation by adding %s", restart_cmd, os.pathsep.join(added)) os.environ["PATH"] = path if util.exe_exists(restart_cmd): return True else: expanded = " expanded" if any(added) else "" logger.warning("Failed to find %s in%s PATH: %s", restart_cmd, expanded, path) return False
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError( "Could not find a usable 'nginx' binary. Ensure nginx exists, " "the binary is executable, and your PATH is set correctly.") # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) self.install_ssl_dhparams() # Set Version if self.version is None: self.version = self.get_version() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError('Unable to lock {0}'.format(self.conf('server-root')))
def set_up(): """Prepare tests to be run. Logging is set up and temporary directories are set up to contain a basic Certbot and Nginx configuration. The directories are returned in the order they should be locked by Certbot. If the Nginx plugin is expected to work on the system, the Nginx directory is included, otherwise, it is not. A Certbot command is also created that uses the temporary directories. The returned command can be used to test different subcommands by appending the desired command to the end. :returns: directories and command :rtype: `tuple` of `list` """ logging.basicConfig(format='%(message)s', level=logging.INFO) config_dir, logs_dir, work_dir, nginx_dir = set_up_dirs() command = set_up_command(config_dir, logs_dir, work_dir, nginx_dir) dirs = [logs_dir, config_dir, work_dir] # Travis and Circle CI set CI to true so we # will always test Nginx's lock during CI if os.environ.get('CI') == 'true' or util.exe_exists('nginx'): dirs.append(nginx_dir) else: logger.warning('Skipping Nginx lock tests') return dirs, command
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError( "Could not find a usable 'nginx' binary. Ensure nginx exists, " "the binary is executable, and your PATH is set correctly.") # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) # Set Version if self.version is None: self.version = self.get_version() if self.openssl_version is None: self.openssl_version = self._get_openssl_version() self.install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) self.install_ssl_dhparams() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError('Unable to lock {0}'.format(self.conf('server-root')))
def path_surgery(cmd): """Attempt to perform PATH surgery to find cmd Mitigates https://github.com/certbot/certbot/issues/1833 :param str cmd: the command that is being searched for in the PATH :returns: True if the operation succeeded, False otherwise """ path = os.environ["PATH"] added = [] for d in STANDARD_BINARY_DIRS: if d not in path: path += os.pathsep + d added.append(d) if any(added): logger.debug("Can't find %s, attempting PATH mitigation by adding %s", cmd, os.pathsep.join(added)) os.environ["PATH"] = path if util.exe_exists(cmd): return True expanded = " expanded" if any(added) else "" logger.debug("Failed to find executable %s in%s PATH: %s", cmd, expanded, path) return False
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) # Set Version if self.version is None: self.version = self.get_version() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError( 'Unable to lock %s', self.conf('server-root'))
def prepare(): """ Check if we can restart HAProxy when we are done. :raises .errors.NoInstallationError when no haproxy executable can be found :raises .errors.NoInstallationError when the default service manager executable can't be found :raises .errors.NotSupportedError when the installed haproxy version is incompatible with this plugin """ service_mgr = constants.os_constant("service_manager") if not util.exe_exists(service_mgr): raise errors.NoInstallationError( "Can't find the default service manager for your system:" "{0}, please install it first or configure different OS" " constants".format(service_mgr)) # Check that a supported version of HAProxy is installed. version_cmd = constants.os_constant("version_cmd") output = subprocess.check_output(version_cmd).decode('utf8') matches = re.match( r'HA-Proxy version' r' (?P<version>[0-9]{1,4}\.[0-9]{1,4}\.[0-9a-z]{1,10}).*', output) if matches is None: raise errors.NoInstallationError( "It looks like HAProxy is not installed or the version might" " be incompatible.") else: version = matches.group('version') if StrictVersion(version) < StrictVersion(HAPROXY_MIN_VERSION): raise errors.NotSupportedError( "Version {} of HAProxy is not supported by this plugin," " you need to install {} or higher to be" " incompatible.".format(version, HAPROXY_MIN_VERSION))
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() self.parser = parser.NginxParser(self.conf('server-root')) install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest) self.install_ssl_dhparams() # Set Version if self.version is None: self.version = self.get_version() # Prevent two Nginx plugins from modifying a config at once try: util.lock_dir_until_exit(self.conf('server-root')) except (OSError, errors.LockError): logger.debug('Encountered error:', exc_info=True) raise errors.PluginError( 'Unable to lock %s', self.conf('server-root'))
def prepare(self): logger.debug("******* Inside prepare*************") logger.debug("value for self" + self.conf('ctl')) if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError( "Could not find a usable 'tomcat' binary. Ensure tomcat exists, " "the binary is executable, and your PATH is set correctly.") self.parser = tomcat_parser.TomcatParser(self.conf("server-root"))
def _enable_mod_debian(self, mod_name, temp): """Assumes mods-available, mods-enabled layout.""" # Generate reversal command. # Try to be safe here... check that we can probably reverse before # applying enmod command if not util.exe_exists(self.option("dismod")): raise errors.MisconfigurationError( "Unable to find a2dismod, please make sure a2enmod and " "a2dismod are configured correctly for certbot.") self.reverter.register_undo_command( temp, [self.option("dismod"), "-f", mod_name]) util.run_script([self.option("enmod"), mod_name])
def __init__(self): self.broken = False if not util.exe_exists("openssl"): logger.info("openssl not installed, can't check revocation") self.broken = True return # New versions of openssl want -header var=val, old ones want -header var val test_host_format = Popen(["openssl", "ocsp", "-header", "var", "val"], stdout=PIPE, stderr=PIPE, universal_newlines=True) _out, err = test_host_format.communicate() if "Missing =" in err: self.host_args = lambda host: ["Host=" + host] else: self.host_args = lambda host: ["Host", host]
def verify_exe_exists(exe, message=None): """Ensures an executable with the given name is available. If an executable isn't found for the given path or name, extra directories are added to the user's PATH to help find system utilities that may not be available in the default cron PATH. :param str exe: executable path or name :param str message: Error message to print. :raises .NoInstallationError: when the executable isn't found """ if message is None: message = "Cannot find executable '{0}'.".format(exe) if not (certbot_util.exe_exists(exe) or plugins_util.path_surgery(exe)): raise errors.NoInstallationError(message)
def __init__(self, enforce_openssl_binary_usage: bool = False) -> None: self.broken = False self.use_openssl_binary = enforce_openssl_binary_usage or not ocsp if self.use_openssl_binary: if not util.exe_exists("openssl"): logger.info("openssl not installed, can't check revocation") self.broken = True return # New versions of openssl want -header var=val, old ones want -header var val test_host_format = subprocess.run(["openssl", "ocsp", "-header", "var", "val"], stdout=PIPE, stderr=PIPE, universal_newlines=True, check=False, env=util.env_no_snap_for_external_calls()) if "Missing =" in test_host_format.stderr: self.host_args = lambda host: ["Host=" + host] else: self.host_args = lambda host: ["Host", host]
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf("ctl")): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() # temp_install must be run before creating the NginxParser temp_install(self.mod_ssl_conf) self.parser = parser.NginxParser(self.conf("server-root"), self.mod_ssl_conf) # Set Version if self.version is None: self.version = self.get_version()
def prepare(self): """Prepare the authenticator/installer. :raises .errors.NoInstallationError: If Nginx ctl cannot be found :raises .errors.MisconfigurationError: If Nginx is misconfigured """ # Verify Nginx is installed if not util.exe_exists(self.conf('ctl')): raise errors.NoInstallationError # Make sure configuration is valid self.config_test() # temp_install must be run before creating the NginxParser temp_install(self.mod_ssl_conf) self.parser = parser.NginxParser(self.conf('server-root'), self.mod_ssl_conf) # Set Version if self.version is None: self.version = self.get_version()
def _call(cls, exe): from certbot.util import exe_exists return exe_exists(exe)