Exemple #1
0
def compress(srcPath, tgtPath): # #Note: shutil.make_archive isn't used, due to its forcing of the zip extension and due to the need for maintaing a compression standard.
	if not exists(srcPath):
		raise('No such path: %s' % srcPath)

	ensureParent(tgtPath)

	from zipfile import ZipFile, ZIP_DEFLATED

	ZipFileObj = ZipFile(tgtPath, 'w', ZIP_DEFLATED)

	cwd = os.getcwd() # The CWD circus is to reduce the relpath calls.

	if isContainer(srcPath):
		os.chdir(srcPath)

		for root, dummy1, Files in os.walk('.', followlinks=True):
			for file in Files:
				ZipFileObj.write(pathJoin(root, file))

	else:
		dir, name = pathSplit(srcPath)
		os.chdir(dir)

		ZipFileObj.write(name)

	os.chdir(cwd)

	ZipFileObj.close()
Exemple #2
0
def mkdirs(SFTP, remotePath):
	currentPath = remotePath

	Skipped = []

	while True:
		err = forgive(lambda: SFTP.mkdir(currentPath, 511)) # #Note: Existense isn't checked for to reduce the number of remote calls.

		if err:
			if err.errno is None: # The dir exists.
				return

			elif not isinstance(err, IOError): # #Pending: Check: Permission errors could result in infinite loops.
				raise err

			else:
				# Try to create the parent path.
				currentPath, skipped = pathSplit(currentPath)
				Skipped.append(skipped)

				if not currentPath or currentPath == '/':
					raise Exception('Failed to create the dir: %s' % remotePath)

		else:
			if not Skipped:
				break

			else:
				currentPath += '/%s' % Skipped.pop(0)
def LoadFolder(arg):
    global fdrOpen, FilesIndex

    fdrOpen = fd.askdirectory()
    WindowTitle(pathSplit(fdrOpen)[1])
    CategoriesShow()
    pathLVL1(0)
    FilesIndex = 0
    TextInsertion(pathOrigin, pathLocal, 0)
    TextInsertion(pathOrigin, pathLocal, 0)
    FilesShow(pathOrigin)
def LocalStep(localPath, Index, step, next_step_set):
    try:
        sortedListdir = sorted(listdir(localPath))[Index]
        if sortedListdir != 'titles.md':
            fl = oPen(localPath + sortedListdir, "r", encoding='UTF-8')
            for line in fl.readlines():
                step.wait()
                step.clear()

                swFilter = regexSub(regexSwearPattern, SwearFilter,
                                    line.rstrip()).split(" ", maxsplit=1)
                try:
                    if swFilter[1] != ostepSWfilter:
                        # TableLocal = '[code][b] ▫ ' + swFilter[1] + '[/b][/code][/code]\n'
                        # TableLocal = '[code][b] ▫ ' + swFilter[1] + '[/b][/code][/th][/tr][/table]\n'
                        # TableLocal = '[tr][th][b] ▫ ' + swFilter[1] + '[/b][/th][/tr][/table][/code]\n'
                        TableLocal = '[hr][/hr][h3] ▫ [b]' + swFilter[
                            1] + '[/b][/h3][/code]'
                    else:
                        # TableLocal = '[/code]\n'
                        # TableLocal = '[/th][/tr][/table]\n'
                        # TableLocal = '[/table][/code]\n'
                        TableLocal = '[/code]'

                    tempf.write(str(TableLocal))
                except:
                    tempf.write('\nerror at: ' + localPath + sortedListdir +
                                ' -|- ' + line.rstrip() + '\n')

                next_step_set.set()
            fl.close()
        else:
            print('BREAK! Found titles file at ' + pathSplit(localPath)[1])
            # break
    except FileNotFoundError:
        quit(1)
