Example #1
0
def pexpect_ask_password(values):
    """
        Interact with process when pexpect found a matching string for password question
        It may Ack previously entered password if several password are asked in the same run.

        This is a mirror from lin_stack.pexpect_ask_password
    """
    process_question = values["child_result_list"][-1]
    try:
        for pattern, auth_realm in values["extra_args"]["auth_realms"]:
            if re.search(pattern, process_question):
                if values["extra_args"]["process_meta"].setdefault(
                        "previous_auth_realm", None) == None:
                    password_mistyped = False
                elif values["extra_args"]["process_meta"][
                        "previous_auth_realm"] != auth_realm:
                    values["extra_args"]["key_chain"].ack_password(
                        values["extra_args"]["process_meta"]
                        ["previous_auth_realm"])
                    password_mistyped = False
                else:
                    password_mistyped = True
                values["extra_args"]["process_meta"][
                    "previous_auth_realm"] = auth_realm
                return values["extra_args"]["key_chain"].get_password(
                    auth_realm, password_mistyped) + "\n"
    except CancelOperationException:
        Output.normal("Operation cancelled.")
        values["extra_args"]["process_meta"]["was_cancelled"] = True
        # Stop current process
        return True
Example #2
0
def main_CLI(args):
    Output.verbose("*" * 10 + " " + str(datetime.datetime.now()) + " " +
                   "*" * 10)
    Output.verbose("ENACdrives " + CONST.FULL_VERSION)
    Output.verbose("Detected OS : " + CONST.OS_DISTRIB + " " + CONST.OS_SYS +
                   " " + CONST.OS_VERSION + "\n")
    Output.debug("LOCAL_USERNAME:"******"LOCAL_GROUPNAME:" + CONST.LOCAL_GROUPNAME)
    Output.debug("LOCAL_UID:" + str(CONST.LOCAL_UID))
    Output.debug("LOCAL_GID:" + str(CONST.LOCAL_GID))
    Output.debug("HOME_DIR:" + CONST.HOME_DIR)
    Output.debug("USER_CONF_FILE:" + CONST.USER_CONF_FILE)
    Output.debug("RESOURCES_DIR:" + CONST.RESOURCES_DIR + "\n")
    Output.debug("IMAGES_DIR:" + CONST.IMAGES_DIR + "\n")
    Output.debug("DEFAULT_MNT_DIR:" + CONST.DEFAULT_MNT_DIR + "\n")

    release_number_validation = validate_release_number()
    if release_number_validation == 'too old':
        Output.warning(CONST.NEED_TO_UPDATE_MSG)
    elif release_number_validation == 'newer':
        Output.normal(CONST.NEWER_THAN_PROD_MSG)
    if args.version:
        Output.cli("ENACdrives " + CONST.FULL_VERSION)
        sys.exit(0)
    ui = CLI(args)
    sys.exit(ui.run())
Example #3
0
 def _cb(is_m):
     # Output.debug("cifs_mount._cb")
     if is_m != self._cache["is_mounted"]:
         Output.normal("--> CIFS_mount {} : {} -> {}".format(self.settings["name"], self._cache["is_mounted"], is_m))
         if is_m:
             cifs_post_mount(self)
         else:
             cifs_post_umount(self)
         self._cache["is_mounted"] = is_m
     if cb is not None:
         cb(is_m)
