def ePubDecrypt(self, path_to_ebook): # Create a TemporaryPersistent file to work with. # Check original epub archive for zip errors. import calibre_plugins.dedrm.zipfix inf = self.temporary_file(".epub") try: print("{0} v{1}: Verifying zip archive integrity".format( PLUGIN_NAME, PLUGIN_VERSION)) fr = zipfix.fixZip(path_to_ebook, inf.name) fr.fix() except Exception as e: print("{0} v{1}: Error \'{2}\' when checking zip archive".format( PLUGIN_NAME, PLUGIN_VERSION, e.args[0])) raise Exception(e) # import the decryption keys import calibre_plugins.dedrm.prefs as prefs dedrmprefs = prefs.DeDRM_Prefs() # import the Barnes & Noble ePub handler import calibre_plugins.dedrm.ignobleepub as ignobleepub #check the book if ignobleepub.ignobleBook(inf.name): print("{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format( PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))) # Attempt to decrypt epub with each encryption key (generated or provided). for keyname, userkey in dedrmprefs['bandnkeys'].items(): keyname_masked = "".join( ("X" if (x.isdigit()) else x) for x in keyname) print("{0} v{1}: Trying Encryption key {2:s}".format( PLUGIN_NAME, PLUGIN_VERSION, keyname_masked)) of = self.temporary_file(".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ignobleepub.decryptBook(userkey, inf.name, of.name) except: print( "{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() result = 1 of.close() if result == 0: # Decryption was successful. # Return the modified PersistentTemporary file to calibre. return of.name print( "{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked, time.time() - self.starttime)) # perhaps we should see if we can get a key from a log file print( "{0} v{1}: Looking for new NOOK Study Keys after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) # get the default NOOK Study keys defaultkeys = [] try: if iswindows or isosx: from calibre_plugins.dedrm.ignoblekey import nookkeys defaultkeys = nookkeys() else: # linux from .wineutils import WineGetKeys scriptpath = os.path.join(self.alfdir, "ignoblekey.py") defaultkeys = WineGetKeys(scriptpath, ".b64", dedrmprefs['adobewineprefix']) except: print( "{0} v{1}: Exception when getting default NOOK Study Key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() newkeys = [] for keyvalue in defaultkeys: if keyvalue not in dedrmprefs['bandnkeys'].values(): newkeys.append(keyvalue) if len(newkeys) > 0: try: for i, userkey in enumerate(newkeys): print("{0} v{1}: Trying a new default key".format( PLUGIN_NAME, PLUGIN_VERSION)) of = self.temporary_file(".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ignobleepub.decryptBook( userkey, inf.name, of.name) except: print( "{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() result = 1 of.close() if result == 0: # Decryption was a success # Store the new successful key in the defaults print("{0} v{1}: Saving a new default key".format( PLUGIN_NAME, PLUGIN_VERSION)) try: dedrmprefs.addnamedvaluetoprefs( 'bandnkeys', 'nook_Study_key', keyvalue) dedrmprefs.writeprefs() print( "{0} v{1}: Saved a new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) except: print( "{0} v{1}: Exception saving a new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() # Return the modified PersistentTemporary file to calibre. return of.name print( "{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) except Exception as e: pass print( "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) raise DeDRMError( "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) # import the Adobe Adept ePub handler import calibre_plugins.dedrm.ineptepub as ineptepub if ineptepub.adeptBook(inf.name): print("{0} v{1}: {2} is a secure Adobe Adept ePub".format( PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))) # Attempt to decrypt epub with each encryption key (generated or provided). for keyname, userkeyhex in dedrmprefs['adeptkeys'].items(): userkey = codecs.decode(userkeyhex, 'hex') print("{0} v{1}: Trying Encryption key {2:s}".format( PLUGIN_NAME, PLUGIN_VERSION, keyname)) of = self.temporary_file(".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ineptepub.decryptBook(userkey, inf.name, of.name) except: print( "{0} v{1}: Exception when decrypting after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() result = 1 try: of.close() except: print( "{0} v{1}: Exception closing temporary file after {2:.1f} seconds. Ignored." .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) if result == 0: # Decryption was successful. # Return the modified PersistentTemporary file to calibre. print( "{0} v{1}: Decrypted with key {2:s} after {3:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, keyname, time.time() - self.starttime)) return of.name print( "{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, keyname, time.time() - self.starttime)) # perhaps we need to get a new default ADE key print( "{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) # get the default Adobe keys defaultkeys = [] try: if iswindows or isosx: from calibre_plugins.dedrm.adobekey import adeptkeys defaultkeys = adeptkeys() else: # linux from .wineutils import WineGetKeys scriptpath = os.path.join(self.alfdir, "adobekey.py") defaultkeys = WineGetKeys(scriptpath, ".der", dedrmprefs['adobewineprefix']) self.default_key = defaultkeys[0] except: print( "{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() self.default_key = "" newkeys = [] for keyvalue in defaultkeys: if codecs.encode(keyvalue, 'hex').decode( 'ascii') not in dedrmprefs['adeptkeys'].values(): newkeys.append(keyvalue) if len(newkeys) > 0: try: for i, userkey in enumerate(newkeys): print("{0} v{1}: Trying a new default key".format( PLUGIN_NAME, PLUGIN_VERSION)) of = self.temporary_file(".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ineptepub.decryptBook( userkey, inf.name, of.name) except: print( "{0} v{1}: Exception when decrypting after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() result = 1 of.close() if result == 0: # Decryption was a success # Store the new successful key in the defaults print("{0} v{1}: Saving a new default key".format( PLUGIN_NAME, PLUGIN_VERSION)) try: dedrmprefs.addnamedvaluetoprefs( 'adeptkeys', 'default_key', codecs.encode(keyvalue, 'hex').decode('ascii')) dedrmprefs.writeprefs() print( "{0} v{1}: Saved a new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) except: print( "{0} v{1}: Exception when saving a new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() print( "{0} v{1}: Decrypted with new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) # Return the modified PersistentTemporary file to calibre. return of.name print( "{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) except Exception as e: print( "{0} v{1}: Unexpected Exception trying a new default key after {2:.1f} seconds" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) traceback.print_exc() pass # Something went wrong with decryption. print( "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) raise DeDRMError( "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime)) # Not a Barnes & Noble nor an Adobe Adept # Import the fixed epub. print( "{0} v{1}: “{2}” is neither an Adobe Adept nor a Barnes & Noble encrypted ePub" .format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))) raise DeDRMError( "{0} v{1}: Couldn't decrypt after {2:.1f} seconds. DRM free perhaps?" .format(PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime))
PLUGIN_NAME, PLUGIN_VERSION, keyname_masked, time.time() - self.starttime ) print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Alf's blog: http://apprenticealf.wordpress.com/".format( PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime ) raise DeDRMError( u"{0} v{1}: Ultimately failed to decrypt “{2}” after {3:.1f} seconds.\nRead the FAQs at Alf's blog: http://apprenticealf.wordpress.com/".format( PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook), time.time() - self.starttime ) ) # import the Adobe Adept ePub handler import calibre_plugins.dedrm.ineptepub as ineptepub if ineptepub.adeptBook(inf.name): print u"{0} v{1}: {2} is a secure Adobe Adept ePub".format( PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook) ) # Attempt to decrypt epub with each encryption key (generated or provided). for keyname, userkeyhex in dedrmprefs["adeptkeys"].items(): userkey = userkeyhex.decode("hex") print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname) of = self.temporary_file(u".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ineptepub.decryptBook(userkey, inf.name, of.name) except: result = 1
PLUGIN_NAME, PLUGIN_VERSION, keyname_masked, time.time() - self.starttime) print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Alf's blog: http://apprenticealf.wordpress.com/".format( PLUGIN_NAME, PLUGIN_VERSION, time.time() - self.starttime) raise DeDRMError( u"{0} v{1}: Ultimately failed to decrypt “{2}” after {3:.1f} seconds.\nRead the FAQs at Alf's blog: http://apprenticealf.wordpress.com/" .format(PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook), time.time() - self.starttime)) # import the Adobe Adept ePub handler import calibre_plugins.dedrm.ineptepub as ineptepub if ineptepub.adeptBook(inf.name): print u"{0} v{1}: {2} is a secure Adobe Adept ePub".format( PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)) # Attempt to decrypt epub with each encryption key (generated or provided). for keyname, userkeyhex in dedrmprefs['adeptkeys'].items(): userkey = userkeyhex.decode('hex') print u"{0} v{1}: Trying Encryption key {2:s}".format( PLUGIN_NAME, PLUGIN_VERSION, keyname) of = self.temporary_file(u".epub") # Give the user key, ebook and TemporaryPersistent file to the decryption function. try: result = ineptepub.decryptBook(userkey, inf.name, of.name) except: result = 1
def decryptepub(infile, outdir, rscpath): errlog = '' # first fix the epub to make sure we do not get errors name, ext = os.path.splitext(os.path.basename(infile)) bpath = os.path.dirname(infile) zippath = os.path.join(bpath, name + '_temp.zip') rv = zipfix.repairBook(infile, zippath) if rv != 0: print("Error while trying to fix epub") return rv # determine a good name for the output file outfile = os.path.join(outdir, name + '_nodrm.epub') rv = 1 # first try with the Adobe adept epub if ineptepub.adeptBook(zippath): # try with any keyfiles (*.der) in the rscpath files = os.listdir(rscpath) filefilter = re.compile("\.der$", re.IGNORECASE) files = filter(filefilter.search, files) if files: for filename in files: keypath = os.path.join(rscpath, filename) userkey = open(keypath, 'rb').read() try: rv = ineptepub.decryptBook(userkey, zippath, outfile) if rv == 0: print("Decrypted Adobe ePub with key file {0}".format( filename)) break except Exception as e: errlog += traceback.format_exc() errlog += str(e) rv = 1 # now try with ignoble epub elif ignobleepub.ignobleBook(zippath): # try with any keyfiles (*.b64) in the rscpath files = os.listdir(rscpath) filefilter = re.compile("\.b64$", re.IGNORECASE) files = filter(filefilter.search, files) if files: for filename in files: keypath = os.path.join(rscpath, filename) userkey = open(keypath, 'r').read() #print userkey try: rv = ignobleepub.decryptBook(userkey, zippath, outfile) if rv == 0: print("Decrypted B&N ePub with key file {0}".format( filename)) break except Exception as e: errlog += traceback.format_exc() errlog += str(e) rv = 1 else: encryption = epubtest.encryption(zippath) if encryption == "Unencrypted": print("{0} is not DRMed.".format(name)) rv = 0 else: print("{0} has an unknown encryption.".format(name)) os.remove(zippath) if rv != 0: print(errlog) return rv