Add passhash interface to CLI

This commit is contained in:
NoDRM 2021-12-29 13:00:45 +01:00
parent b11aadcca6
commit e0fcd99bcb
4 changed files with 169 additions and 33 deletions

View File

@ -147,7 +147,7 @@ if iswindows:
#print("Didn't find fingerprint for decryption ...") #print("Didn't find fingerprint for decryption ...")
return [], [] return [], []
print("Found {0:d} passhashes".format(len(keys))) print("Found {0:d} passhashes".format(len(keys)), file=sys.stderr)
keys_decrypted = [] keys_decrypted = []

View File

@ -157,7 +157,7 @@ def getNookLogFiles():
logpath = path +'\\Barnes & Noble\\NOOKstudy\\logs\\BNClientLog.txt' logpath = path +'\\Barnes & Noble\\NOOKstudy\\logs\\BNClientLog.txt'
if os.path.isfile(logpath): if os.path.isfile(logpath):
found = True found = True
print('Found nookStudy log file: ' + logpath.encode('ascii','ignore')) print('Found nookStudy log file: ' + logpath.encode('ascii','ignore'), file=sys.stderr)
logFiles.append(logpath) logFiles.append(logpath)
else: else:
home = os.getenv('HOME') home = os.getenv('HOME')
@ -165,26 +165,26 @@ def getNookLogFiles():
testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/logs/BNClientLog.txt' testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/logs/BNClientLog.txt'
if os.path.isfile(testpath): if os.path.isfile(testpath):
logFiles.append(testpath) logFiles.append(testpath)
print('Found nookStudy log file: ' + testpath) print('Found nookStudy log file: ' + testpath, file=sys.stderr)
found = True found = True
testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/indices/BNClientLog.txt' testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/indices/BNClientLog.txt'
if os.path.isfile(testpath): if os.path.isfile(testpath):
logFiles.append(testpath) logFiles.append(testpath)
print('Found nookStudy log file: ' + testpath) print('Found nookStudy log file: ' + testpath, file=sys.stderr)
found = True found = True
testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/logs/BNClientLog.txt' testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/logs/BNClientLog.txt'
if os.path.isfile(testpath): if os.path.isfile(testpath):
logFiles.append(testpath) logFiles.append(testpath)
print('Found nookStudy log file: ' + testpath) print('Found nookStudy log file: ' + testpath, file=sys.stderr)
found = True found = True
testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/indices/BNClientLog.txt' testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/indices/BNClientLog.txt'
if os.path.isfile(testpath): if os.path.isfile(testpath):
logFiles.append(testpath) logFiles.append(testpath)
print('Found nookStudy log file: ' + testpath) print('Found nookStudy log file: ' + testpath, file=sys.stderr)
found = True found = True
if not found: if not found:
print('No nook Study log files have been found.') print('No nook Study log files have been found.', file=sys.stderr)
return logFiles return logFiles
@ -205,7 +205,7 @@ def nookkeys(files = []):
for file in files: for file in files:
fileKeys = getKeysFromLog(file) fileKeys = getKeysFromLog(file)
if fileKeys: if fileKeys:
print("Found {0} keys in the Nook Study log files".format(len(fileKeys))) print("Found {0} keys in the Nook Study log files".format(len(fileKeys)), file=sys.stderr)
keys.extend(fileKeys) keys.extend(fileKeys)
return list(set(keys)) return list(set(keys))
@ -218,7 +218,7 @@ def getkey(outpath, files=[]):
outfile = outpath outfile = outpath
with open(outfile, 'w') as keyfileout: with open(outfile, 'w') as keyfileout:
keyfileout.write(keys[-1]) keyfileout.write(keys[-1])
print("Saved a key to {0}".format(outfile)) print("Saved a key to {0}".format(outfile), file=sys.stderr)
else: else:
keycount = 0 keycount = 0
for key in keys: for key in keys:
@ -229,7 +229,7 @@ def getkey(outpath, files=[]):
break break
with open(outfile, 'w') as keyfileout: with open(outfile, 'w') as keyfileout:
keyfileout.write(key) keyfileout.write(key)
print("Saved a key to {0}".format(outfile)) print("Saved a key to {0}".format(outfile), file=sys.stderr)
return True return True
return False return False

View File

