]> xmof Git - DeDRM.git/commitdiff
Add passhash interface to CLI
authorNoDRM <no_drm123@protonmail.com>
Wed, 29 Dec 2021 12:00:45 +0000 (13:00 +0100)
committerNoDRM <no_drm123@protonmail.com>
Wed, 29 Dec 2021 12:00:45 +0000 (13:00 +0100)
DeDRM_plugin/adobekey_get_passhash.py
DeDRM_plugin/ignoblekeyNookStudy.py
DeDRM_plugin/standalone/__init__.py
DeDRM_plugin/standalone/passhash.py [new file with mode: 0644]

index 5b4502a5e93af34222b0441e42637ae431944a5f..adb0965c8cc6d7926b7e5463ad97e0734f271ff5 100644 (file)
@@ -147,7 +147,7 @@ if iswindows:
             #print("Didn't find fingerprint for decryption ...")
             return [], []
 
-        print("Found {0:d} passhashes".format(len(keys)))
+        print("Found {0:d} passhashes".format(len(keys)), file=sys.stderr)
 
         keys_decrypted = []
 
index 4152093d2d3cb26e53ccfcc8c38af1b804deee79..93c691b09ebb0f2a1dfdb4a27fa101484edce3c2 100644 (file)
@@ -157,7 +157,7 @@ def getNookLogFiles():
             logpath = path +'\\Barnes & Noble\\NOOKstudy\\logs\\BNClientLog.txt'
             if os.path.isfile(logpath):
                 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)
     else:
         home = os.getenv('HOME')
@@ -165,26 +165,26 @@ def getNookLogFiles():
         testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/logs/BNClientLog.txt'
         if os.path.isfile(testpath):
             logFiles.append(testpath)
-            print('Found nookStudy log file: ' + testpath)
+            print('Found nookStudy log file: ' + testpath, file=sys.stderr)
             found = True
         testpath = home + '/Library/Application Support/Barnes & Noble/DesktopReader/indices/BNClientLog.txt'
         if os.path.isfile(testpath):
             logFiles.append(testpath)
-            print('Found nookStudy log file: ' + testpath)
+            print('Found nookStudy log file: ' + testpath, file=sys.stderr)
             found = True
         testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/logs/BNClientLog.txt'
         if os.path.isfile(testpath):
             logFiles.append(testpath)
-            print('Found nookStudy log file: ' + testpath)
+            print('Found nookStudy log file: ' + testpath, file=sys.stderr)
             found = True
         testpath = home + '/Library/Application Support/Barnes & Noble/BNDesktopReader/indices/BNClientLog.txt'
         if os.path.isfile(testpath):
             logFiles.append(testpath)
-            print('Found nookStudy log file: ' + testpath)
+            print('Found nookStudy log file: ' + testpath, file=sys.stderr)
             found = True
 
     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
 
 
@@ -205,7 +205,7 @@ def nookkeys(files = []):
     for file in files:
         fileKeys = getKeysFromLog(file)
         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)
     return list(set(keys))
 
@@ -218,7 +218,7 @@ def getkey(outpath, files=[]):
             outfile = outpath
             with open(outfile, 'w') as keyfileout:
                 keyfileout.write(keys[-1])
-            print("Saved a key to {0}".format(outfile))
+            print("Saved a key to {0}".format(outfile), file=sys.stderr)
         else:
             keycount = 0
             for key in keys:
@@ -229,7 +229,7 @@ def getkey(outpath, files=[]):
                         break
                 with open(outfile, 'w') as keyfileout:
                     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 False
 
index dbf0cab68a9273a67fc7a0a8105653bde1161c7c..fe74bb31137ecb6dfaa9585d9b4d5a326fed17ca 100644 (file)
@@ -8,14 +8,16 @@ from __future__ import absolute_import, print_function
 # Copyright © 2021 NoDRM
 
 OPT_SHORT_TO_LONG = [
+    ["c", "config"],
+    ["d", "dest"],
+    ["e", "extract"],
+    ["f", "force"], 
     ["h", "help"], 
-    ["t", "test"], 
-    ["v", "verbose"],
+    ["p", "password"],
     ["q", "quiet"],
+    ["t", "test"], 
     ["u", "username"],
-    ["p", "password"],
-    ["d", "dest"],
-    ["f", "force"]
+    ["v", "verbose"],
 ]
 
 #@@CALIBRE_COMPAT_CODE@@
@@ -32,6 +34,29 @@ _additional_data = []
 _additional_params = []
 _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():
     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("through Python like you are doing right now.")
     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():
     from __init__ import PLUGIN_NAME, PLUGIN_VERSION
@@ -77,31 +106,23 @@ def handle_single_argument(arg, next):
     used_up = 0
     global _additional_params
     
-    if arg == "--help":
-        print_help()
-        sys.exit(0)
-
-    elif arg == "--credits":
-        print_credits()
-        sys.exit(0)
-
-    elif arg in ["--username", "--password"]: 
+    if arg in ["--username", "--password"]: 
         used_up = 1
         _additional_params.append(arg)
         if next is None: 
             print_err_header()
-            print("Missing parameter for argument " + arg)
+            print("Missing parameter for argument " + arg, file=sys.stderr)
             sys.exit(1)
         else:
             _additional_params.append(next[0])
 
-    elif arg in ["--verbose", "--quiet"]:
+    elif arg in ["--help", "--credits", "--verbose", "--quiet", "--extract"]:
         _additional_params.append(arg)
 
         
     else:
         print_err_header()
-        print("Unknown argument: " + arg)
+        print("Unknown argument: " + arg, file=sys.stderr)
         sys.exit(1)
     
     
@@ -120,9 +141,14 @@ def handle_data(data):
         _additional_data.append(str(data))
 
 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):
@@ -194,9 +220,17 @@ def main(argv):
         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:
         print_help()
-        return(1)
+        sys.exit(1)
     
     # Okay, now actually begin doing stuff.
     # This function gets told what to do and gets additional data (filenames).
diff --git a/DeDRM_plugin/standalone/passhash.py b/DeDRM_plugin/standalone/passhash.py
new file mode 100644 (file)
index 0000000..215f283
--- /dev/null
@@ -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!")
\ No newline at end of file