98 lines
3.1 KiB
Python
98 lines
3.1 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
This file is a standalone python script that is tested with python 2.7
|
|
If Duplicati is producing a backup with the option --upload-verification-file,
|
|
it will produce a *-verification.json file on the backend, which can be verified
|
|
by this script. Simply run this script with the path to the backup
|
|
folder as input, and it will verify all *-verification.json files in the folder.
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import string
|
|
import json
|
|
import base64
|
|
import codecs
|
|
from hashlib import sha256
|
|
|
|
""" Utility function to return byte chunks from a binary file """
|
|
def bytes_from_file(filename, chunksize=8192):
|
|
with open(filename, "rb") as f:
|
|
while True:
|
|
chunk = f.read(chunksize)
|
|
if chunk:
|
|
for b in chunk:
|
|
yield b
|
|
else:
|
|
break
|
|
|
|
""" Verifies a single -verification.json file """
|
|
def verifyHashes(filename):
|
|
errorCount = 0
|
|
checked = 0
|
|
|
|
if (not os.path.exists(filename)):
|
|
print "Specified file does not exist: ", filename
|
|
return -1
|
|
|
|
folder = os.path.dirname(filename)
|
|
with codecs.open(filename, "r", "utf-8-sig") as f:
|
|
doc = json.load(f)
|
|
|
|
for file in doc:
|
|
filename = file["Name"]
|
|
hash = file["Hash"]
|
|
size = file["Size"]
|
|
|
|
fullpath = os.path.join(folder, filename)
|
|
if not os.path.exists(fullpath):
|
|
print "File missing: ", fullpath
|
|
errorCount += 1
|
|
else:
|
|
checked += 1
|
|
print "Verifying file ", filename
|
|
hashalg = sha256()
|
|
for b in bytes_from_file(fullpath):
|
|
hashalg.update(b)
|
|
hashval = base64.b64encode(hashalg.digest())
|
|
if hashval != hash:
|
|
print "*** Hash check failed for file: ", fullpath
|
|
errorCount += 1
|
|
|
|
|
|
if errorCount > 0:
|
|
print "Errors were found"
|
|
else:
|
|
print "No errors found"
|
|
|
|
return errorCount
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 1 and len(sys.argv) != 2:
|
|
print "Usage:", len(sys.argv)
|
|
print "DuplicatiVerify.py <path to verification file>"
|
|
print "DuplicatiVerify.py <folder with verification files>"
|
|
print "DuplicatiVerify.py (no arguments, uses current dir)"
|
|
else:
|
|
if len(sys.argv) == 1:
|
|
argument = os.getcwd()
|
|
else:
|
|
argument = sys.argv[1]
|
|
|
|
if not os.path.exists(argument):
|
|
print "No such file or directory: ", argument
|
|
else:
|
|
if os.path.isfile(argument):
|
|
verifyHashes(argument)
|
|
else:
|
|
files = 0
|
|
for f in os.listdir(argument):
|
|
if (f.endswith("-verification.json")):
|
|
print "Verifying file: ", f
|
|
files += 1
|
|
verifyHashes(os.path.join(argument, f))
|
|
|
|
if files == 0:
|
|
print "No verification files in folder: ", argument |