Add passhash interface to CLI
This commit is contained in:
parent
b11aadcca6
commit
e0fcd99bcb
|
@ -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 = []
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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!")
|
Loading…
Reference in New Issue