def unprotectZip(self, zipPath, password): password = password.encode("ascii") try: old_zfp = zipfile.ZipFile(zipPath, "r") files = old_zfp.infolist() for fileN in files: old_zfp.open(fileN).read() self.log.info("Do not need to decrypt zip") return except RuntimeError: self.log.error("Error in archive checker?") for line in traceback.format_exc().split("\n"): self.log.error(line) return except zipfile.BadZipFile: self.log.error("Archive is corrupt/damaged?") for line in traceback.format_exc().split("\n"): self.log.error(line) return except: self.log.error("Unknown error??") for line in traceback.format_exc().split("\n"): self.log.error(line) return self.log.info("Removing password from zip '%s'", zipPath) old_zfp = zipfile.ZipFile(zipPath, "r") old_zfp.setpassword(password) fileNs = old_zfp.namelist() files = [] # The zip decryption is STUPID slow. It's really insane how shitty # the python integrated library is. # See czipfile.pyd for some work on making it faster. for fileInfo in fileNs: fctnt = old_zfp.open(fileInfo).read() files.append((fileInfo, fctnt)) old_zfp.close() os.remove(zipPath) # only replace the file if we need to # Now, recreate the zip file without the ad self.log.info("Rebuilding zip without password.") new_zfp = zipfile.ZipFile(zipPath, "w") for fileInfo, contents in files: new_zfp.writestr(fileInfo, contents) new_zfp.close()
def cleanZip(self, archPath): origPath = archPath if not os.path.exists(archPath): raise ValueError("Trying to clean non-existant file?") fType = magic.from_file(archPath, mime=True).decode('ascii') if not fType == 'application/zip' and \ not fType == 'application/x-rar' and \ not fType == 'application/x-7z-compressed': raise NotAnArchive( "Trying to clean a file that is not a zip/rar/7z archive! File=%s" % archPath) self.log.info("Scanning arch '%s'", archPath) try: old_zfp = UniversalArchiveInterface.ArchiveReader(archPath) files = [] hadBadFile = False if fType == 'application/x-7z-compressed': # Cause f**k 7z files. They're slowwwww hadBadFile = True if fType == 'application/x-rar': # Fukkit, convert ALL THE FILES hadBadFile = True for fileN, fileCtnt in old_zfp: if fileN.endswith("Thumbs.db"): hadBadFile = True self.log.info("Had windows 'Thumbs.db' file. Removing") continue if "/__MACOSX/" in fileN or fileN.startswith("__MACOSX/"): hadBadFile = True self.log.info("Have apple bullshit files. Removing") continue if ".DS_Store" in fileN: hadBadFile = True self.log.info( "Have apple bullshit '.DS_Store' files. Removing") continue fctnt = fileCtnt.read() md5 = hashlib.md5() md5.update(fctnt) # Replace bad image with a text-file with the same name, and an explanation in it. if md5.hexdigest() in self.badHashes: self.log.info("File %s was the advert. Removing!", fileN) fileN = fileN + ".deleted.txt" fctnt = "This was an advertisement. It has been automatically removed.\n" fctnt += "Don't worry, there are no missing files, despite the gap in the numbering." hadBadFile = True files.append((fileN, fctnt)) old_zfp.close() # only replace the file if we need to if hadBadFile: # Now, recreate the zip file without the ad if not archPath.endswith(".zip"): archPath = os.path.splitext(archPath)[0] archPath += ".zip" self.log.info("Had advert. Rebuilding zip as '%s'.", archPath) new_zfp = zipfile.ZipFile(archPath, "w") for fileInfo, contents in files: new_zfp.writestr(fileInfo, contents) new_zfp.close() if origPath != archPath: os.remove(origPath) for proc in self.proc: proc.updatePath(origPath, archPath) else: self.log.info( "No offending contents. No changes made to file.") except UniversalArchiveInterface.ArchiveError: self.log.error("Bad archive file!") for line in traceback.format_exc().split("\n"): self.log.error(line) raise DamagedArchive() return archPath