def _get_storage_paths() -> List[str]:
    if util.is_windows_os():
        storage_paths = WINDOWS_STORAGE_PATHS
    else:
        storage_paths = LINUX_STORAGE_PATHS

    return storage_paths
Example #2
0
def _parse_user(user):
    if util.is_windows_os():
        raise Exception('This function is not supported on windows')

    row = None
    try:
        try:
            # attempt to treat the 'user' option as a uid
            uid = int(user)
        except ValueError:
            # if that failed, look up the username and get the associated uid
            row = pwd.getpwnam(user)
        else:
            row = pwd.getpwuid(uid)
    except KeyError:
        print("Warning: user \'%s\' does not exist - "
              "duoauthproxy will not drop privileges" % user, file=sys.stderr)
    if row:
        return (row.pw_uid, row.pw_gid)
    return (None, None)
def restrict_permissions(path: str) -> None:
    """
    Restricts the permissions on a file to something reasonably secure on both linux
    and windows

    args:
        path (str): Path to file to secure. Does not work on directories
    """

    if util.is_windows_os():
        import win32api
        import win32con
        if os.path.exists(path):
            existing_attributes = win32api.GetFileAttributes(path)
            win32api.SetFileAttributes(
                path, existing_attributes | win32con.FILE_ATTRIBUTE_HIDDEN)
    else:
        if os.path.isdir(path):
            os.chmod(path, 0o700)
        elif os.path.isfile(path):
            os.chmod(path, 0o600)
Example #4
0
def check_valid_bind_dn_for_auth_type(config, toolbox):
    """
    Checks that bind_dn has been specified if it's required for the specified
    auth_type.
    Args:
        config (ConfigDict): The config object to check
        toolbox (ConfigTestToolbox): Toolbox used to execute the tests

    Returns:
        list of BaseResult
    """
    problems = []
    try:
        if util.is_windows_os():
            auth_type = config.get_enum(
                "auth_type",
                const.AD_AUTH_TYPES_WIN,
                const.AD_AUTH_TYPE_NTLM_V2,
                str.lower,
            )
        else:
            auth_type = config.get_enum(
                "auth_type",
                const.AD_AUTH_TYPES_NIX,
                const.AD_AUTH_TYPE_NTLM_V2,
                str.lower,
            )
        has_bind_dn = toolbox.test_config_has_value(config, "bind_dn")
        if auth_type == const.AD_AUTH_TYPE_PLAIN and not has_bind_dn:
            problems.append(
                UnmetDependency(message="bind_dn is required for "
                                "auth_type %s" % auth_type))
    except ConfigError:
        problems.append(
            SkippedTest(test=check_valid_bind_dn_for_auth_type.__name__,
                        key="auth_type"))

    return problems
Example #5
0
 def _verify_ldap_config_args(self, bind_dn: str, bind_pw: str,
                              auth_type: str, transport_type: str) -> None:
     if util.is_windows_os():
         if auth_type not in const.AD_AUTH_TYPES_WIN:
             raise drpc_exceptions.CallBadArgError(["auth_type"])
     else:
         if auth_type not in const.AD_AUTH_TYPES_NIX:
             raise drpc_exceptions.CallBadArgError(["auth_type"])
     if transport_type not in const.AD_TRANSPORTS:
         raise drpc_exceptions.CallBadArgError(["transport_type"])
     if auth_type != const.AD_AUTH_TYPE_SSPI and (bind_dn == ""
                                                  or bind_pw == ""):
         e = drpc_exceptions.CallError(
             ERR_LDAP_CONFIGURATION_FAILED,
             {
                 "authproxy_configuration_error":
                 "Missing {0} or {1}".format(CONFIG_BIND_USER,
                                             CONFIG_BIND_PASSWORD)
             },
         )
         log.error("{msg}. Error: {error}",
                   msg=ERR_LDAP_CONFIGURATION_FAILED,
                   error=e)
         raise e
Example #6
0
from twisted.logger import (
    FileLogObserver,
    FilteringLogObserver,
    LegacyLogObserverWrapper,
    LogLevel,
    LogLevelFilterPredicate,
    PredicateResult,
    formatEvent,
    jsonFileLogObserver,
    textFileLogObserver,
)
from twisted.python.logfile import LogFile

from duoauthproxy.lib import config_error, log, util

if not util.is_windows_os():
    # This module is not supported on Windows
    import grp
    import pwd

try:
    from twisted.python import syslog
    import syslog as pySyslog
except ImportError:
    syslog = None


def get_observers(main_config, twistd_user, log_group):
    log_debug = main_config.get_bool("debug", False)
    log_to_file = main_config.get_bool("log_file", False)
    log_stdout = main_config.get_bool("log_stdout", False)
Example #7
0
def check_config_values(config, toolbox):
    """
    Validates the values for provided config in the [ad_client] section

    Args:
        config (ConfigDict): The config object to check the optional config for
        toolbox (ConfigTestToolbox): Toolbox used to execute the tests

    Returns:
        list of BaseResult
    """
    problems = []
    config_test_resolver = base.get_basic_config_resolver(toolbox)
    config_dict = {
        "service_account_username":
        toolbox.test_is_string,
        "service_account_password":
        toolbox.test_is_string,
        "service_account_password_protected":
        toolbox.test_is_string,
        "search_dn":
        toolbox.test_dn,
        "security_group_dn":
        toolbox.test_dn,
        "ldap_filter":
        toolbox.test_ldap_filter,
        "timeout":
        toolbox.test_is_int,
        "ssl_ca_certs_file":
        toolbox.test_file_readable,
        "ssl_verify_hostname":
        toolbox.test_is_bool,
        "bind_dn":
        toolbox.test_dn,
        "ntlm_domain":
        toolbox.test_is_string,
        "ntlm_workstation":
        toolbox.test_is_string,
        "port":
        toolbox.test_valid_port,
        "transport":
        functools.partial(toolbox.test_valid_enum,
                          enum=const.AD_TRANSPORTS,
                          transform=str.lower),
        "username_attribute":
        toolbox.test_is_string,
        "at_attribute":
        toolbox.test_is_string,
    }
    if util.is_windows_os():
        config_dict["auth_type"] = functools.partial(
            toolbox.test_valid_enum,
            enum=const.AD_AUTH_TYPES_WIN,
            transform=str.lower)
        config_test_resolver.update(config_dict)
    else:
        config_dict["auth_type"] = functools.partial(
            toolbox.test_valid_enum,
            enum=const.AD_AUTH_TYPES_NIX,
            transform=str.lower)
        config_test_resolver.update(config_dict)
    dynamic_test_resolver = {
        "host": toolbox.test_is_string,
    }
    base.add_dynamic_keys_to_test_resolver(config, config_test_resolver,
                                           dynamic_test_resolver)

    problems += base.run_config_value_checks(config, config_test_resolver)

    problems += base.check_for_unexpected_keys(config, toolbox,
                                               config_test_resolver)

    possible_protected_keys = ["service_account_password_protected"]
    problems += base.check_protected_usage(config, toolbox,
                                           possible_protected_keys)

    return problems