@ -8,14 +8,16 @@ from __future__ import absolute_import, print_function
# Copyright © 2021 NoDRM # Copyright © 2021 NoDRM
OPT_SHORT_TO_LONG = [ OPT_SHORT_TO_LONG = [
["h", "help"], ["c", "config"],
["t", "test"],
["v", "verbose"],
["q", "quiet"],
["u", "username"],
["p", "password"],
["d", "dest"], ["d", "dest"],
["f", "force"] ["e", "extract"],
["f", "force"],
["h", "help"],
["p", "password"],
["q", "quiet"],
["t", "test"],
["u", "username"],
["v", "verbose"],
] ]
#@@CALIBRE_COMPAT_CODE@@ #@@CALIBRE_COMPAT_CODE@@
@ -32,6 +34,29 @@ _additional_data = []
_additional_params = [] _additional_params = []
_function = None _function = None
def print_fname(f, info):
print(" " + f.ljust(15) + " " + info)
def print_opt(short, long, info):
if short is None:
short = " "
else:
short = " -" + short
if long is None:
long = " "
else:
long = "--" + long.ljust(16)
print(short + " " + long + " " + info, file=sys.stderr)
def print_std_usage(name, param_string):
print("Usage: ", file=sys.stderr)
if "calibre" in sys.modules:
print(" calibre-debug -r \"DeDRM\" -- "+name+" " + param_string, file=sys.stderr)
else:
print(" python3 DeDRM_plugin.zip "+name+" "+param_string, file=sys.stderr)
def print_err_header(): def print_err_header():
from __init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore from __init__ import PLUGIN_NAME, PLUGIN_VERSION # type: ignore
@ -51,7 +76,11 @@ def print_help():
print("This plugin can either be imported into Calibre, or be executed directly") print("This plugin can either be imported into Calibre, or be executed directly")
print("through Python like you are doing right now.") print("through Python like you are doing right now.")
print() print()
print("TODO: Parameters here ...") print("Available functions:")
print_fname("passhash", "Manage Adobe PassHashes")
print()
# TODO: All parameters that are global should be listed here.
def print_credits(): def print_credits():
from __init__ import PLUGIN_NAME, PLUGIN_VERSION from __init__ import PLUGIN_NAME, PLUGIN_VERSION
@ -77,31 +106,23 @@ def handle_single_argument(arg, next):
used_up = 0 used_up = 0
global _additional_params global _additional_params
if arg == "--help": if arg in ["--username", "--password"]:
print_help()
sys.exit(0)
elif arg == "--credits":
print_credits()
sys.exit(0)
elif arg in ["--username", "--password"]:
used_up = 1 used_up = 1
_additional_params.append(arg) _additional_params.append(arg)
if next is None: if next is None:
print_err_header() print_err_header()
print("Missing parameter for argument " + arg) print("Missing parameter for argument " + arg, file=sys.stderr)
sys.exit(1) sys.exit(1)
else: else:
_additional_params.append(next[0]) _additional_params.append(next[0])
elif arg in ["--verbose", "--quiet"]: elif arg in ["--help", "--credits", "--verbose", "--quiet", "--extract"]:
_additional_params.append(arg) _additional_params.append(arg)
else: else:
print_err_header() print_err_header()
print("Unknown argument: " + arg) print("Unknown argument: " + arg, file=sys.stderr)
sys.exit(1) sys.exit(1)
@ -120,9 +141,14 @@ def handle_data(data):
_additional_data.append(str(data)) _additional_data.append(str(data))
def execute_action(action, filenames, params): def execute_action(action, filenames, params):
print("Executing '{0}' on file(s) {1} with parameters {2}".format(action, str(filenames), str(params))) print("Executing '{0}' on file(s) {1} with parameters {2}".format(action, str(filenames), str(params)), file=sys.stderr)
print("ERROR: This feature is still in development. Right now it can't be used yet.") if action == "passhash":
from standalone.passhash import perform_action
perform_action(params, filenames)
else:
print("ERROR: This feature is still in development. Right now it can't be used yet.", file=sys.stderr)
def main(argv): def main(argv):
@ -194,9 +220,17 @@ def main(argv):
handle_data(arg) handle_data(arg)
if _function is None and "--credits" in _additional_params:
print_credits()
sys.exit(0)
if _function is None and "--help" in _additional_params:
print_help()
sys.exit(0)
if _function is None: if _function is None:
print_help() print_help()
return(1) sys.exit(1)
# Okay, now actually begin doing stuff. # Okay, now actually begin doing stuff.
# This function gets told what to do and gets additional data (filenames). # This function gets told what to do and gets additional data (filenames).

View File

@ -0,0 +1,102 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# CLI interface for the DeDRM plugin (useable without Calibre, too)
# Adobe PassHash implementation
from __future__ import absolute_import, print_function
# Copyright © 2021 NoDRM
#@@CALIBRE_COMPAT_CODE@@
import os, sys
from standalone.__init__ import print_opt, print_std_usage
iswindows = sys.platform.startswith('win')
isosx = sys.platform.startswith('darwin')
def print_passhash_help():
from __init__ import PLUGIN_NAME, PLUGIN_VERSION
print(PLUGIN_NAME + " v" + PLUGIN_VERSION + " - Calibre DRM removal plugin by noDRM")
print()
print("passhash: Manage Adobe PassHashes")
print()
print_std_usage("passhash", "[ -u username -p password | -e ]")
print()
print("Options: ")
print_opt("u", "username", "Generate a PassHash with the given username")
print_opt("p", "password", "Generate a PassHash with the given username")
print_opt("e", "extract", "Extract PassHashes found on this machine")
def perform_action(params, files):
user = None
pwd = None
if len(params) == 0:
print_passhash_help()
return 0
extract = False
while len(params) > 0:
p = params.pop(0)
if p == "--username":
user = params.pop(0)
elif p == "--password":
pwd = params.pop(0)
elif p == "--extract":
extract = True
elif p == "--help":
print_passhash_help()
return 0
if not extract:
if user is None:
print("Missing parameter: --username", file=sys.stderr)
if pwd is None:
print("Missing parameter: --password", file=sys.stderr)
if user is None or pwd is None:
return 1
if user is not None and pwd is not None:
from ignoblekeyGenPassHash import generate_key
key = generate_key(user, pwd)
print(key.decode("utf-8"))
if extract:
if not iswindows and not isosx:
print("Extracting PassHash keys not supported on Linux.", file=sys.stderr)
return 1
keys = []
from ignoblekeyNookStudy import nookkeys
keys.extend(nookkeys())
if iswindows:
from ignoblekeyWindowsStore import dump_keys
keys.extend(dump_keys())
from adobekey_get_passhash import passhash_keys
ade_keys, ade_names = passhash_keys()
keys.extend(ade_keys)
# Trim duplicates
newkeys = []
for k in keys:
if not k in newkeys:
newkeys.append(k)
# Print all found keys
for k in newkeys:
print(k)
return 0
if __name__ == "__main__":
print("This code is not intended to be executed directly!")