diff options
Diffstat (limited to 'dom/plugins/ipc/FunctionBrokerIPCUtils.h')
-rw-r--r-- | dom/plugins/ipc/FunctionBrokerIPCUtils.h | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/dom/plugins/ipc/FunctionBrokerIPCUtils.h b/dom/plugins/ipc/FunctionBrokerIPCUtils.h new file mode 100644 index 0000000000..c4b72dbe95 --- /dev/null +++ b/dom/plugins/ipc/FunctionBrokerIPCUtils.h @@ -0,0 +1,436 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef dom_plugins_ipc_functionbrokeripcutils_h +#define dom_plugins_ipc_functionbrokeripcutils_h 1 + +#include "ipc/EnumSerializer.h" +#include "ipc/IPCMessageUtilsSpecializations.h" +#include "PluginMessageUtils.h" + +#if defined(XP_WIN) + +# define SECURITY_WIN32 +# include <security.h> +# include <wininet.h> +# include <schannel.h> +# include <commdlg.h> + +#endif // defined(XP_WIN) + +namespace mozilla { +namespace plugins { + +/** + * This enum represents all of the methods hooked by the main facility in + * BrokerClient. It is used to allow quick lookup in the sFunctionsToHook + * structure. + */ +enum FunctionHookId { +#if defined(XP_WIN) + ID_GetWindowInfo = 0, + ID_GetKeyState, + ID_SetCursorPos, + ID_GetSaveFileNameW, + ID_GetOpenFileNameW, + ID_InternetOpenA, + ID_InternetConnectA, + ID_InternetCloseHandle, + ID_InternetQueryDataAvailable, + ID_InternetReadFile, + ID_InternetWriteFile, + ID_InternetSetOptionA, + ID_HttpAddRequestHeadersA, + ID_HttpOpenRequestA, + ID_HttpQueryInfoA, + ID_HttpSendRequestA, + ID_HttpSendRequestExA, + ID_HttpEndRequestA, + ID_InternetQueryOptionA, + ID_InternetErrorDlg, + ID_AcquireCredentialsHandleA, + ID_QueryCredentialsAttributesA, + ID_FreeCredentialsHandle, + ID_PrintDlgW, + ID_CreateMutexW +# if defined(MOZ_SANDBOX) + , + ID_GetFileAttributesW +# endif // defined(MOZ_SANDBOX) + , + ID_FunctionHookCount +#else // defined(XP_WIN) + ID_FunctionHookCount +#endif // defined(XP_WIN) +}; + +// Max number of bytes to show when logging a blob of raw memory +static const uint32_t MAX_BLOB_CHARS_TO_LOG = 12; + +// Format strings for safe logging despite the fact that they are sometimes +// used as raw binary blobs. +inline nsCString FormatBlob(const nsACString& aParam) { + if (aParam.IsVoid() || aParam.IsEmpty()) { + return nsCString(aParam.IsVoid() ? "<void>" : "<empty>"); + } + + nsCString str; + uint32_t totalLen = std::min(MAX_BLOB_CHARS_TO_LOG, aParam.Length()); + // If we are printing only a portion of the string then follow it with + // ellipsis + const char* maybeEllipsis = + (MAX_BLOB_CHARS_TO_LOG < aParam.Length()) ? "..." : ""; + for (uint32_t idx = 0; idx < totalLen; ++idx) { + // Should be %02x but I've run into a AppendPrintf bug... + str.AppendPrintf("0x%2x ", aParam.Data()[idx] & 0xff); + } + str.AppendPrintf("%s | '", maybeEllipsis); + for (uint32_t idx = 0; idx < totalLen; ++idx) { + str.AppendPrintf("%c", (aParam.Data()[idx] > 0) ? aParam.Data()[idx] : '.'); + } + str.AppendPrintf("'%s", maybeEllipsis); + return str; +} + +#if defined(XP_WIN) + +// Values indicate GetOpenFileNameW and GetSaveFileNameW. +enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC }; + +typedef CopyableTArray<nsCString> StringArray; + +// IPC-capable version of the Windows OPENFILENAMEW struct. +typedef struct _OpenFileNameIPC { + // Allocates memory for the strings in this object. This should usually + // be used with a zeroed out OPENFILENAMEW structure. + void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const; + static void FreeOfnStrings(LPOPENFILENAMEW aLpofn); + void AddToOfn(LPOPENFILENAMEW aLpofn) const; + void CopyFromOfn(LPOPENFILENAMEW aLpofn); + bool operator==(const _OpenFileNameIPC& o) const { + return (o.mHwndOwner == mHwndOwner) && (o.mFilter == mFilter) && + (o.mHasFilter == mHasFilter) && + (o.mCustomFilterIn == mCustomFilterIn) && + (o.mHasCustomFilter == mHasCustomFilter) && + (o.mNMaxCustFilterOut == mNMaxCustFilterOut) && + (o.mFilterIndex == mFilterIndex) && (o.mFile == mFile) && + (o.mNMaxFile == mNMaxFile) && (o.mNMaxFileTitle == mNMaxFileTitle) && + (o.mInitialDir == mInitialDir) && + (o.mHasInitialDir == mHasInitialDir) && (o.mTitle == mTitle) && + (o.mHasTitle == mHasTitle) && (o.mFlags == mFlags) && + (o.mDefExt == mDefExt) && (o.mHasDefExt == mHasDefExt) && + (o.mFlagsEx == mFlagsEx); + } + + NativeWindowHandle mHwndOwner; + std::wstring + mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true + bool mHasFilter; + std::wstring mCustomFilterIn; + bool mHasCustomFilter; + uint32_t mNMaxCustFilterOut; + uint32_t mFilterIndex; + std::wstring mFile; + uint32_t mNMaxFile; + uint32_t mNMaxFileTitle; + std::wstring mInitialDir; + bool mHasInitialDir; + std::wstring mTitle; + bool mHasTitle; + uint32_t mFlags; + std::wstring mDefExt; + bool mHasDefExt; + uint32_t mFlagsEx; +} OpenFileNameIPC; + +// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW +// parameter. This represents those values so that they can be returned via +// IPC. +typedef struct _OpenFileNameRetIPC { + void CopyFromOfn(LPOPENFILENAMEW aLpofn); + void AddToOfn(LPOPENFILENAMEW aLpofn) const; + bool operator==(const _OpenFileNameRetIPC& o) const { + return (o.mCustomFilterOut == mCustomFilterOut) && (o.mFile == mFile) && + (o.mFileTitle == mFileTitle) && (o.mFileOffset == mFileOffset) && + (o.mFileExtension == mFileExtension); + } + + std::wstring mCustomFilterOut; + std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0") + std::wstring mFileTitle; + uint16_t mFileOffset; + uint16_t mFileExtension; +} OpenFileNameRetIPC; + +typedef struct _IPCSchannelCred { + void CopyFrom(const PSCHANNEL_CRED& aSCred); + void CopyTo(PSCHANNEL_CRED& aSCred) const; + bool operator==(const _IPCSchannelCred& o) const { + return (o.mEnabledProtocols == mEnabledProtocols) && + (o.mMinStrength == mMinStrength) && + (o.mMaxStrength == mMaxStrength) && (o.mFlags == mFlags); + } + + DWORD mEnabledProtocols; + DWORD mMinStrength; + DWORD mMaxStrength; + DWORD mFlags; +} IPCSchannelCred; + +typedef struct _IPCInternetBuffers { + void CopyFrom(const LPINTERNET_BUFFERSA& aBufs); + void CopyTo(LPINTERNET_BUFFERSA& aBufs) const; + bool operator==(const _IPCInternetBuffers& o) const { + return o.mBuffers == mBuffers; + } + static void FreeBuffers(LPINTERNET_BUFFERSA& aBufs); + + struct Buffer { + nsCString mHeader; + uint32_t mHeaderTotal; + nsCString mBuffer; + uint32_t mBufferTotal; + bool operator==(const Buffer& o) const { + return (o.mHeader == mHeader) && (o.mHeaderTotal == mHeaderTotal) && + (o.mBuffer == mBuffer) && (o.mBufferTotal == mBufferTotal); + } + }; + CopyableTArray<Buffer> mBuffers; +} IPCInternetBuffers; + +typedef struct _IPCPrintDlg { + void CopyFrom(const LPPRINTDLGW& aDlg); + void CopyTo(LPPRINTDLGW& aDlg) const; + bool operator==(const _IPCPrintDlg& o) const { + MOZ_ASSERT_UNREACHABLE("DLP: TODO:"); + return false; + } +} IPCPrintDlg; + +#endif // defined(XP_WIN) + +} // namespace plugins +} // namespace mozilla + +namespace IPC { + +using mozilla::plugins::FunctionHookId; + +#if defined(XP_WIN) + +using mozilla::plugins::IPCInternetBuffers; +using mozilla::plugins::IPCPrintDlg; +using mozilla::plugins::IPCSchannelCred; +using mozilla::plugins::NativeWindowHandle; +using mozilla::plugins::OpenFileNameIPC; +using mozilla::plugins::OpenFileNameRetIPC; +using mozilla::plugins::StringArray; + +template <> +struct ParamTraits<OpenFileNameIPC> { + typedef OpenFileNameIPC paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mHwndOwner); + WriteParam(aMsg, aParam.mFilter); + WriteParam(aMsg, aParam.mHasFilter); + WriteParam(aMsg, aParam.mCustomFilterIn); + WriteParam(aMsg, aParam.mHasCustomFilter); + WriteParam(aMsg, aParam.mNMaxCustFilterOut); + WriteParam(aMsg, aParam.mFilterIndex); + WriteParam(aMsg, aParam.mFile); + WriteParam(aMsg, aParam.mNMaxFile); + WriteParam(aMsg, aParam.mNMaxFileTitle); + WriteParam(aMsg, aParam.mInitialDir); + WriteParam(aMsg, aParam.mHasInitialDir); + WriteParam(aMsg, aParam.mTitle); + WriteParam(aMsg, aParam.mHasTitle); + WriteParam(aMsg, aParam.mFlags); + WriteParam(aMsg, aParam.mDefExt); + WriteParam(aMsg, aParam.mHasDefExt); + WriteParam(aMsg, aParam.mFlagsEx); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) && + ReadParam(aMsg, aIter, &aResult->mFilter) && + ReadParam(aMsg, aIter, &aResult->mHasFilter) && + ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) && + ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) && + ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) && + ReadParam(aMsg, aIter, &aResult->mFilterIndex) && + ReadParam(aMsg, aIter, &aResult->mFile) && + ReadParam(aMsg, aIter, &aResult->mNMaxFile) && + ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) && + ReadParam(aMsg, aIter, &aResult->mInitialDir) && + ReadParam(aMsg, aIter, &aResult->mHasInitialDir) && + ReadParam(aMsg, aIter, &aResult->mTitle) && + ReadParam(aMsg, aIter, &aResult->mHasTitle) && + ReadParam(aMsg, aIter, &aResult->mFlags) && + ReadParam(aMsg, aIter, &aResult->mDefExt) && + ReadParam(aMsg, aIter, &aResult->mHasDefExt) && + ReadParam(aMsg, aIter, &aResult->mFlagsEx)) { + return true; + } + return false; + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + aLog->append(StringPrintf(L"[%ls, %ls, %ls, %ls]", aParam.mFilter.c_str(), + aParam.mCustomFilterIn.c_str(), + aParam.mFile.c_str(), aParam.mTitle.c_str())); + } +}; + +template <> +struct ParamTraits<OpenFileNameRetIPC> { + typedef OpenFileNameRetIPC paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mCustomFilterOut); + WriteParam(aMsg, aParam.mFile); + WriteParam(aMsg, aParam.mFileTitle); + WriteParam(aMsg, aParam.mFileOffset); + WriteParam(aMsg, aParam.mFileExtension); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) && + ReadParam(aMsg, aIter, &aResult->mFile) && + ReadParam(aMsg, aIter, &aResult->mFileTitle) && + ReadParam(aMsg, aIter, &aResult->mFileOffset) && + ReadParam(aMsg, aIter, &aResult->mFileExtension)) { + return true; + } + return false; + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + aLog->append(StringPrintf(L"[%ls, %ls, %ls, %d, %d]", + aParam.mCustomFilterOut.c_str(), + aParam.mFile.c_str(), aParam.mFileTitle.c_str(), + aParam.mFileOffset, aParam.mFileExtension)); + } +}; + +template <> +struct ParamTraits<mozilla::plugins::GetFileNameFunc> + : public ContiguousEnumSerializerInclusive< + mozilla::plugins::GetFileNameFunc, mozilla::plugins::OPEN_FUNC, + mozilla::plugins::SAVE_FUNC> {}; + +template <> +struct ParamTraits<IPCSchannelCred> { + typedef mozilla::plugins::IPCSchannelCred paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, static_cast<uint32_t>(aParam.mEnabledProtocols)); + WriteParam(aMsg, static_cast<uint32_t>(aParam.mMinStrength)); + WriteParam(aMsg, static_cast<uint32_t>(aParam.mMaxStrength)); + WriteParam(aMsg, static_cast<uint32_t>(aParam.mFlags)); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + uint32_t proto, minStr, maxStr, flags; + if (!ReadParam(aMsg, aIter, &proto) || !ReadParam(aMsg, aIter, &minStr) || + !ReadParam(aMsg, aIter, &maxStr) || !ReadParam(aMsg, aIter, &flags)) { + return false; + } + aResult->mEnabledProtocols = proto; + aResult->mMinStrength = minStr; + aResult->mMaxStrength = maxStr; + aResult->mFlags = flags; + return true; + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + aLog->append(StringPrintf(L"[%d,%d,%d,%d]", aParam.mEnabledProtocols, + aParam.mMinStrength, aParam.mMaxStrength, + aParam.mFlags)); + } +}; + +template <> +struct ParamTraits<IPCInternetBuffers::Buffer> { + typedef mozilla::plugins::IPCInternetBuffers::Buffer paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mHeader); + WriteParam(aMsg, aParam.mHeaderTotal); + WriteParam(aMsg, aParam.mBuffer); + WriteParam(aMsg, aParam.mBufferTotal); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + return ReadParam(aMsg, aIter, &aResult->mHeader) && + ReadParam(aMsg, aIter, &aResult->mHeaderTotal) && + ReadParam(aMsg, aIter, &aResult->mBuffer) && + ReadParam(aMsg, aIter, &aResult->mBufferTotal); + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + nsCString head = mozilla::plugins::FormatBlob(aParam.mHeader); + nsCString buffer = mozilla::plugins::FormatBlob(aParam.mBuffer); + std::string msg = + StringPrintf("[%s, %d, %s, %d]", head.Data(), aParam.mHeaderTotal, + buffer.Data(), aParam.mBufferTotal); + aLog->append(msg.begin(), msg.end()); + } +}; + +template <> +struct ParamTraits<IPCInternetBuffers> { + typedef mozilla::plugins::IPCInternetBuffers paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + WriteParam(aMsg, aParam.mBuffers); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + return ReadParam(aMsg, aIter, &aResult->mBuffers); + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + ParamTraits<nsTArray<IPCInternetBuffers::Buffer>>::Log(aParam.mBuffers, + aLog); + } +}; + +template <> +struct ParamTraits<IPCPrintDlg> { + typedef mozilla::plugins::IPCPrintDlg paramType; + + static void Write(Message* aMsg, const paramType& aParam) { + MOZ_ASSERT_UNREACHABLE("TODO: DLP:"); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, + paramType* aResult) { + MOZ_ASSERT_UNREACHABLE("TODO: DLP:"); + return true; + } + + static void Log(const paramType& aParam, std::wstring* aLog) { + MOZ_ASSERT_UNREACHABLE("TODO: DLP:"); + } +}; + +#endif // defined(XP_WIN) + +template <> +struct ParamTraits<FunctionHookId> + : public ContiguousEnumSerializer<FunctionHookId, + static_cast<FunctionHookId>(0), + FunctionHookId::ID_FunctionHookCount> {}; + +} // namespace IPC + +#endif /* dom_plugins_ipc_functionbrokeripcutils_h */ |