Ejemplo n.º 1
0
 def testSmallFile(self):
     clear_file = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     crypt_file = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     clear_file2 = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     clear_file.write("abc")
     clear_file.close()
     crypt_file.close()
     clear_file2.close()
     encrypt_file(self.password, clear_file.name, crypt_file.name)
     decrypt_file(self.password, crypt_file.name, clear_file2.name)
     self.assertTrue(filecmp.cmp(clear_file.name, clear_file2.name, shallow=False))
     self.assertFalse(filecmp.cmp(clear_file.name, crypt_file.name, shallow=False))
Ejemplo n.º 2
0
 def testOpenSSLCompatabilityDecrypt(self):
     clear_file = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     crypt_file = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     clear_file2 = tempfile.NamedTemporaryFile(delete=False, dir=self.testdir)
     clear_file.write(self.tinydata)
     clear_file.close()
     crypt_file.close()
     clear_file2.close()
     cmd = "openssl enc -md sha256 -aes-256-cbc -pass pass:%s -in %s -out %s" % \
             (self.password, clear_file.name, crypt_file.name)
     os.system(cmd) 
     decrypt_file(self.password, crypt_file.name, clear_file2.name)
     self.assertTrue(filecmp.cmp(clear_file.name, clear_file2.name, shallow=False))
     self.assertFalse(filecmp.cmp(clear_file.name, crypt_file.name, shallow=False))
Ejemplo n.º 3
0
    def onShowPackages(self, event):
        #    Fetch the package list from the last run of the selected backup
        if self.cboBackup.Count == 0:
            return
        #    Get the backup and store
        bname = self.cboBackup.GetStringSelection()
        backup = self.config.backups[bname]
        store = self.config.storage[backup.store].copy()
        #    Figure out the last run
        runs = self.db.runs(bname)
        if len(runs) == 0:
            dlg.Info(self, _("The selected backup has not run"))
            return

        #    last is the most recent
        run = runs[-1]
        #    Get the folder
        folder = os.path.join(bname, run.start_time_str + ' ' + run.type)
        src = os.path.join(folder, const.PackageFile)

        if backup.encrypt:
            src = src + const.EncryptionSuffix
        workfolder = tempfile.mkdtemp()
        store.connect()
        store.copy_from(src, workfolder)
        store.disconnect()
        package_path = os.path.join(workfolder, const.PackageFile)
        if backup.encrypt:
            crypt_path = package_path + const.EncryptionSuffix
            cryptor.decrypt_file(self.config.data_passphrase, crypt_path, package_path)

        package_list = open(package_path).read().split('\n')
        #    Cleanup
        shutil.rmtree(workfolder)

        win = PackageWindow(self, package_list)
Ejemplo n.º 4
0
def recover_run(config, db, backup, store, run):
    wx.Yield()
    
    #    Grab the LOF
    tmp_dir = tempfile.mkdtemp()
    try:
        #    Create encrypted and clear pathnames
        lof_remote = os.path.join(backup.name, run, const.LOFFile)
        lof_remote_enc = os.path.join(backup.name, run, const.LOFFile + const.EncryptionSuffix)
        #    Look at the remote site - is it encrypted or not?
        if store.exists(lof_remote):
            src = lof_remote
            encrypted = False
        elif store.exists(lof_remote_enc):
            src = lof_remote_enc
            encrypted = True
        else:
            raise Exception(_("Backup '{backup}' run '{run}' is corrupt").format(backup=backup.name, run=run))

        #    Get the LOF file
        store.copy_from(src, tmp_dir)
        lof_file = os.path.join(tmp_dir, const.LOFFile)
        #    Decrypt if required.
        if encrypted:
            decrypt_file(config.data_passphrase, lof_file + const.EncryptionSuffix, lof_file)

        #    Now we open and walk through the ZIP file.
        lof = gzip.GzipFile(lof_file, "rb")
        folder = ""
        nfiles = 0 # the config file
        nfolders = 0
        file_sizes = 0
        while True:
            #    Get the next line, and remove the CR
            line = lof.readline()
            if line is None or line == "":
                break
            if line[-1:] == '\n':
                line = line[:-1]
            log.debug("Next Line", line)
            if line == "":
                #    New folder on the next line
                line = lof.readline()
                if line is None or line == "":
                    break
                if line[-1:] == '\n':
                    line = line[:-1]
                folder = utils.unescape(line)
                nfolders += 1
            else:
                parts = line.split(",")
                type = parts[0]
                name = utils.unescape(parts[1])
                path = os.path.join(folder, name)
                path = utils.path_to_unicode(path)
                if type == "F" or type == "D":
                    mod_time = parts[2]
                    size = parts[3]
                    db.fs_saved(path, mod_time, size, type)
                    if type == 'F':
                        nfiles += 1
                        file_sizes += int(size)
                elif type == 'X':
                    db.fs_deleted(path)
                else:
                    raise Exception(_("Corrupt type in file list"))
            wx.Yield()
        #    To calculate the amount of size, we need to see how big the data files are.
        run_dir = os.path.join(backup.name, run)
        size = 0
        log.debug("Checking files sizes")
        files = store.list(run_dir)
        for file in files:
            size += store.size(os.path.join(run_dir, file))
            wx.Yield()

    finally:
        shutil.rmtree(tmp_dir)
    log.trace("Completed recover run: ", size, file_sizes, nfiles, nfolders)
    return size, file_sizes, nfiles, nfolders
