示例#1
0
def securityFileSourceFile(cntlr, ownerObject, filepath, binary, stripDeclaration):
    # handle FileSource file requests which can return encrypted contents
    if ownerObject.hasEncryption:
        for entrypointfile in ownerObject.entrypointfiles:
            if (filepath == entrypointfile.get("file") or 
                any(filepath == ixfile.get("file") for ixfile in entrypointfile.get("ixds",()))
                ) and "key" in entrypointfile and "iv" in entrypointfile:
                ownerObject.cipherIv = base64.decodebytes(entrypointfile["iv"].encode())
                ownerObject.cipherKey = base64.decodebytes(entrypointfile["key"].encode())
                break # set new iv, key based on entrypointfiles
        # may be a non-entry file (xsd, linkbase, jpg) using entry's iv, key
        if os.path.exists(filepath + ENCRYPTED_FILE_SUFFIX) and ownerObject.cipherKey is not None and ownerObject.cipherIv is not None:
            encrdata = io.open(filepath + ENCRYPTED_FILE_SUFFIX, "rb").read()
            cipher = AES.new(ownerObject.cipherKey, AES.MODE_CBC, iv=ownerObject.cipherIv)
            bytesdata = cipher.decrypt(encrdata)
            encrdata = None # dereference before decode operation
            if binary: # return bytes
                return (FileSource.FileNamedBytesIO(filepath, bytesdata[0:-bytesdata[-1]]), ) # trim AES CBC padding
            # detect encoding if there is an XML header
            encoding = XmlUtil.encoding(bytesdata[0:512], 
                                        default=cntlr.modelManager.disclosureSystem.defaultXmlEncoding
                                                if cntlr else 'utf-8')
            # return decoded string
            text = bytesdata[0:-bytesdata[-1]].decode(encoding or 'utf-8') # trim AES CBC padding and decode
            bytesdata = None # dereference before text operation
            if stripDeclaration: # file source may strip XML declaration for libxml
                xmlDeclarationMatch = FileSource.XMLdeclaration.search(text)
                if xmlDeclarationMatch: # remove it for lxml
                    start,end = xmlDeclarationMatch.span()
                    text = text[0:start] + text[end:]
            return (FileSource.FileNamedStringIO(filepath, initial_value=text), encoding)
    return None