Exemple #5
0
def start():
    global inputFile, outputFile, password, ad, kept
    global working, gMode, headerRsc, draggedFiles
    global dragFolderPath
    dummy.focus()
    reedsolo = False
    chunkSize = 2**20

    # Decide if encrypting or decrypting
    if ".pcv" not in inputFile:
        mode = "encrypt"
        gMode = "encrypt"
        outputFile = inputFile + ".pcv"
        reedsolo = rs.get() == 1
    else:
        mode = "decrypt"
        gMode = "decrypt"
        # Check if Reed-Solomon was enabled by checking for "+"
        test = open(inputFile, "rb")
        decider = test.read(1).decode("utf-8")
        test.close()
        if decider == "+":
            reedsolo = True
        # Decrypted output is just input file without the extension
        outputFile = inputFile[:-4]

    # Check if file already exists (getsize() throws error if file not found)
    try:
        getsize(outputFile)
        force = messagebox.askyesno("Warning", overwriteNotice)
        dummy.focus()
        if force != 1:
            return
    except:
        pass

    # Disable inputs and buttons while encrypting/decrypting
    disableAllInputs()

    # Make sure passwords match
    if passwordInput.get() != cpasswordInput.get() and mode == "encrypt":
        resetEncryptionUI()
        statusString.set("Passwords don't match.")
        return

    # Set progress bar indeterminate
    progress.config(mode="indeterminate")
    progress.start(15)
    statusString.set(rscNotice)

    # Create Reed-Solomon object
    if reedsolo:
        # 13 bytes per 128 bytes, ~10% larger output file
        rsc = RSCodec(13)

    # Compress files together if user dragged multiple files
    if draggedFiles:
        statusString.set(compressingNotice)
        tmp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        if dragFolderPath:
            zfName = Path(dragFolderPath).parent.absolute()
            zfName = pathJoin(zfName, tmp + ".zip")
        else:
            zfName = Path(draggedFiles[0]).parent.absolute()
            zfName = pathJoin(zfName, tmp + ".zip")
        zf = ZipFile(zfName, "w")
        for i in draggedFiles:
            if dragFolderPath:
                nameOffset = len(dragFolderPath)
                zf.write(i, i[nameOffset:])
            else:
                zf.write(i, pathSplit(i)[1])
        zf.close()
        inputFile = zfName
        outputFile = zfName + ".pcv"
        outputPath = dirname(outputFile)

    # Set and get some variables
    working = True
    headerBroken = False
    reedsoloFixedCount = 0
    reedsoloErrorCount = 0
    dummy.focus()
    password = passwordInput.get().encode("utf-8")
    ad = adArea.get("1.0", tkinter.END).encode("utf-8")
    wipe = erase.get() == 1

    # Open files
    fin = open(inputFile, "rb")
    if reedsolo and mode == "decrypt":
        # Move pointer one forward
        fin.read(1)
    fout = open(outputFile, "wb+")
    if reedsolo and mode == "encrypt":
        # Signal that Reed-Solomon was enabled with a "+"
        fout.write(b"+")

    # Generate values for encryption if encrypting
    if mode == "encrypt":
        salt = urandom(16)
        nonce = urandom(24)

        # Reed-Solomon-encode metadata
        ad = bytes(headerRsc.encode(ad))
        # Write the metadata to output
        tmp = str(len(ad)).encode("utf-8")
        # Right-pad with "+"
        while len(tmp) != 10:
            tmp += b"+"
        tmp = bytes(headerRsc.encode(tmp))
        fout.write(tmp)  # Length of metadata
        fout.write(ad)  # Metadata (associated data)

        # Write zeros as placeholders, come back to write over it later.
        # Note that 128 extra Reed-Solomon bytes are added
        fout.write(b"0" * 192)  # SHA3-512 of encryption key
        fout.write(b"0" * 192)  # CRC of file
        fout.write(b"0" * 144)  # Poly1305 tag
        # Reed-Solomon-encode salt and nonce
        fout.write(bytes(headerRsc.encode(salt)))  # Argon2 salt
        fout.write(bytes(headerRsc.encode(nonce)))  # ChaCha20 nonce

    # If decrypting, read values from file
    else:
        # Move past metadata into actual data
        tmp = fin.read(138)
        if tmp[0] == 43:
            tmp = tmp[1:] + fin.read(1)
        tmp = bytes(headerRsc.decode(tmp)[0])
        tmp = tmp.replace(b"+", b"")
        adlen = int(tmp.decode("utf-8"))
        fin.read(int(adlen))

        # Read the salt, nonce, etc.
        cs = fin.read(192)
        crccs = fin.read(192)
        digest = fin.read(144)
        salt = fin.read(144)
        nonce = fin.read(152)
        # Reed-Solomon-decode each value
        try:
            cs = bytes(headerRsc.decode(cs)[0])
        except:
            headerBroken = True
            cs = cs[:64]
        try:
            crccs = bytes(headerRsc.decode(crccs)[0])
        except:
            headerBroken = True
            crccs = crccs[:64]
        try:
            digest = bytes(headerRsc.decode(digest)[0])
        except:
            headerBroken = True
            digest = digest[:16]
        try:
            salt = bytes(headerRsc.decode(salt)[0])
        except:
            headerBroken = True
            salt = salt[:16]
        try:
            nonce = bytes(headerRsc.decode(nonce)[0])
        except:
            headerBroken = True
            nonce = nonce[:24]

        if headerBroken:
            if keep.get() != 1:
                statusString.set(veryCorruptedNotice)
                fin.close()
                fout.close()
                remove(outputFile)
                # Reset UI
                resetDecryptionUI()
                return
            else:
                kept = "badlyCorrupted"

    # Show notice about key derivation
    statusString.set(derivingNotice)

    # Derive argon2id key
    key = hash_secret_raw(
        password,
        salt,
        time_cost=8,  # 8 iterations
        memory_cost=2**20,  # 2^20 Kibibytes (1GiB)
        parallelism=8,  # 8 parallel threads
        hash_len=32,
        type=Type.ID)

    # Key deriving done, set progress bar determinate
    progress.stop()
    progress.config(mode="determinate")
    progress["value"] = 0

    # Compute hash of derived key
    check = sha3_512.new()
    check.update(key)
    check = check.digest()

    # If decrypting, check if key is correct
    if mode == "decrypt":
        # If key is incorrect...
        if not compare_digest(check, cs):
            if not headerBroken:
                statusString.set(passwordNotice)
                fin.close()
                fout.close()
                remove(outputFile)
                # Reset UI
                resetDecryptionUI()
                return

    # Create XChaCha20-Poly1305 object
    cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)
    # Cyclic redundancy check for file corruption
    crc = sha3_512.new()

    # Amount of data encrypted/decrypted, total file size, starting time
    done = 0
    total = getsize(inputFile)

    # If secure wipe enabled, create a wiper object

    # Keep track of time because it flies...
    startTime = datetime.now()
    previousTime = datetime.now()

    # Continously read file in chunks of 1MB
    while True:
        if mode == "decrypt" and reedsolo:
            # Read a chunk plus Reed-Solomon recovery bytes
            piece = fin.read(1104905)
        else:
            piece = fin.read(chunkSize)

        # If EOF
        if not piece:
            if mode == "encrypt":
                # Get the cipher MAC tag (Poly1305)
                digest = cipher.digest()
                fout.flush()
                fout.close()
                fout = open(outputFile, "r+b")
                # Compute the offset and seek to it (unshift "+")
                rsOffset = 1 if reedsolo else 0
                fout.seek(138 + len(ad) + rsOffset)
                # Write hash of key, CRC, and Poly1305 MAC tag
                fout.write(bytes(headerRsc.encode(check)))
                fout.write(bytes(headerRsc.encode(crc.digest())))
                fout.write(bytes(headerRsc.encode(digest)))
            else:
                # If decrypting, verify CRC
                crcdg = crc.digest()
                if not compare_digest(crccs, crcdg):
                    # File is corrupted
                    statusString.set(corruptedNotice)
                    progress["value"] = 100
                    fin.close()
                    fout.close()
                    # If keep file not checked...
                    if keep.get() != 1:
                        remove(outputFile)
                        # Reset UI
                        resetDecryptionUI()
                        del fin, fout, cipher, key
                        return
                    else:
                        if not kept:
                            kept = "corrupted"
                # Next, verify MAC tag (Poly1305)
                try:
                    # Throws ValueError if incorrect Poly1305
                    cipher.verify(digest)
                except:
                    if not reedsoloErrorCount and not headerBroken:
                        # File is modified
                        statusString.set(modifiedNotice)
                        progress["value"] = 100
                        fin.close()
                        fout.close()
                        # If keep file not checked...
                        if keep.get() != 1:
                            remove(outputFile)
                            # Reset UI
                            resetDecryptionUI()
                            del fin, fout, cipher, key
                            return
                        else:
                            if not kept:
                                kept = "modified"
            break

        # Encrypt/decrypt chunk and update CRC
        if mode == "encrypt":
            # Encrypt piece
            data = cipher.encrypt(piece)
            # Update checksum
            crc.update(data)
            if reedsolo:
                # Encode using Reed-Solomon if user chooses
                data = bytes(rsc.encode(data))
        else:
            # Basically encrypting but in reverse
            if reedsolo:
                try:
                    data, _, fixed = rsc.decode(piece)
                except ReedSolomonError:
                    # File is really corrupted
                    if not reedsoloErrorCount:
                        if keep.get() != 1:
                            statusString.set(veryCorruptedNotice)
                            progress["value"] = 100
                    # If keep file not checked...
                    if keep.get() != 1:
                        fin.close()
                        fout.close()
                        remove(outputFile)
                        # Reset UI
                        resetDecryptionUI()
                        del fin, fout, cipher, key
                        return
                    else:
                        kept = "badlyCorrupted"
                        # Attempt to recover badly corrupted data
                        data = b""
                        piece = piece[:-13]
                        counter = 0
                        while True:
                            # Basically just strip the Reed-Solomon bytes
                            # and return the original non-encoded data
                            if counter < 1104905:
                                data += piece[counter:counter + 242]
                                counter += 255  # 255 bytes, 242 original
                            else:
                                break
                        fixed = bytearray()
                        reedsoloErrorCount += 1
                data = bytes(data)
                reedsoloFixedCount += len(fixed)
                crc.update(data)
                data = cipher.decrypt(data)
            else:
                crc.update(piece)
                data = cipher.decrypt(piece)

        # Calculate speed, ETA, etc.
        first = False
        elapsed = (datetime.now() - previousTime).total_seconds() or 0.0001
        sinceStart = (datetime.now() - startTime).total_seconds() or 0.0001
        previousTime = datetime.now()
        # Prevent divison by zero
        if not elapsed:
            elapsed = 0.1**6
        percent = done * 100 / total
        progress["value"] = percent
        rPercent = round(percent)
        speed = (done / sinceStart) / 10**6
        # Prevent divison by zero
        if not speed:
            first = True
            speed = 0.1**6
        rSpeed = str(round(speed, 2))
        # Right-pad with zeros to large prevent layout shifts
        while len(rSpeed.split(".")[1]) != 2:
            rSpeed += "0"
        eta = round((total - done) / (speed * 10**6))
        # Seconds to minutes if seconds more than 59
        if eta >= 60:
            eta = f"{eta//60}m {eta%60}"
        if isinstance(eta, int) or isinstance(eta, float):
            if eta < 0:
                eta = 0
        # If it's the first round and no data/predictions yet...
        if first:
            statusString.set("...% at ... MB/s (ETA: ...s)")
        else:
            # Update status
            info = f"{rPercent}% at {rSpeed} MB/s (ETA: {eta}s)"
            if reedsolo and mode == "decrypt" and reedsoloFixedCount:
                eng = "s" if reedsoloFixedCount != 1 else ""
                info += f", fixed {reedsoloFixedCount} corrupted byte{eng}"
            if reedsolo and mode == "decrypt" and reedsoloErrorCount:
                info += f", {reedsoloErrorCount} MB unrecoverable"
            statusString.set(info)

        # Increase done and write to output
        done += 1104905 if (reedsolo and mode == "decrypt") else chunkSize
        fout.write(data)

    # Flush outputs, close files
    if not kept:
        fout.flush()
        fsync(fout.fileno())
    fout.close()
    fin.close()

    # Securely wipe files as necessary
    if wipe:
        progress.config(mode="indeterminate")
        progress.start(15)
        if draggedFiles:
            for i in draggedFiles:
                print("===============" + i)
                secureWipe(i)
        secureWipe(inputFile)
    else:
        if draggedFiles:
            remove(inputFile)

    # Show appropriate notice if file corrupted or modified
    if not kept:
        if mode == "encrypt":
            output = inputFile.split("/")[-1] + ".pcv"
        else:
            output = inputFile.split("/")[-1].replace(".pcv", "")
        statusString.set(f"Completed. (Output: {output})")
        # Show Reed-Solomon stats if it fixed corrupted bytes
        if mode == "decrypt" and reedsolo and reedsoloFixedCount:
            statusString.set(
                f"Completed with {reedsoloFixedCount} bytes fixed." +
                f" (Output: {output})")
    else:
        if kept == "modified":
            statusString.set(kModifiedNotice)
        elif kept == "corrupted":
            statusString.set(kCorruptedNotice)
        else:
            statusString.set(kVeryCorruptedNotice)

    status.config(cursor="hand2")
    status.bind("<Button-1>", lambda e: print(outputPath))

    # Reset variables and UI states
    resetUI()
    inputFile = ""
    outputFile = ""
    password = ""
    ad = ""
    kept = False
    working = False
    draggedFiles = False
    dragFolderPath = False

    # Wipe keys for safety
    del fin, fout, cipher, key
