PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/auth/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/auth/file.py |
""" Provide authentication using local files .. versionadded:: 2018.3.0 The `file` auth module allows simple authentication via local files. Different filetypes are supported, including: 1. Text files, with passwords in plaintext or hashed 2. Apache-style htpasswd files 3. Apache-style htdigest files .. note:: The ``python-passlib`` library is required when using a ``^filetype`` of ``htpasswd`` or ``htdigest``. The simplest example is a plaintext file with usernames and passwords: .. code-block:: yaml external_auth: file: ^filename: /etc/insecure-user-list.txt gene: - .* dean: - test.* In this example the ``/etc/insecure-user-list.txt`` file would be formatted as so: .. code-block:: text dean:goneFishing gene:OceanMan ``^filename`` is the only required parameter. Any parameter that begins with a ``^`` is passed directly to the underlying file authentication function via ``kwargs``, with the leading ``^`` being stripped. The text file option is configurable to work with legacy formats: .. code-block:: yaml external_auth: file: ^filename: /etc/legacy_users.txt ^filetype: text ^hashtype: md5 ^username_field: 2 ^password_field: 3 ^field_separator: '|' trey: - .* This would authenticate users against a file of the following format: .. code-block:: text 46|trey|16a0034f90b06bf3c5982ed8ac41aab4 555|mike|b6e02a4d2cb2a6ef0669e79be6fd02e4 2001|page|14fce21db306a43d3b680da1a527847a 8888|jon|c4e94ba906578ccf494d71f45795c6cb .. note:: The :py:func:`hashutil.digest <salt.modules.hashutil.digest>` execution function is used for comparing hashed passwords, so any algorithm supported by that function will work. There is also support for Apache-style ``htpasswd`` and ``htdigest`` files: .. code-block:: yaml external_auth: file: ^filename: /var/www/html/.htusers ^filetype: htpasswd cory: - .* When using ``htdigest`` the ``^realm`` must be set: .. code-block:: yaml external_auth: file: ^filename: /var/www/html/.htdigest ^filetype: htdigest ^realm: MySecureRealm cory: - .* """ import logging import os # Import salt utils import salt.utils.files import salt.utils.versions log = logging.getLogger(__name__) __virtualname__ = "file" def __virtual__(): return __virtualname__ def _get_file_auth_config(): """ Setup defaults and check configuration variables for auth backends """ config = { "filetype": "text", "hashtype": "plaintext", "field_separator": ":", "username_field": 1, "password_field": 2, } for opt in __opts__["external_auth"][__virtualname__]: if opt.startswith("^"): config[opt[1:]] = __opts__["external_auth"][__virtualname__][opt] if "filename" not in config: log.error( "salt.auth.file: An authentication file must be specified " "via external_auth:file:^filename" ) return False if not os.path.exists(config["filename"]): log.error( "salt.auth.file: The configured external_auth:file:^filename (%s)" "does not exist on the filesystem", config["filename"], ) return False config["username_field"] = int(config["username_field"]) config["password_field"] = int(config["password_field"]) return config def _text(username, password, **kwargs): """ The text file function can authenticate plaintext and digest methods that are available in the :py:func:`hashutil.digest <salt.modules.hashutil.digest>` function. """ filename = kwargs["filename"] hashtype = kwargs["hashtype"] field_separator = kwargs["field_separator"] username_field = kwargs["username_field"] - 1 password_field = kwargs["password_field"] - 1 with salt.utils.files.fopen(filename, "r") as pwfile: for line in pwfile.readlines(): fields = line.strip().split(field_separator) try: this_username = fields[username_field] except IndexError: log.error( "salt.auth.file: username field (%s) does not exist in file %s", username_field, filename, ) return False try: this_password = fields[password_field] except IndexError: log.error( "salt.auth.file: password field (%s) does not exist in file %s", password_field, filename, ) return False if this_username == username: if hashtype == "plaintext": if this_password == password: return True else: # Exceptions for unknown hash types will be raised by hashutil.digest if this_password == __salt__["hashutil.digest"](password, hashtype): return True # Short circuit if we've already found the user but the password was wrong return False return False def _htpasswd(username, password, **kwargs): """ Provide authentication via Apache-style htpasswd files """ from passlib.apache import HtpasswdFile pwfile = HtpasswdFile(kwargs["filename"]) # passlib below version 1.6 uses 'verify' function instead of 'check_password' if salt.utils.versions.version_cmp(kwargs["passlib_version"], "1.6") < 0: return pwfile.verify(username, password) else: return pwfile.check_password(username, password) def _htdigest(username, password, **kwargs): """ Provide authentication via Apache-style htdigest files """ realm = kwargs.get("realm", None) if not realm: log.error( "salt.auth.file: A ^realm must be defined in " "external_auth:file for htdigest filetype" ) return False from passlib.apache import HtdigestFile pwfile = HtdigestFile(kwargs["filename"]) # passlib below version 1.6 uses 'verify' function instead of 'check_password' if salt.utils.versions.version_cmp(kwargs["passlib_version"], "1.6") < 0: return pwfile.verify(username, realm, password) else: return pwfile.check_password(username, realm, password) def _htfile(username, password, **kwargs): """ Gate function for _htpasswd and _htdigest authentication backends """ filetype = kwargs.get("filetype", "htpasswd").lower() try: import passlib kwargs["passlib_version"] = passlib.__version__ except ImportError: log.error( "salt.auth.file: The python-passlib library is required for %s filetype", filetype, ) return False if filetype == "htdigest": return _htdigest(username, password, **kwargs) else: return _htpasswd(username, password, **kwargs) FILETYPE_FUNCTION_MAP = {"text": _text, "htpasswd": _htfile, "htdigest": _htfile} def auth(username, password): """ File based authentication ^filename The path to the file to use for authentication. ^filetype The type of file: ``text``, ``htpasswd``, ``htdigest``. Default: ``text`` ^realm The realm required by htdigest authentication. .. note:: The following parameters are only used with the ``text`` filetype. ^hashtype The digest format of the password. Can be ``plaintext`` or any digest available via :py:func:`hashutil.digest <salt.modules.hashutil.digest>`. Default: ``plaintext`` ^field_separator The character to use as a delimiter between fields in a text file. Default: ``:`` ^username_field The numbered field in the text file that contains the username, with numbering beginning at 1 (one). Default: ``1`` ^password_field The numbered field in the text file that contains the password, with numbering beginning at 1 (one). Default: ``2`` """ config = _get_file_auth_config() if not config: return False auth_function = FILETYPE_FUNCTION_MAP.get(config["filetype"], "text") return auth_function(username, password, **config)