Пример #1
0
    def ePubDecrypt(self, path_to_ebook):
        # Create a TemporaryPersistent file to work with.
        # Check original epub archive for zip errors.
        import calibre_plugins.dedrm.zipfix

        inf = self.temporary_file(".epub")
        try:
            print("{0} v{1}: Verifying zip archive integrity".format(
                PLUGIN_NAME, PLUGIN_VERSION))
            fr = zipfix.fixZip(path_to_ebook, inf.name)
            fr.fix()
        except Exception as e:
            print("{0} v{1}: Error \'{2}\' when checking zip archive".format(
                PLUGIN_NAME, PLUGIN_VERSION, e.args[0]))
            raise Exception(e)

        # import the decryption keys
        import calibre_plugins.dedrm.prefs as prefs
        dedrmprefs = prefs.DeDRM_Prefs()

        # import the Barnes & Noble ePub handler
        import calibre_plugins.dedrm.ignobleepub as ignobleepub

        #check the book
        if ignobleepub.ignobleBook(inf.name):
            print("{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format(
                PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))

            # Attempt to decrypt epub with each encryption key (generated or provided).
            for keyname, userkey in dedrmprefs['bandnkeys'].items():
                keyname_masked = "".join(
                    ("X" if (x.isdigit()) else x) for x in keyname)
                print("{0} v{1}: Trying Encryption key {2:s}".format(
                    PLUGIN_NAME, PLUGIN_VERSION, keyname_masked))
                of = self.temporary_file(".epub")

                # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                try:
                    result = ignobleepub.decryptBook(userkey, inf.name,
                                                     of.name)
                except:
                    print(
                        "{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds"
                        .format(PLUGIN_NAME, PLUGIN_VERSION,
                                time.time() - self.starttime))
                    traceback.print_exc()
                    result = 1

                of.close()

                if result == 0:
                    # Decryption was successful.
                    # Return the modified PersistentTemporary file to calibre.
                    return of.name

                print(
                    "{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds"
                    .format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked,
                            time.time() - self.starttime))

            # perhaps we should see if we can get a key from a log file
            print(
                "{0} v{1}: Looking for new NOOK Study Keys after {2:.1f} seconds"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))

            # get the default NOOK Study keys
            defaultkeys = []

            try:
                if iswindows or isosx:
                    from calibre_plugins.dedrm.ignoblekey import nookkeys

                    defaultkeys = nookkeys()
                else:  # linux
                    from .wineutils import WineGetKeys

                    scriptpath = os.path.join(self.alfdir, "ignoblekey.py")
                    defaultkeys = WineGetKeys(scriptpath, ".b64",
                                              dedrmprefs['adobewineprefix'])

            except:
                print(
                    "{0} v{1}: Exception when getting default NOOK Study Key after {2:.1f} seconds"
                    .format(PLUGIN_NAME, PLUGIN_VERSION,
                            time.time() - self.starttime))
                traceback.print_exc()

            newkeys = []
            for keyvalue in defaultkeys:
                if keyvalue not in dedrmprefs['bandnkeys'].values():
                    newkeys.append(keyvalue)

            if len(newkeys) > 0:
                try:
                    for i, userkey in enumerate(newkeys):
                        print("{0} v{1}: Trying a new default key".format(
                            PLUGIN_NAME, PLUGIN_VERSION))

                        of = self.temporary_file(".epub")

                        # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                        try:
                            result = ignobleepub.decryptBook(
                                userkey, inf.name, of.name)
                        except:
                            print(
                                "{0} v{1}: Exception when trying to decrypt after {2:.1f} seconds"
                                .format(PLUGIN_NAME, PLUGIN_VERSION,
                                        time.time() - self.starttime))
                            traceback.print_exc()
                            result = 1

                        of.close()

                        if result == 0:
                            # Decryption was a success
                            # Store the new successful key in the defaults
                            print("{0} v{1}: Saving a new default key".format(
                                PLUGIN_NAME, PLUGIN_VERSION))
                            try:
                                dedrmprefs.addnamedvaluetoprefs(
                                    'bandnkeys', 'nook_Study_key', keyvalue)
                                dedrmprefs.writeprefs()
                                print(
                                    "{0} v{1}: Saved a new default key after {2:.1f} seconds"
                                    .format(PLUGIN_NAME, PLUGIN_VERSION,
                                            time.time() - self.starttime))
                            except:
                                print(
                                    "{0} v{1}: Exception saving a new default key after {2:.1f} seconds"
                                    .format(PLUGIN_NAME, PLUGIN_VERSION,
                                            time.time() - self.starttime))
                                traceback.print_exc()
                            # Return the modified PersistentTemporary file to calibre.
                            return of.name

                        print(
                            "{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds"
                            .format(PLUGIN_NAME, PLUGIN_VERSION,
                                    time.time() - self.starttime))
                except Exception as e:
                    pass

            print(
                "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))
            raise DeDRMError(
                "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))

        # import the Adobe Adept ePub handler
        import calibre_plugins.dedrm.ineptepub as ineptepub

        if ineptepub.adeptBook(inf.name):
            print("{0} v{1}: {2} is a secure Adobe Adept ePub".format(
                PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)))

            # Attempt to decrypt epub with each encryption key (generated or provided).
            for keyname, userkeyhex in dedrmprefs['adeptkeys'].items():
                userkey = codecs.decode(userkeyhex, 'hex')
                print("{0} v{1}: Trying Encryption key {2:s}".format(
                    PLUGIN_NAME, PLUGIN_VERSION, keyname))
                of = self.temporary_file(".epub")

                # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                try:
                    result = ineptepub.decryptBook(userkey, inf.name, of.name)
                except:
                    print(
                        "{0} v{1}: Exception when decrypting after {2:.1f} seconds"
                        .format(PLUGIN_NAME, PLUGIN_VERSION,
                                time.time() - self.starttime))
                    traceback.print_exc()
                    result = 1

                try:
                    of.close()
                except:
                    print(
                        "{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(
                        "{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(
                    "{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds"
                    .format(PLUGIN_NAME, PLUGIN_VERSION, keyname,
                            time.time() - self.starttime))

            # perhaps we need to get a new default ADE key
            print(
                "{0} v{1}: Looking for new default Adobe Digital Editions Keys after {2:.1f} seconds"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))

            # get the default Adobe keys
            defaultkeys = []

            try:
                if iswindows or isosx:
                    from calibre_plugins.dedrm.adobekey import adeptkeys

                    defaultkeys = adeptkeys()
                else:  # linux
                    from .wineutils import WineGetKeys

                    scriptpath = os.path.join(self.alfdir, "adobekey.py")
                    defaultkeys = WineGetKeys(scriptpath, ".der",
                                              dedrmprefs['adobewineprefix'])

                self.default_key = defaultkeys[0]
            except:
                print(
                    "{0} v{1}: Exception when getting default Adobe Key after {2:.1f} seconds"
                    .format(PLUGIN_NAME, PLUGIN_VERSION,
                            time.time() - self.starttime))
                traceback.print_exc()
                self.default_key = ""

            newkeys = []
            for keyvalue in defaultkeys:
                if codecs.encode(keyvalue, 'hex').decode(
                        'ascii') not in dedrmprefs['adeptkeys'].values():
                    newkeys.append(keyvalue)

            if len(newkeys) > 0:
                try:
                    for i, userkey in enumerate(newkeys):
                        print("{0} v{1}: Trying a new default key".format(
                            PLUGIN_NAME, PLUGIN_VERSION))
                        of = self.temporary_file(".epub")

                        # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                        try:
                            result = ineptepub.decryptBook(
                                userkey, inf.name, of.name)
                        except:
                            print(
                                "{0} v{1}: Exception when decrypting after {2:.1f} seconds"
                                .format(PLUGIN_NAME, PLUGIN_VERSION,
                                        time.time() - self.starttime))
                            traceback.print_exc()
                            result = 1

                        of.close()

                        if result == 0:
                            # Decryption was a success
                            # Store the new successful key in the defaults
                            print("{0} v{1}: Saving a new default key".format(
                                PLUGIN_NAME, PLUGIN_VERSION))
                            try:
                                dedrmprefs.addnamedvaluetoprefs(
                                    'adeptkeys', 'default_key',
                                    codecs.encode(keyvalue,
                                                  'hex').decode('ascii'))
                                dedrmprefs.writeprefs()
                                print(
                                    "{0} v{1}: Saved a new default key after {2:.1f} seconds"
                                    .format(PLUGIN_NAME, PLUGIN_VERSION,
                                            time.time() - self.starttime))
                            except:
                                print(
                                    "{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(
                                "{0} v{1}: Decrypted with new default key after {2:.1f} seconds"
                                .format(PLUGIN_NAME, PLUGIN_VERSION,
                                        time.time() - self.starttime))
                            # Return the modified PersistentTemporary file to calibre.
                            return of.name

                        print(
                            "{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds"
                            .format(PLUGIN_NAME, PLUGIN_VERSION,
                                    time.time() - self.starttime))
                except Exception as e:
                    print(
                        "{0} v{1}: Unexpected Exception trying a new default key after {2:.1f} seconds"
                        .format(PLUGIN_NAME, PLUGIN_VERSION,
                                time.time() - self.starttime))
                    traceback.print_exc()
                    pass

            # Something went wrong with decryption.
            print(
                "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))
            raise DeDRMError(
                "{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md"
                .format(PLUGIN_NAME, PLUGIN_VERSION,
                        time.time() - self.starttime))

        # Not a Barnes & Noble nor an Adobe Adept
        # Import the fixed epub.
        print(
            "{0} v{1}: “{2}” is neither an Adobe Adept nor a Barnes & Noble encrypted ePub"
            .format(PLUGIN_NAME, PLUGIN_VERSION,
                    os.path.basename(path_to_ebook)))
        raise DeDRMError(
            "{0} v{1}: Couldn't decrypt after {2:.1f} seconds. DRM free perhaps?"
            .format(PLUGIN_NAME, PLUGIN_VERSION,
                    time.time() - self.starttime))
Пример #2
0
            fr = zipfix.fixZip(path_to_ebook, inf.name)
            fr.fix()
        except Exception, e:
            print u"{0} v{1}: Error '{2}' when checking zip archive".format(PLUGIN_NAME, PLUGIN_VERSION, e.args[0])
            raise Exception(e)

        # import the decryption keys
        import calibre_plugins.dedrm.prefs as prefs

        dedrmprefs = prefs.DeDRM_Prefs()

        # import the Barnes & Noble ePub handler
        import calibre_plugins.dedrm.ignobleepub as ignobleepub

        # check the book
        if ignobleepub.ignobleBook(inf.name):
            print u"{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format(
                PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook)
            )

            # Attempt to decrypt epub with each encryption key (generated or provided).
            for keyname, userkey in dedrmprefs["bandnkeys"].items():
                keyname_masked = u"".join((u"X" if (x.isdigit()) else x) for x in keyname)
                print u"{0} v{1}: Trying Encryption key {2:s}".format(PLUGIN_NAME, PLUGIN_VERSION, keyname_masked)
                of = self.temporary_file(u".epub")

                # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                result = ignobleepub.decryptBook(userkey, inf.name, of.name)

                of.close()