Exemple #6
0
def work():
    global inputFile, outputFile, working, mode, rs13, rs128, reedsolo
    global done, stopUpdating, startTime, previousTime, onlyFiles
    global onlyFolders, allFiles, reedsoloFixed, reedsoloErrors
    disableAllInputs()
    dummy.focus()

    # Set and get some variables
    kept = False
    shouldKeep = keep.get() == 1
    shouldErase = erase.get() == 1
    reedsolo = rs.get() == 1
    working = True
    stopUpdating = False
    headerBroken = False
    reedsoloFixed = 0
    reedsoloErrors = 0
    password = passwordInput.get().encode("utf-8")
    metadata = metadataInput.get("1.0", tkinter.END).encode("utf-8")
    cancelBtn["state"] = "normal"
    cancelBtn.config(cursor="hand2")

    # Decide if encrypting or decrypting
    if mode == "encrypt":
        outputFile = outputInput.get() + ".pcv"
    else:
        outputFile = outputInput.get()

    # Set progress bar indeterminate
    progress.config(mode="indeterminate")
    progress.start(15)

    # Compress files together if necessary
    if onlyFiles or allFiles:
        statusString.set(strings[1])
        tmp = outputFile[:-4]
        if onlyFiles:
            zfPath = Path(onlyFiles[0]).parent.absolute()
        else:
            zfPath = Path(dirname(allFiles[0])).parent.absolute()
        zfOffset = len(str(zfPath))
        zfName = pathJoin(zfPath, tmp)
        zf = ZipFile(zfName, "w")
        for i in allFiles:
            zf.write(i, i[zfOffset:])
        for i in onlyFiles:
            zf.write(i, pathSplit(i)[1])
        zf.close()
        inputFile = zfName
        outputFile = zfName + ".pcv"
        outputPath = dirname(outputFile)

    # Open files
    try:
        fin = open(inputFile, "rb")
    except:
        setEncryptionUI()
        statusString.set(strings[16])
        return

    # If encrypting, generate values for encryption
    if mode == "encrypt":
        salt = urandom(16)  # Argon2 salt
        nonce = urandom(24)  # XChaCha20 nonce
        fout = open(outputFile, "wb+")

        # Indicate Reed-Solomon with "+"
        if reedsolo:
            fout.write(rs128.encode(b"+"))
        else:
            fout.write(rs128.encode(b"-"))

        # Encode metadata and length of metadata
        metadata = rs128.encode(metadata)
        tmp = len(metadata)
        tmp = f"{tmp:+<10}"
        tmp = rs128.encode(tmp.encode("utf-8"))

        # Write to file
        fout.write(tmp)
        fout.write(metadata)
        fout.write(rs128.encode(salt))  # Argon2 salt
        fout.write(rs128.encode(nonce))  # XChaCha20 nonce
        fout.write(b"0" * 192)  # Hash of key
        fout.write(b"0" * 144)  # Poly1305 MAC
        fout.write(b"0" * 160)  # BLAKE3 CRC

    # If decrypting, read values from file
    else:
        tmp = fin.read(129)
        try:
            if bytes(rs128.decode(tmp)[0]) == b"+":
                reedsolo = True
            else:
                reedsolo = False
        except:
            setDecryptionUI()
            statusString.set(strings[21])
            return

        metadataLength = fin.read(138)
        metadataLength = bytes(rs128.decode(metadataLength)[0])
        metadataLength = metadataLength.replace(b"+", b"")
        fin.read(int(metadataLength.decode("utf-8")))

        # Read values
        salt = fin.read(144)
        nonce = fin.read(152)
        keycs = fin.read(192)
        maccs = fin.read(144)
        crccs = fin.read(160)

        # Try to decode each value, increase Reed-Solomon errors fixed if needed
        try:
            salt, _, fixed = rs128.decode(salt)
            salt = bytes(salt)
            reedsoloFixed += len(fixed)
        except:
            headerBroken = True
            salt = salt[:16]
        try:
            nonce, _, fixed = rs128.decode(nonce)
            nonce = bytes(nonce)
            reedsoloFixed += len(fixed)
        except:
            headerBroken = True
            nonce = nonce[:24]
        try:
            keycs, _, fixed = rs128.decode(keycs)
            keycs = bytes(keycs)
            reedsoloFixed += len(fixed)
        except:
            headerBroken = True
            keycs = keycs[:64]
        try:
            maccs, _, fixed = rs128.decode(maccs)
            maccs = bytes(maccs)
            reedsoloFixed += len(fixed)
        except:
            headerBroken = True
            maccs = maccs[:16]
        try:
            crccs, _, fixed = rs128.decode(crccs)
            crccs = bytes(crccs)
            reedsoloFixed += len(fixed)
        except:
            headerBroken = True
            crccs = crccs[:32]

        # If the header is broken...
        if headerBroken:
            # Stop if user chose not to keep broken output
            if not shouldKeep:
                statusString.set(strings[4])
                fin.close()
                try:
                    remove(outputFile)
                except:
                    pass
                setDecryptionUI()
                return
            else:
                kept = "badlyCorrupted"

    statusString.set(strings[9])

    # Generate Argon2d key from master password
    key = hash_secret_raw(password,
                          salt,
                          time_cost=8,
                          memory_cost=2**20,
                          parallelism=8,
                          hash_len=32,
                          type=argonType.D)

    # Stop the indeterminate progress bar and set determinate
    progress.stop()
    progress.config(mode="determinate")
    progress["value"] = 0

    # Hash of the derived Argon2 key
    check = SHA3_512.new(data=key).digest()

    # Check if password is correct
    if mode == "decrypt":
        if not compare_digest(check, keycs):
            # If header isn't broken...
            if not headerBroken:
                # Tell user password is incorrect
                statusString.set(strings[2])
                fin.close()
                setDecryptionUI()
                return
        fout = open(outputFile, "wb+")

    crc = blake3()  # Blake3 CRC
    cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)  # XChaCha20

    # Variables for calculating speeds, etc.
    done = 0
    total = getsize(inputFile)
    startTime = datetime.now()
    previousTime = datetime.now()

    # Update progress bar, etc. in another thread
    Thread(target=updateStats, daemon=True, args=(total, )).start()

    # Start the encryption/decryption process
    while True:
        # Check if cancel button pressed
        if not working:
            fin.close()
            fout.close()
            remove(outputFile)
            if mode == "encrypt":
                setEncryptionUI()
            else:
                setDecryptionUI()
            statusString.set("Operation canceled by user.")
            dummy.focus()
            return

        # Read from file, read extra if Reed-Solomon was enabled
        if mode == "decrypt" and reedsolo:
            piece = fin.read(1104905)
        else:
            piece = fin.read(2**20)

        # End of file
        if not piece:
            break

        # Encrypt, etc.
        if mode == "encrypt":
            data = cipher.encrypt(piece)
            crc.update(data)
            if reedsolo:
                data = bytes(rs13.encode(data))

        # Decrypt, etc.
        else:
            if reedsolo:
                try:
                    data, _, fixed = rs13.decode(piece)
                except ReedSolomonError:
                    # File is really corrupted
                    if not reedsoloErrors and not shouldKeep:
                        stopUpdating = True
                        statusString.set(strings[4])
                        fin.close()
                        fout.close()
                        remove(outputFile)
                        setDecryptionUI()
                        return

                    # Attempt to recover badly corrupted data
                    kept = "badlyCorrupted"
                    data = b""
                    piece = piece[:-13]
                    counter = 0
                    while True:
                        # Basically just strip off the Reed-Solomon bytes
                        if counter < 1104905:
                            data += piece[counter:counter + 242]
                            counter += 255  # 242 bytes + 13 Reed-Solomon
                        else:
                            break
                    fixed = bytearray()
                    reedsoloErrors += 1

                reedsoloFixed += len(fixed)
                crc.update(data)
                data = cipher.decrypt(data)

            else:
                crc.update(piece)
                data = cipher.decrypt(piece)

        # Write the data, increase the amount done
        fout.write(data)
        done += 1104905 if (mode == "decrypt" and reedsolo) else 2**20

    # Stop UI updater from overwriting potential messages
    stopUpdating = True

    # Encryption is done, write appropriate values to file
    if mode == "encrypt":
        fout.flush()
        fout.close()
        fout = open(outputFile, "r+b")
        fout.seek(129 + 138 + len(metadata) + 144 + 152)
        fout.write(rs128.encode(check))
        fout.write(rs128.encode(cipher.digest()))
        fout.write(rs128.encode(crc.digest()))

    # Decryption is done, check for integrity and authenticity
    else:
        # File is corrupted
        if not compare_digest(crccs, crc.digest()):
            statusString.set(strings[3])
            fin.close()
            fout.close()
            if keep.get() != 1:
                remove(outputFile)
                setDecryptionUI()
                return
            else:
                if not kept:
                    kept = "corrupted"
        try:
            cipher.verify(maccs)
        except:
            if not reedsoloErrors and not headerBroken:
                # File is modified
                statusString.set(strings[5])
                fin.close()
                fout.close()
                # If keep file not checked...
                if keep.get() != 1:
                    remove(outputFile)
                    # Reset UI
                    setDecryptionUI()
                    return
                else:
                    if not kept:
                        kept = "modified"

    # Flush outputs, close files
    if not kept:
        fout.flush()
        fsync(fout.fileno())
    fout.close()
    fin.close()

    # Securely wipe files as necessary
    if shouldErase:
        if onlyFolders:
            for i in onlyFolders:
                secureWipe(i)
        if onlyFiles:
            for i in range(len(onlyFiles)):
                statusString.set(strings[12] + f" ({i}/{len(onlyFiles)}")
                progress["value"] = i / len(onlyFiles)
                secureWipe(onlyFiles[i])
        secureWipe(inputFile)

    # Secure wipe not enabled
    else:
        # Remove temporary zip file if created
        if allFiles or onlyFiles:
            remove(inputFile)

    # Show appropriate notice if file corrupted or modified
    arrow = "" if platform.system() == "Darwin" else "🡪"
    if not kept:
        statusString.set(f"Completed. (Click here to show output {arrow})")
        # Show Reed-Solomon stats if it fixed corrupted bytes
        if mode == "decrypt" and reedsoloFixed:
            tmp = "s" if reedsoloFixed != 1 else ""
            statusString.set(f"Completed with {reedsoloFixed} byte{tmp}" +
                             f" fixed. (Click here to show output {arrow})")
    else:
        if kept == "modified":
            statusString.set(strings[7])
        elif kept == "corrupted":
            statusString.set(strings[6])
        else:
            statusString.set(strings[8])

    status.config(cursor="hand2")

    # A little hack to prevent reference nonsense
    output = "".join([i for i in outputFile])

    # Bind the output file to the status label
    if platform.system() == "Windows":
        status.bind("<Button-1>",
                    lambda e: showOutput(output.replace("/", "\\")))
    else:
        status.bind("<Button-1>", lambda e: showOutput(output))

    # Reset variables and UI states
    resetUI()
    inputFile = ""
    outputFile = ""
    allFiles = []
    onlyFolders = []
    onlyFiles = []
    working = False