Ejemplo n.º 5
0
def wiz_execute(wiz):
    #    Connect
    if wiz.fields["storagetype"].value == _("Local Folder"):
        store = FolderStore("store", 0, False, wiz.fields["folderpath"].value)
    elif wiz.fields["storagetype"].value == _("FTP Server"):
        server = wiz.fields["ftpserver"].value
        login = wiz.fields["ftplogin"].value
        password = wiz.fields["ftppassword"].value
        root = wiz.fields["ftproot"].value
        sftp = wiz.fields["sftp"].value
        store = FTPStore("store", 0, False, server, root, login, password, sftp)
    elif wiz.fields["storagetype"].value == _("DropBox"):
        login = wiz.fields["dblogin"].value
        password = wiz.fields["dbpassword"].value
        root = wiz.fields["dbroot"].value
        store = DropBoxStore("store", 0, False, root, login, password)
    elif wiz.fields["storagetype"].value == _("Server Share"):
        mountcmd = wiz.fields["mountcmd"].value
        umountcmd = wiz.fields["umountcmd"].value
        shareroot = wiz.fields["shareroot"].value
        store = ShareStore("store", 0, False, shareroot, mountcmd, umountcmd)
    else:
        raise Exception("Internal error: bad store type")
    log.debug("Store = ", store)
    
    #    In case we need to revert our config later
    orig_config = Config.get_config()
    try:
        store.connect()

        folders = []
        #    List all backups
        backups = store.list(".")
        for backup in backups:
            #    Make sure its not a system folder
            if backup[0] != "_":
                try:
                    runs = store.list(backup + "/")
                    for run in runs:
                        folders.append((backup, run))
                except:
                    pass

        log.debug("Folders", folders)
        if len(folders) == 0:
            raise Exception(_("There are no backup runs in this store"))
        #    Sort them based on the path name
        folders.sort(key=lambda item: item[1], reverse=True)
        #    Now the first item is the one to use (as it is the most recent).
        backupname, backuprun = folders[0]
        config = os.path.join(backupname, backuprun, const.ConfigName)
        configenc = config + const.EncryptionSuffix
        #    Check if the config exists.
        if store.exists(config):
            src = config
            encrypted = False
        elif store.exists(configenc):
            src = configenc
            encrypted = True
        else:
            raise Exception(_("The backup runs are missing or corrupt (no config files)"))

        if not encrypted:
            store.get(src, const.ConfigDir+os.sep)
        else:
            #    Fetch the file.
            enc_file = const.ConfigFile + const.EncryptionSuffix
            clear_file = const.ConfigFile
            store.get(src, const.ConfigDir+os.sep)

            #    ENCRYPTED
            bad = True  #    keep going until we get a good password
            while bad:
                password = GetPassword(wiz, backupname, backuprun)
                if password == None:
                    #    User is quitting
                    return

                #    Lets check the file is good.
                try:
                    log.debug("Decrypting", enc_file, clear_file, password)
                    ret = cryptor.decrypt_file(password, enc_file, clear_file)
                    log.debug("Return from decrypt", ret)
                    if ret != 0:
                        raise Exception(_("Failed encryption"))
                    bad = False
                    if os.path.exists(enc_file):
                        os.remove(enc_file)
                    #    Looks like this password is a good one. 
                except:
                    log.info("Invalid backup password")
                    dlg.Warn(wiz, _("Invalid password. Please enter the correct backup password."))
                    os.remove(clear_file)
                    #    Revert the old config
                    orig_config.save()


        dlg.Info(wiz, _("Your configuration has been restored.\nClick OK to restart the UI..."), _("Restore"))

        python = sys.executable
        log.debug("Starting:", const.UIProgram)
        subprocess.Popen(const.UIProgram)
        app.quit()

    except Exception as e:
        dlg.Warn(wiz, str(e), _("Configuration restore failed"))
    finally:
        store.disconnect()