Key retrieval updates
This commit is contained in:
parent
8986855a47
commit
1958989487
|
@ -38,7 +38,7 @@ List of changes since the fork of Apprentice Harper's repository:
|
||||||
## Fixes on master (not yet released):
|
## Fixes on master (not yet released):
|
||||||
|
|
||||||
- Fix issue where importing a key from Adobe Digital Editions would fail in Python2 (Calibre < 5) if there were non-ASCII characters in the username.
|
- Fix issue where importing a key from Adobe Digital Editions would fail in Python2 (Calibre < 5) if there were non-ASCII characters in the username.
|
||||||
- Add code to support importing multiple decryption keys from ADE (click the 'plus' button multiple times).
|
- Add code to support importing multiple decryption keys from ADE.
|
||||||
- Improve epubtest.py to also detect Kobo & Apple DRM.
|
- Improve epubtest.py to also detect Kobo & Apple DRM.
|
||||||
- Small updates to the LCP DRM error messages.
|
- Small updates to the LCP DRM error messages.
|
||||||
- Merge ignobleepub into ineptepub so there's no duplicate code.
|
- Merge ignobleepub into ineptepub so there's no duplicate code.
|
||||||
|
|
|
@ -105,8 +105,11 @@ if iswindows:
|
||||||
fp = winreg.QueryValueEx(plkkey, 'value')[0]
|
fp = winreg.QueryValueEx(plkkey, 'value')[0]
|
||||||
#print("Found fingerprint: " + fp)
|
#print("Found fingerprint: " + fp)
|
||||||
|
|
||||||
|
|
||||||
|
# Note: There can be multiple lists, with multiple entries each.
|
||||||
if ktype == 'passHashList':
|
if ktype == 'passHashList':
|
||||||
|
|
||||||
|
# Find operator (used in key name)
|
||||||
j = -1
|
j = -1
|
||||||
lastOperator = "Unknown"
|
lastOperator = "Unknown"
|
||||||
while True:
|
while True:
|
||||||
|
@ -118,13 +121,23 @@ if iswindows:
|
||||||
ktype = winreg.QueryValueEx(plkkey, None)[0]
|
ktype = winreg.QueryValueEx(plkkey, None)[0]
|
||||||
if ktype == 'operatorURL':
|
if ktype == 'operatorURL':
|
||||||
operatorURL = winreg.QueryValueEx(plkkey, 'value')[0]
|
operatorURL = winreg.QueryValueEx(plkkey, 'value')[0]
|
||||||
#print("Found operator URL: " + operatorURL)
|
|
||||||
try:
|
try:
|
||||||
lastOperator = operatorURL.split('//')[1].split('/')[0]
|
lastOperator = operatorURL.split('//')[1].split('/')[0]
|
||||||
except:
|
except:
|
||||||
lastOperator = "Unknown"
|
pass
|
||||||
|
|
||||||
elif ktype == "passHash":
|
|
||||||
|
# Find hashes
|
||||||
|
j = -1
|
||||||
|
while True:
|
||||||
|
j = j + 1 # start with 0
|
||||||
|
try:
|
||||||
|
plkkey = winreg.OpenKey(plkparent, "%04d" % (j,))
|
||||||
|
except WindowsError:
|
||||||
|
break
|
||||||
|
ktype = winreg.QueryValueEx(plkkey, None)[0]
|
||||||
|
|
||||||
|
if ktype == "passHash":
|
||||||
passhash_encrypted = winreg.QueryValueEx(plkkey, 'value')[0]
|
passhash_encrypted = winreg.QueryValueEx(plkkey, 'value')[0]
|
||||||
names.append("ADE_key_" + lastOperator + "_" + str(int(time.time())) + "_" + str(idx))
|
names.append("ADE_key_" + lastOperator + "_" + str(int(time.time())) + "_" + str(idx))
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
|
|
|
@ -379,7 +379,6 @@ class ManageKeysDialog(QDialog):
|
||||||
if new_key_value in self.plugin_keys.values():
|
if new_key_value in self.plugin_keys.values():
|
||||||
dup_key_count = dup_key_count + 1
|
dup_key_count = dup_key_count + 1
|
||||||
continue
|
continue
|
||||||
print("Setting idx " + str(idx) + ", name " + d.k_name_list[idx] + " to " + new_key_value)
|
|
||||||
self.plugin_keys[d.k_name_list[idx]] = new_key_value
|
self.plugin_keys[d.k_name_list[idx]] = new_key_value
|
||||||
added_key_count = added_key_count + 1
|
added_key_count = added_key_count + 1
|
||||||
else:
|
else:
|
||||||
|
@ -389,10 +388,16 @@ class ManageKeysDialog(QDialog):
|
||||||
self.plugin_keys.append(new_key_value)
|
self.plugin_keys.append(new_key_value)
|
||||||
added_key_count = added_key_count + 1
|
added_key_count = added_key_count + 1
|
||||||
|
|
||||||
|
if (added_key_count > 0 or dup_key_count > 0):
|
||||||
if (added_key_count > 0):
|
if (added_key_count == 0):
|
||||||
info_dialog(None, "{0} {1}: Adding {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
|
info_dialog(None, "{0} {1}: Adding {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
|
||||||
"Successfully added {0} key(s).".format(added_key_count), show=True)
|
"Skipped adding {0} duplicate / existing keys.".format(dup_key_count), show=True, show_copy_button=False)
|
||||||
|
elif (dup_key_count == 0):
|
||||||
|
info_dialog(None, "{0} {1}: Adding {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
|
||||||
|
"Added {0} new keys.".format(added_key_count), show=True, show_copy_button=False)
|
||||||
|
else:
|
||||||
|
info_dialog(None, "{0} {1}: Adding {2}".format(PLUGIN_NAME, PLUGIN_VERSION,self.key_type_name),
|
||||||
|
"Added {0} new keys, skipped adding {1} existing keys.".format(added_key_count, dup_key_count), show=True, show_copy_button=False)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Import single key
|
# Import single key
|
||||||
|
@ -855,10 +860,25 @@ class AddBandNKeyDialog(QDialog):
|
||||||
errmsg = "Failed to extract keys. Is this the correct folder?"
|
errmsg = "Failed to extract keys. Is this the correct folder?"
|
||||||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||||
|
|
||||||
# Take the first key we found. In the future it might be a good idea to import them all.
|
if len(store_result) == 1:
|
||||||
# See accept_ade_dump_passhash for an example on how to do that.
|
# Found exactly one key. Store it with that name.
|
||||||
self.result_data = store_result[0]
|
self.result_data = store_result[0]
|
||||||
QDialog.accept(self)
|
QDialog.accept(self)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Found multiple keys
|
||||||
|
keys = []
|
||||||
|
names = []
|
||||||
|
idx = 1
|
||||||
|
for key in store_result:
|
||||||
|
keys.append(key)
|
||||||
|
names.append(self.key_name + "_" + str(idx))
|
||||||
|
idx = idx + 1
|
||||||
|
|
||||||
|
self.k_full_name_list = names
|
||||||
|
self.k_full_key_list = keys
|
||||||
|
QDialog.accept(self)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def accept_ade_dump_passhash(self):
|
def accept_ade_dump_passhash(self):
|
||||||
|
@ -911,19 +931,36 @@ class AddBandNKeyDialog(QDialog):
|
||||||
errmsg = "Failed to import from Nook Microsoft Store app."
|
errmsg = "Failed to import from Nook Microsoft Store app."
|
||||||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||||
|
|
||||||
if len(store_result) == 0:
|
try:
|
||||||
# Nothing found, try the Nook Study app
|
# Try the Nook Study app
|
||||||
from calibre_plugins.dedrm.ignoblekeyNookStudy import nookkeys
|
from calibre_plugins.dedrm.ignoblekeyNookStudy import nookkeys
|
||||||
store_result = nookkeys()
|
study_result = nookkeys()
|
||||||
|
except:
|
||||||
|
errmsg = "Failed to import from Nook Study app."
|
||||||
|
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||||
|
|
||||||
# Take the first key we found. In the future it might be a good idea to import them all.
|
# Add all found keys to a list
|
||||||
# See accept_ade_dump_passhash for an example on how to do that.
|
keys = []
|
||||||
if len(store_result) > 0:
|
names = []
|
||||||
self.result_data = store_result[0]
|
idx = 1
|
||||||
|
for key in store_result:
|
||||||
|
keys.append(key)
|
||||||
|
names.append(self.key_name + "_nookStore_" + str(idx))
|
||||||
|
idx = idx + 1
|
||||||
|
idx = 1
|
||||||
|
for key in study_result:
|
||||||
|
keys.append(key)
|
||||||
|
names.append(self.key_name + "_nookStudy_" + str(idx))
|
||||||
|
idx = idx + 1
|
||||||
|
|
||||||
|
if len(keys) > 0:
|
||||||
|
self.k_full_name_list = names
|
||||||
|
self.k_full_key_list = keys
|
||||||
QDialog.accept(self)
|
QDialog.accept(self)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Okay, we didn't find anything. How do we get rid of the window?
|
|
||||||
|
# Okay, we didn't find anything.
|
||||||
errmsg = "Didn't find any Nook keys in the Windows app."
|
errmsg = "Didn't find any Nook keys in the Windows app."
|
||||||
error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
||||||
QDialog.reject(self)
|
QDialog.reject(self)
|
||||||
|
@ -1050,14 +1087,23 @@ class AddEReaderDialog(QDialog):
|
||||||
QDialog.accept(self)
|
QDialog.accept(self)
|
||||||
|
|
||||||
|
|
||||||
class AddAdeptDialog(QDialog):
|
class AddAdeptDialog():
|
||||||
def __init__(self, parent=None,):
|
# We don't actually need to show a dialog, but the wrapper class is expecting a QDialog here.
|
||||||
QDialog.__init__(self, parent)
|
# Emulate enough methods and parameters so that that works ...
|
||||||
self.parent = parent
|
|
||||||
self.setWindowTitle("{0} {1}: Getting Default Adobe Digital Editions Key".format(PLUGIN_NAME, PLUGIN_VERSION))
|
|
||||||
layout = QVBoxLayout(self)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
|
def exec_(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
def result(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def Accepted(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __init__(self, parent=None,):
|
||||||
|
|
||||||
|
self.parent = parent
|
||||||
self.new_keys = []
|
self.new_keys = []
|
||||||
self.new_names = []
|
self.new_names = []
|
||||||
|
|
||||||
|
@ -1121,54 +1167,10 @@ class AddAdeptDialog(QDialog):
|
||||||
new_names_2.append(self.new_names[i])
|
new_names_2.append(self.new_names[i])
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
self.new_keys = new_keys_2
|
self.k_full_key_list = new_keys_2
|
||||||
self.new_names = new_names_2
|
self.k_full_name_list = new_names_2
|
||||||
|
|
||||||
|
|
||||||
# Okay, new_keys is now a list of new keys, and new_names has the names for these keys.
|
|
||||||
# Right now this code only supports adding one key per each invocation,
|
|
||||||
# so if the user has multiple keys, he's going to need to add the "plus" button multiple times.
|
|
||||||
|
|
||||||
# In the future it might be a good idea to import them all.
|
|
||||||
# See accept_ade_dump_passhash for an example on how to do that.
|
|
||||||
|
|
||||||
if len(self.new_keys)>0:
|
|
||||||
self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
||||||
|
|
||||||
data_group_box = QGroupBox("", self)
|
|
||||||
layout.addWidget(data_group_box)
|
|
||||||
data_group_box_layout = QVBoxLayout()
|
|
||||||
data_group_box.setLayout(data_group_box_layout)
|
|
||||||
|
|
||||||
key_group = QHBoxLayout()
|
|
||||||
data_group_box_layout.addLayout(key_group)
|
|
||||||
key_group.addWidget(QLabel("Unique Key Name:", self))
|
|
||||||
self.key_ledit = QLineEdit("ade_key_uuid_" + self.new_names[0], self)
|
|
||||||
self.key_ledit.setToolTip("<p>Enter an identifying name for the current Adobe key. Note that it's recommended to leave the UUID (the random-looking digits and letters) as it is.")
|
|
||||||
key_group.addWidget(self.key_ledit)
|
|
||||||
|
|
||||||
if len(self.new_keys) > 1:
|
|
||||||
# The code currently doesn't support adding multiple keys.
|
|
||||||
# If there are more keys, tell the user to trigger this again.
|
|
||||||
data_group_box_layout.addWidget(QLabel("<p>There are more keys available. <br/>Click the 'plus' icon again after adding this key to add the other keys.</p>", self))
|
|
||||||
|
|
||||||
self.button_box.accepted.connect(self.accept)
|
|
||||||
else:
|
|
||||||
# No new key found - neither in ADE nor in the DeACSM plugin
|
|
||||||
|
|
||||||
self.button_box = QDialogButtonBox(QDialogButtonBox.Ok)
|
|
||||||
|
|
||||||
default_key_error = QLabel("No new ADE key could be found. Either ADE is not installed, or the key is already present in the plugin.", self)
|
|
||||||
default_key_error.setAlignment(Qt.AlignHCenter)
|
|
||||||
layout.addWidget(default_key_error)
|
|
||||||
# if no default, bot buttons do the same
|
|
||||||
self.button_box.accepted.connect(self.reject)
|
|
||||||
|
|
||||||
self.button_box.rejected.connect(self.reject)
|
|
||||||
layout.addWidget(self.button_box)
|
|
||||||
|
|
||||||
self.resize(self.sizeHint())
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def key_name(self):
|
def key_name(self):
|
||||||
return str(self.key_ledit.text()).strip()
|
return str(self.key_ledit.text()).strip()
|
||||||
|
@ -1178,14 +1180,19 @@ class AddAdeptDialog(QDialog):
|
||||||
return codecs.encode(self.new_keys[0],'hex').decode("utf-8")
|
return codecs.encode(self.new_keys[0],'hex').decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def accept(self):
|
@property
|
||||||
if len(self.key_name) == 0 or self.key_name.isspace():
|
def k_name_list(self):
|
||||||
errmsg = "Key name must not be empty!"
|
# If the plugin supports returning multiple keys, return a list of names.
|
||||||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
if self.k_full_name_list is not None and self.k_full_key_list is not None:
|
||||||
if len(self.key_name) < 4:
|
return self.k_full_name_list
|
||||||
errmsg = "Key name must be at <i>least</i> 4 characters long!"
|
return None
|
||||||
return error_dialog(None, "{0} {1}".format(PLUGIN_NAME, PLUGIN_VERSION), errmsg, show=True, show_copy_button=False)
|
|
||||||
QDialog.accept(self)
|
@property
|
||||||
|
def k_key_list(self):
|
||||||
|
# If the plugin supports returning multiple keys, return a list of keys.
|
||||||
|
if self.k_full_name_list is not None and self.k_full_key_list is not None:
|
||||||
|
return self.k_full_key_list
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class AddKindleDialog(QDialog):
|
class AddKindleDialog(QDialog):
|
||||||
|
|
Loading…
Reference in New Issue