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