diff --git a/DeDRM_Macintosh_Application/DeDRM.app.txt b/DeDRM_Macintosh_Application/DeDRM.app.txt index fdf0a43..ade0d1c 100644 Binary files a/DeDRM_Macintosh_Application/DeDRM.app.txt and b/DeDRM_Macintosh_Application/DeDRM.app.txt differ diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index a18d8e4..c9919f8 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,7 +24,7 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM AppleScript 6.3.4 Written 2010–2015 by Apprentice Alf et al. + DeDRM AppleScript 6.3.5 Written 2010–2016 by Apprentice Alf et al. CFBundleIconFile DeDRM CFBundleIdentifier @@ -36,7 +36,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 6.3.4 + 6.3.5 CFBundleSignature dplt LSRequiresCarbon diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index 53b1200..3254222 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -46,6 +46,7 @@ __docformat__ = 'restructuredtext en' # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 +# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging """ @@ -53,7 +54,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 4) +PLUGIN_VERSION_TUPLE = (6, 3, 5) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' @@ -96,7 +97,7 @@ class DeDRM(FileTypePlugin): supported_platforms = ['linux', 'osx', 'windows'] author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages" version = PLUGIN_VERSION_TUPLE - minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions. + minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions. file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz']) on_import = True priority = 600 @@ -296,11 +297,15 @@ class DeDRM(FileTypePlugin): traceback.print_exc() result = 1 - of.close() + try: + of.close() + except: + print u"{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 u"{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 u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime) @@ -360,6 +365,7 @@ class DeDRM(FileTypePlugin): except: print u"{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 u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime) # Return the modified PersistentTemporary file to calibre. return of.name diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py index e116a6e..5987b8c 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptepub.pyw, version 6.1 +# ineptepub.pyw, version 6.3 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015–2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptepub.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptepub.pyw. You can run this @@ -38,13 +39,14 @@ from __future__ import with_statement # 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility # 6.1 - Work if TkInter is missing # 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis +# 6.3 - Add additional check on DER file sanity """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "6.2" +__version__ = "6.3" import sys import os @@ -169,9 +171,14 @@ def _load_crypto_libcrypto(): def __init__(self, der): buf = create_string_buffer(der) pp = c_char_pp(cast(buf, c_char_p)) - rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) + rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -313,6 +320,12 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') + def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py index 1986e20..3967647 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptpdf.pyw, version 7.11 +# ineptpdf.pyw, version 8.0.2 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015-2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptpdf.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptpdf.pyw. You can run this @@ -53,13 +54,15 @@ from __future__ import with_statement # 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility # 8.0 - Work if TkInter is missing # 8.0.1 - Broken Metadata fix. +# 8.0.2 - Add additional check on DER file sanity + """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "8.0.1" +__version__ = "8.0.2" import sys import os @@ -198,6 +201,11 @@ def _load_crypto_libcrypto(): rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -383,6 +391,11 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py index b54db80..f2f8edc 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/wineutils.py @@ -26,6 +26,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""): if not os.path.exists(outdirpath): os.makedirs(outdirpath) + wineprefix = os.path.abspath(os.path.expanduser(os.path.expandvars(wineprefix))) if wineprefix != "" and os.path.exists(wineprefix): cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) else: @@ -38,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""): result = p2.wait("wait") except Exception, e: print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) - return [] + if wineprefix != "" and os.path.exists(wineprefix): + cmdline = u"WINEPREFIX=\"{2}\" wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) + else: + cmdline = u"wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath) + print u"{0} v{1}: Command line: “{2}”".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline) + try: + cmdline = cmdline.encode(sys.getfilesystemencoding()) + p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=sys.stdout, stderr=STDOUT, close_fds=False) + result = p2.wait("wait") + except Exception, e: + print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) + + # try finding winekeys anyway, even if above code errored winekeys = [] # get any files with extension in the output dir files = [f for f in os.listdir(outdirpath) if f.endswith(extension)] diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw index 87b8634..0aa55d3 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # DeDRM.pyw -# Copyright 2010-2015 some_updates, Apprentice Alf and Apprentice Harper +# Copyright 2010-2016 some_updates, Apprentice Alf and Apprentice Harper # Revision history: # 6.0.0 - Release along with unified plugin @@ -19,8 +19,9 @@ # 6.3.2 - Version bump to match plugin # 6.3.3 - Version bump to match plugin # 6.3.4 - Version bump to match plugin +# 6.3.5 - Version bump to match plugin -__version__ = '6.3.4' +__version__ = '6.3.5' import sys import os, os.path diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py index 53b1200..3254222 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py @@ -46,6 +46,7 @@ __docformat__ = 'restructuredtext en' # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 +# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging """ @@ -53,7 +54,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 4) +PLUGIN_VERSION_TUPLE = (6, 3, 5) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' @@ -96,7 +97,7 @@ class DeDRM(FileTypePlugin): supported_platforms = ['linux', 'osx', 'windows'] author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages" version = PLUGIN_VERSION_TUPLE - minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions. + minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions. file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz']) on_import = True priority = 600 @@ -296,11 +297,15 @@ class DeDRM(FileTypePlugin): traceback.print_exc() result = 1 - of.close() + try: + of.close() + except: + print u"{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 u"{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 u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime) @@ -360,6 +365,7 @@ class DeDRM(FileTypePlugin): except: print u"{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 u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime) # Return the modified PersistentTemporary file to calibre. return of.name diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py index e116a6e..5987b8c 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptepub.pyw, version 6.1 +# ineptepub.pyw, version 6.3 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015–2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptepub.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptepub.pyw. You can run this @@ -38,13 +39,14 @@ from __future__ import with_statement # 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility # 6.1 - Work if TkInter is missing # 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis +# 6.3 - Add additional check on DER file sanity """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "6.2" +__version__ = "6.3" import sys import os @@ -169,9 +171,14 @@ def _load_crypto_libcrypto(): def __init__(self, der): buf = create_string_buffer(der) pp = c_char_pp(cast(buf, c_char_p)) - rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) + rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -313,6 +320,12 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') + def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py index 1986e20..3967647 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptpdf.pyw, version 7.11 +# ineptpdf.pyw, version 8.0.2 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015-2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptpdf.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptpdf.pyw. You can run this @@ -53,13 +54,15 @@ from __future__ import with_statement # 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility # 8.0 - Work if TkInter is missing # 8.0.1 - Broken Metadata fix. +# 8.0.2 - Add additional check on DER file sanity + """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "8.0.1" +__version__ = "8.0.2" import sys import os @@ -198,6 +201,11 @@ def _load_crypto_libcrypto(): rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -383,6 +391,11 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py index b54db80..f2f8edc 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/wineutils.py @@ -26,6 +26,7 @@ def WineGetKeys(scriptpath, extension, wineprefix=""): if not os.path.exists(outdirpath): os.makedirs(outdirpath) + wineprefix = os.path.abspath(os.path.expanduser(os.path.expandvars(wineprefix))) if wineprefix != "" and os.path.exists(wineprefix): cmdline = u"WINEPREFIX=\"{2}\" wine python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) else: @@ -38,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""): result = p2.wait("wait") except Exception, e: print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) - return [] + if wineprefix != "" and os.path.exists(wineprefix): + cmdline = u"WINEPREFIX=\"{2}\" wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) + else: + cmdline = u"wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath) + print u"{0} v{1}: Command line: “{2}”".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline) + try: + cmdline = cmdline.encode(sys.getfilesystemencoding()) + p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=sys.stdout, stderr=STDOUT, close_fds=False) + result = p2.wait("wait") + except Exception, e: + print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) + + # try finding winekeys anyway, even if above code errored winekeys = [] # get any files with extension in the output dir files = [f for f in os.listdir(outdirpath) if f.endswith(extension)] diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index a64da23..05cfb8f 100644 Binary files a/DeDRM_calibre_plugin/DeDRM_plugin.zip and b/DeDRM_calibre_plugin/DeDRM_plugin.zip differ diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py index 53b1200..3254222 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py @@ -46,6 +46,7 @@ __docformat__ = 'restructuredtext en' # 6.3.2 - Fixed Kindle for Android help file # 6.3.3 - Bug fix for Kindle for PC support # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 +# 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging """ @@ -53,7 +54,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 4) +PLUGIN_VERSION_TUPLE = (6, 3, 5) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' @@ -96,7 +97,7 @@ class DeDRM(FileTypePlugin): supported_platforms = ['linux', 'osx', 'windows'] author = u"Apprentice Alf, Aprentice Harper, The Dark Reverser and i♥cabbages" version = PLUGIN_VERSION_TUPLE - minimum_calibre_version = (0, 7, 55) # Compiled python libraries cannot be imported in earlier versions. + minimum_calibre_version = (1, 0, 0) # Compiled python libraries cannot be imported in earlier versions. file_types = set(['epub','pdf','pdb','prc','mobi','pobi','azw','azw1','azw3','azw4','tpz']) on_import = True priority = 600 @@ -296,11 +297,15 @@ class DeDRM(FileTypePlugin): traceback.print_exc() result = 1 - of.close() + try: + of.close() + except: + print u"{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 u"{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 u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname,time.time()-self.starttime) @@ -360,6 +365,7 @@ class DeDRM(FileTypePlugin): except: print u"{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 u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime) # Return the modified PersistentTemporary file to calibre. return of.name diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py b/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py index e116a6e..5987b8c 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptepub.pyw, version 6.1 +# ineptepub.pyw, version 6.3 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2013 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015–2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptepub.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptepub.pyw. You can run this @@ -38,13 +39,14 @@ from __future__ import with_statement # 6.0 - moved unicode_argv call inside main for Windows DeDRM compatibility # 6.1 - Work if TkInter is missing # 6.2 - Handle UTF-8 file names inside an ePub, fix by Jose Luis +# 6.3 - Add additional check on DER file sanity """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "6.2" +__version__ = "6.3" import sys import os @@ -169,9 +171,14 @@ def _load_crypto_libcrypto(): def __init__(self, der): buf = create_string_buffer(der) pp = c_char_pp(cast(buf, c_char_p)) - rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) + rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -313,6 +320,12 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') + def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py b/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py index 1986e20..3967647 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py @@ -3,18 +3,19 @@ from __future__ import with_statement -# ineptpdf.pyw, version 7.11 +# ineptpdf.pyw, version 8.0.2 # Copyright © 2009-2010 by i♥cabbages # Released under the terms of the GNU General Public Licence, version 3 # # Modified 2010–2012 by some_updates, DiapDealer and Apprentice Alf +# Modified 2015-2016 by Apprentice Harper -# Windows users: Before running this program, you must first install Python 2.6 +# Windows users: Before running this program, you must first install Python 2.7 # from and PyCrypto from # (make sure to -# install the version for Python 2.6). Save this script file as +# install the version for Python 2.7). Save this script file as # ineptpdf.pyw and double-click on it to run it. # # Mac OS X users: Save this script file as ineptpdf.pyw. You can run this @@ -53,13 +54,15 @@ from __future__ import with_statement # 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility # 8.0 - Work if TkInter is missing # 8.0.1 - Broken Metadata fix. +# 8.0.2 - Add additional check on DER file sanity + """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "8.0.1" +__version__ = "8.0.2" import sys import os @@ -198,6 +201,11 @@ def _load_crypto_libcrypto(): rsa = self._rsa = d2i_RSAPrivateKey(None, pp, len(der)) if rsa is None: raise ADEPTError('Error parsing ADEPT user key DER') + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def decrypt(self, from_): rsa = self._rsa @@ -383,6 +391,11 @@ def _load_crypto_pycrypto(): key = [key.getChild(x).value for x in xrange(1, 4)] key = [self.bytesToNumber(v) for v in key] self._rsa = _RSA.construct(key) + # check if pointer is not NULL + try: + c = self._rsa.contents + except ValueError: + raise ADEPTError('Error parsing ADEPT user key DER') def bytesToNumber(self, bytes): total = 0L diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/wineutils.py b/DeDRM_calibre_plugin/DeDRM_plugin/wineutils.py index 6d79c9b..f2f8edc 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/wineutils.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/wineutils.py @@ -39,8 +39,20 @@ def WineGetKeys(scriptpath, extension, wineprefix=""): result = p2.wait("wait") except Exception, e: print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) - return [] + if wineprefix != "" and os.path.exists(wineprefix): + cmdline = u"WINEPREFIX=\"{2}\" wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath,wineprefix) + else: + cmdline = u"wine C:\\Python27\\python.exe \"{0}\" \"{1}\"".format(scriptpath,outdirpath) + print u"{0} v{1}: Command line: “{2}”".format(PLUGIN_NAME, PLUGIN_VERSION, cmdline) + try: + cmdline = cmdline.encode(sys.getfilesystemencoding()) + p2 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=sys.stdout, stderr=STDOUT, close_fds=False) + result = p2.wait("wait") + except Exception, e: + print u"{0} v{1}: Wine subprocess call error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0]) + + # try finding winekeys anyway, even if above code errored winekeys = [] # get any files with extension in the output dir files = [f for f in os.listdir(outdirpath) if f.endswith(extension)] diff --git a/ReadMe_First.txt b/ReadMe_First.txt index beb7287..10d0478 100644 --- a/ReadMe_First.txt +++ b/ReadMe_First.txt @@ -12,7 +12,7 @@ The is archive includes tools to remove DRM from: - Adobe Digital Editions PDFs - Mobipocket ebooks - eReader PDB books - - Scuolabooks (Windows only solution by Hex) + - Scuolabooks (Link to solution by Hex) These tools do NOT work with Apple's iBooks FairPlay DRM (see end of this file.) @@ -78,7 +78,7 @@ Rocket_ebooks Information about the now-obsolete Rocket ebook format and DRM, along with source for a tool to remove the DRM. Scuolabook_DRM -A windows-only application (including source code) for removing DRM from ScuolaBooks PDFs, created by "Hex" and included with permission. +A link to the tool for removing DRM from ScuolaBooks PDFs, created by "Hex". Windows and Python