Example #4
0
def cifs_mount(mount):
    remote = r"\\{server_name}\{server_path}".format(**mount.settings)
    local = mount.settings["Windows_letter"]
    Output.normal("remote={}\nlocal={}".format(remote, local))

    # 1st attempt without password
    try:
        Output.verbose("1st attempt without password")
        win32wnet.WNetAddConnection2(
            win32netcon.RESOURCETYPE_DISK,
            local,
            remote,
        )
        Output.verbose("succeeded")
        cifs_uncache_is_mounted(mount)
        return True
    except pywintypes.error as e:
        if e.winerror == 5:  # (5, 'WNetAddConnection2', 'Access is denied.')
            pass
        elif e.winerror == 86:  # (86, "WNetAddConnection2", "The specified network password is not correct.")
            pass
        elif e.winerror == 1326:  # (1326, "WNetAddConnection2", "Logon failure: unknown user name or bad password.")
            pass
        elif e.winerror == 31:  # (31, 'WNetAddConnection2', 'A device attached to the system is not functioning.')
            pass
        elif e.winerror == 53:  # (53, 'WNetAddConnection2', 'The network path was not found.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 55:  # (55, 'WNetAddConnection2', 'The specified network resource or device is no longer available.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 64:  # (64, 'WNetAddConnection2', 'Le nom réseau spécifié n’est plus disponible.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 67:  # (67, 'WNetAddConnection2', 'The network name cannot be found.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 71:  # (71, 'WNetAddConnection2', 'No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 85:  # (85, 'WNetAddConnection2', 'The local device name is already in use.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 121:  # (121, 'WNetAddConnection2', 'The semaphore timeout period has expired.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1202:  # (1202, 'WNetAddConnection2', 'The local device name has a remembered connection to another network resource.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1208:  # (1208, 'WNetAddConnection2', 'An extended error has occurred.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1219:  # (1219, 'WNetAddConnection2', 'Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1222:  # (1222, 'WNetAddConnection2', 'The network is not present or not started.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1265:  # (1265, 'WNetAddConnection2', 'The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you.')
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1272:  # (1272, 'WNetAddConnection2', "You can't access this shared folder because your organization's security policies block unauthenticated guest access. These policies help protect your PC from unsafe or malicious devices on the network.")
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1311:  # (1311, 'WNetAddConnection2', 'There are currently no logon servers available to service the logon request.')
            # (1311, 'WNetAddConnection2', "We can't sign you in with this credential because your domain isn't available. Make sure your device is connected to your organization's network and try again. If you previously signed in on this device with another credential, you can sign in with that credential.")
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1331:  # (1331, 'WNetAddConnection2', "This user can't sign in because this account is currently disabled.")
            mount.ui.notify_user(e.strerror)
            return False
        elif e.winerror == 1907:  # (1907, 'WNetAddConnection2', "The user's password must be changed before signing in.")
            pass
        else:
            Output.error("failed : {0}".format(e))
            debug_send("mount without password:\n{0}".format(e))

    # 2nd attempt with password
    wrong_password = False
    for _ in range(3):
        try:
            pw = mount.key_chain.get_password(mount.settings["realm"],
                                              wrong_password)
            wrong_password = False
            Output.verbose("New attempt with password")
            win32wnet.WNetAddConnection2(
                win32netcon.RESOURCETYPE_DISK, local, remote, None,
                r"{0}\{1}".format(mount.settings["realm_domain"],
                                  mount.settings["realm_username"]), pw, 0)
            mount.key_chain.ack_password(mount.settings["realm"])
            Output.verbose("succeeded")
            cifs_uncache_is_mounted(mount)
            return True
        except pywintypes.error as e:
            if e.winerror == 86:  # (86, "WNetAddConnection2", "The specified network password is not correct.")
                mount.key_chain.invalidate_if_no_ack_password(
                    mount.settings["realm"])
                wrong_password = True
            elif e.winerror == 1326:  # (1326, "WNetAddConnection2", "Logon failure: unknown user name or bad password.")
                mount.key_chain.invalidate_if_no_ack_password(
                    mount.settings["realm"])
                wrong_password = True
            elif e.winerror == 5:  # (5, 'WNetAddConnection2', 'Access is denied.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 31:  # (31, 'WNetAddConnection2', 'A device attached to the system is not functioning.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 53:  # (53, 'WNetAddConnection2', 'The network path was not found.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 55:  # (55, 'WNetAddConnection2', 'The specified network resource or device is no longer available.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 64:  # (64, 'WNetAddConnection2', 'Le nom réseau spécifié n’est plus disponible.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 67:  # (67, 'WNetAddConnection2', 'The network name cannot be found.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 71:  # (71, 'WNetAddConnection2', 'No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 85:  # (85, 'WNetAddConnection2', 'The local device name is already in use.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 121:  # (121, 'WNetAddConnection2', 'The semaphore timeout period has expired.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1202:  # (1202, 'WNetAddConnection2', 'The local device name has a remembered connection to another network resource.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1208:  # (1208, 'WNetAddConnection2', 'An extended error has occurred.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1219:  # (1219, 'WNetAddConnection2', 'Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1222:  # (1222, 'WNetAddConnection2', 'The network is not present or not started.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1265:  # (1265, 'WNetAddConnection2', 'The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you.')
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1272:  # (1272, 'WNetAddConnection2', "You can't access this shared folder because your organization's security policies block unauthenticated guest access. These policies help protect your PC from unsafe or malicious devices on the network.")
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1311:  # (1311, 'WNetAddConnection2', 'There are currently no logon servers available to service the logon request.')
                # (1311, 'WNetAddConnection2', "We can't sign you in with this credential because your domain isn't available. Make sure your device is connected to your organization's network and try again. If you previously signed in on this device with another credential, you can sign in with that credential.")
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1331:  # (1331, 'WNetAddConnection2', "This user can't sign in because this account is currently disabled.")
                mount.ui.notify_user(e.strerror)
                return False
            elif e.winerror == 1907:  # (1907, 'WNetAddConnection2', "The user's password must be changed before signing in.")
                mount.ui.notify_user(e.strerror)
                return False
            else:
                Output.error("failed : {0}".format(e))
                debug_send("mount with password:\n{0}".format(e))
                mount.ui.notify_user(e.strerror)
        except CancelOperationException:
            Output.verbose("Operation cancelled.")
            return False
    return False
