#!/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 " print "DuplicatiVerify.py " 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