Exemple #7
0
'''


def SwearFilter(Swear):
    if len(Swear[0]) - 2 <= 2:
        return '⚹' * (len(Swear[0]) - 2)
    elif len(Swear[0]) - 2 <= 5:
        return Swear[0][1:2] + '*' * (len(Swear[0]) - 3)
    elif len(Swear[0]) - 2 > 5:
        return Swear[0][1:2] + '*' * (len(Swear[0]) - 4) + Swear[0][-2:-1]


srtOpen = fd.askopenfilename(title='Open srt sample')
fdrOpen = fd.askdirectory(title='Open folder (According Video and Language)')

copyfile(srtOpen, pathSplit(srtOpen))
fileopen = open(pathSplit(srtOpen), 'r', encoding='utf-8')
fileread = fileopen.readlines()
fileopen.close
Counter = 0
for mdfiles in sorted(listdir(fdrOpen)):
    if mdfiles != 'titles.md':
        fo = open(fdrOpen + '\\' + mdfiles, "r", encoding='UTF-8')
        for line in fo.readlines():

            swFilter = regexSub(regexSwearPattern, SwearFilter,
                                line.rstrip()).split(" ", maxsplit=1)
            fileread[(3 * (Counter + 1)) + Counter - 1] = swFilter[1] + '\n'
            # print(swFilter)
            Counter += 1
Exemple #8
0
def getParentFolder(file):
    """
	[String] file name with full path 
		=> [String] parent folder of the file
	"""
    return pathSplit(file)[0]
Exemple #9
0
def getFilenameWithoutPath(file):
    """
	[String] file name (with or without full path) 
		=> [String] file name without path
	"""
    return pathSplit(file)[1]