Example #5
0
def get_config():
    # Create cache_dir if not already existent
    if not os.path.exists(CONST.USER_CACHE_DIR):
        os.makedirs(CONST.USER_CACHE_DIR)

    # HARD CODED CONFIG
    default_config = {
        'global': {
         'Linux_CIFS_method': 'gvfs',
         'Linux_gvfs_symlink': False,
         'Linux_mountcifs_dirmode': '0770',
         'Linux_mountcifs_filemode': '0770',
         'Linux_mountcifs_options': 'rw,nobrl,noserverino,iocharset=utf8,sec=ntlm'},
        'CIFS_mount': {},
        'network': {},
        'realm': {},
        'msg': {},
    }
    cfg = default_config

    # USER CONFIG -> get only username from [global]
    user_config = None
    username = None
    try:
        with open(CONST.USER_CONF_FILE, "r") as f:
            user_config = read_config_source(f)
        username = user_config.get("global", {}).get("username", None)
        if username is not None:
            Output.verbose("Loaded username '{}' from User context. ({})".format(username, CONST.USER_CONF_FILE))
        else:
            Output.normal("Username not found in User context. ({})".format(CONST.USER_CONF_FILE))
    except FileNotFoundException:
        Output.normal("Username not found in User context. ({})".format(CONST.USER_CONF_FILE))

    if username is None:
        if CONST.AD_USERNAME is not None:
            username = CONST.AD_USERNAME
            Output.verbose("Loaded username '{}' from environment variables (user in domain '{}').".format(username, CONST.AD_DOMAIN))
            # Save to config file and reload it for after
            save_username(username)
            with open(CONST.USER_CONF_FILE, "r") as f:
                user_config = read_config_source(f)
        else:
            Output.normal("Username not found in environment variables (user not in a domain).")

    # ENACDRIVE SERVER CONFIG (included cache function)
    if username is not None:
        config_url = CONST.CONFIG_URL.format(username=username)
        cache_filename = os.path.join(CONST.USER_CACHE_DIR, hashlib.md5(config_url.encode()).hexdigest())
        try:
            with urllib.request.urlopen(config_url, timeout=CONST.URL_TIMEOUT) as response:
                lines = [bytes_decode(l) for l in response.readlines()]
                # Output.debug("get_config {} : {}".format(config_url, lines))
                s_io = io.StringIO("".join(lines))
                enacdrives_config = read_config_source(s_io)
                merge_configs(cfg, enacdrives_config)
                s_io.seek(0)
                with open(cache_filename, "w") as f:
                    f.writelines(s_io.readlines())
            Output.verbose("Loaded config from ENACdrives server ({})".format(config_url))
        except (socket.timeout, urllib.error.URLError, ConfigException) as e:
            Output.warning("Could not load config ENACdrives server. ({})".format(config_url))
            Output.warning("Got error : {}".format(e))
            try:
                with open(cache_filename, "r") as f:
                    cached_config = read_config_source(f)
                    merge_configs(cfg, cached_config)
                Output.normal("Loaded config from cache file. ({})".format(cache_filename))
            except FileNotFoundException:
                Output.warning("Could not load config from cache file. ({})".format(cache_filename))
    else:
        Output.normal("Skipping config from ENACdrives server (no username).")

    # SYSTEM CONFIG
    try:
        with open(CONST.SYSTEM_CONF_FILE, "r") as f:
            system_config = read_config_source(f)
            merge_configs(cfg, system_config)
        Output.verbose("Loaded config from System context. ({})".format(CONST.SYSTEM_CONF_FILE))
    except FileNotFoundException:
        Output.normal("No config found from System context. ({})".format(CONST.SYSTEM_CONF_FILE))

    # USER CONFIG
    if user_config is not None:
        merge_configs(cfg, user_config)
        Output.verbose("Loaded config from User context. ({})".format(CONST.USER_CONF_FILE))
    else:
        Output.normal("No config found from User context. ({})".format(CONST.USER_CONF_FILE))

    cfg = validate_config(cfg)
    return cfg
Example #6
0
 def notify_user(self, msg):
     Output.normal("Notified User: " + msg)
     msgBox = QtWidgets.QMessageBox()
     msgBox.setText(msg)
     msgBox.exec_()