Пример #3
0
            fr = zipfix.fixZip(path_to_ebook, inf.name)
            fr.fix()
        except Exception, e:
            print u"{0} v{1}: Error \'{2}\' when checking zip archive".format(
                PLUGIN_NAME, PLUGIN_VERSION, e.args[0])
            raise Exception(e)

        # import the decryption keys
        import calibre_plugins.dedrm.prefs as prefs
        dedrmprefs = prefs.DeDRM_Prefs()

        # import the Barnes & Noble ePub handler
        import calibre_plugins.dedrm.ignobleepub as ignobleepub

        #check the book
        if ignobleepub.ignobleBook(inf.name):
            print u"{0} v{1}: “{2}” is a secure Barnes & Noble ePub".format(
                PLUGIN_NAME, PLUGIN_VERSION, os.path.basename(path_to_ebook))

            # Attempt to decrypt epub with each encryption key (generated or provided).
            for keyname, userkey in dedrmprefs['bandnkeys'].items():
                keyname_masked = u"".join(
                    (u'X' if (x.isdigit()) else x) for x in keyname)
                print u"{0} v{1}: Trying Encryption key {2:s}".format(
                    PLUGIN_NAME, PLUGIN_VERSION, keyname_masked)
                of = self.temporary_file(u".epub")

                # Give the user key, ebook and TemporaryPersistent file to the decryption function.
                result = ignobleepub.decryptBook(userkey, inf.name, of.name)

                of.close()
Пример #4
0
def decryptepub(infile, outdir, rscpath):
    errlog = ''

    # first fix the epub to make sure we do not get errors
    name, ext = os.path.splitext(os.path.basename(infile))
    bpath = os.path.dirname(infile)
    zippath = os.path.join(bpath, name + '_temp.zip')
    rv = zipfix.repairBook(infile, zippath)
    if rv != 0:
        print("Error while trying to fix epub")
        return rv

    # determine a good name for the output file
    outfile = os.path.join(outdir, name + '_nodrm.epub')

    rv = 1
    # first try with the Adobe adept epub
    if ineptepub.adeptBook(zippath):
        # try with any keyfiles (*.der) in the rscpath
        files = os.listdir(rscpath)
        filefilter = re.compile("\.der$", re.IGNORECASE)
        files = filter(filefilter.search, files)
        if files:
            for filename in files:
                keypath = os.path.join(rscpath, filename)
                userkey = open(keypath, 'rb').read()
                try:
                    rv = ineptepub.decryptBook(userkey, zippath, outfile)
                    if rv == 0:
                        print("Decrypted Adobe ePub with key file {0}".format(
                            filename))
                        break
                except Exception as e:
                    errlog += traceback.format_exc()
                    errlog += str(e)
                    rv = 1
    # now try with ignoble epub
    elif ignobleepub.ignobleBook(zippath):
        # try with any keyfiles (*.b64) in the rscpath
        files = os.listdir(rscpath)
        filefilter = re.compile("\.b64$", re.IGNORECASE)
        files = filter(filefilter.search, files)
        if files:
            for filename in files:
                keypath = os.path.join(rscpath, filename)
                userkey = open(keypath, 'r').read()
                #print userkey
                try:
                    rv = ignobleepub.decryptBook(userkey, zippath, outfile)
                    if rv == 0:
                        print("Decrypted B&N ePub with key file {0}".format(
                            filename))
                        break
                except Exception as e:
                    errlog += traceback.format_exc()
                    errlog += str(e)
                    rv = 1
    else:
        encryption = epubtest.encryption(zippath)
        if encryption == "Unencrypted":
            print("{0} is not DRMed.".format(name))
            rv = 0
        else:
            print("{0} has an unknown encryption.".format(name))

    os.remove(zippath)
    if rv != 0:
        print(errlog)
    return rv