mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Bug 1382251: Part 9 - Hook functions needed for SSL communication in NPAPI process; r=jimm
Adds Win32 networking APIs to the function broker so that we can run SSL communications outside of the sandbox.
This commit is contained in:
parent
cc15f3d517
commit
8b000b81a9
@ -10,6 +10,7 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <commdlg.h>
|
||||
#include <schannel.h>
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
using namespace mozilla;
|
||||
@ -128,12 +129,774 @@ BOOL GetOpenFileNameWFB::RunFunction(GetOpenFileNameWFB::FunctionType* aOrigFunc
|
||||
template<> template<>
|
||||
struct GetOpenFileNameWFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
|
||||
/* InternetOpenA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetOpenA,
|
||||
decltype(InternetOpenA)> InternetOpenAFB;
|
||||
|
||||
/* InternetConnectA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetConnectA,
|
||||
decltype(InternetConnectA)> InternetConnectAFB;
|
||||
|
||||
typedef InternetConnectAFB::Request ICAReqHandler;
|
||||
|
||||
template<>
|
||||
bool ICAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const LPCSTR& srv, const INTERNET_PORT& port,
|
||||
const LPCSTR& user, const LPCSTR& pass,
|
||||
const DWORD& svc, const DWORD& flags,
|
||||
const DWORD_PTR& cxt)
|
||||
{
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* InternetCloseHandle */
|
||||
|
||||
typedef FunctionBroker<ID_InternetCloseHandle,
|
||||
decltype(InternetCloseHandle)> InternetCloseHandleFB;
|
||||
|
||||
typedef InternetCloseHandleFB::Request ICHReqHandler;
|
||||
|
||||
template<>
|
||||
bool ICHReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h)
|
||||
{
|
||||
// If we are server side then we were already validated since we had to be
|
||||
// looked up in the "uint64_t <-> HINTERNET" hashtable.
|
||||
// In the client, we check that this is a dummy handle.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* InternetQueryDataAvailable */
|
||||
|
||||
typedef FunctionBroker<ID_InternetQueryDataAvailable,
|
||||
decltype(InternetQueryDataAvailable)> InternetQueryDataAvailableFB;
|
||||
|
||||
typedef InternetQueryDataAvailableFB::Request IQDAReq;
|
||||
|
||||
typedef struct RequestHandler<ID_InternetQueryDataAvailable,
|
||||
BOOL HOOK_CALL (HINTERNET)> IQDADelegateReq;
|
||||
|
||||
template<>
|
||||
void IQDAReq::Marshal(IpdlTuple& aTuple, const HINTERNET& file,
|
||||
const LPDWORD& nBytes, const DWORD& flags,
|
||||
const DWORD_PTR& cxt)
|
||||
{
|
||||
IQDADelegateReq::Marshal(aTuple, file);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IQDAReq::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& file,
|
||||
LPDWORD& nBytes, DWORD& flags, DWORD_PTR& cxt)
|
||||
{
|
||||
bool success = IQDADelegateReq::Unmarshal(aScd, aTuple, file);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
flags = 0;
|
||||
cxt = 0;
|
||||
nBytes = aScd.Allocate<DWORD>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IQDAReq::ShouldBroker(Endpoint endpoint, const HINTERNET& file,
|
||||
const LPDWORD& nBytes, const DWORD& flags,
|
||||
const DWORD_PTR& cxt)
|
||||
{
|
||||
// If we are server side then we were already validated since we had to be
|
||||
// looked up in the "uint64_t <-> HINTERNET" hashtable.
|
||||
// In the client, we check that this is a dummy handle.
|
||||
return (endpoint == SERVER) ||
|
||||
((flags == 0) && (cxt == 0) &&
|
||||
IsOdd(reinterpret_cast<uint64_t>(file)));
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
struct InternetQueryDataAvailableFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
|
||||
|
||||
/* InternetReadFile */
|
||||
|
||||
typedef FunctionBroker<ID_InternetReadFile,
|
||||
decltype(InternetReadFile)> InternetReadFileFB;
|
||||
|
||||
typedef InternetReadFileFB::Request IRFRequestHandler;
|
||||
typedef struct RequestHandler<ID_InternetReadFile,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD)> IRFDelegateReq;
|
||||
|
||||
template<>
|
||||
void IRFRequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
const LPVOID& buf, const DWORD& nBytesToRead,
|
||||
const LPDWORD& nBytesRead)
|
||||
{
|
||||
IRFDelegateReq::Marshal(aTuple, h, nBytesToRead);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
bool IRFRequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
LPVOID& buf, DWORD& nBytesToRead,
|
||||
LPDWORD& nBytesRead)
|
||||
{
|
||||
bool ret = IRFDelegateReq::Unmarshal(aScd, aTuple, h, nBytesToRead);
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nBytesRead = aScd.Allocate<DWORD>();
|
||||
MOZ_ASSERT(nBytesToRead > 0);
|
||||
aScd.AllocateMemory(nBytesToRead, buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IRFRequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const LPVOID& buf, const DWORD& nBytesToRead,
|
||||
const LPDWORD& nBytesRead)
|
||||
{
|
||||
// For server-side validation, the HINTERNET deserialization will have
|
||||
// required it to already be looked up in the IdToPtrMap. At that point,
|
||||
// any call is valid.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
// Marshal the output parameter that we sent to the response delegate.
|
||||
template<> template<>
|
||||
struct InternetReadFileFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
|
||||
typedef ResponseHandler<ID_InternetReadFile, decltype(InternetReadFile)> IRFResponseHandler;
|
||||
typedef ResponseHandler<ID_InternetReadFile,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring)> IRFDelegateResponseHandler;
|
||||
|
||||
template<>
|
||||
void IRFResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
const LPVOID& buf, const DWORD& nBytesToRead,
|
||||
const LPDWORD& nBytesRead)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
if (*nBytesRead) {
|
||||
str.Assign(static_cast<const char*>(buf), *nBytesRead);
|
||||
}
|
||||
IRFDelegateResponseHandler::Marshal(aTuple, ret, str);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IRFResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
|
||||
LPVOID& buf, DWORD& nBytesToRead,
|
||||
LPDWORD& nBytesRead)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
bool success =
|
||||
IRFDelegateResponseHandler::Unmarshal(aTuple, ret, str);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str.Length()) {
|
||||
memcpy(buf, str.Data(), str.Length());
|
||||
*nBytesRead = str.Length();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* InternetWriteFile */
|
||||
|
||||
typedef FunctionBroker<ID_InternetWriteFile,
|
||||
decltype(InternetWriteFile)> InternetWriteFileFB;
|
||||
|
||||
typedef InternetWriteFileFB::Request IWFReqHandler;
|
||||
typedef RequestHandler<ID_InternetWriteFile,
|
||||
int HOOK_CALL (HINTERNET, nsDependentCSubstring)> IWFDelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void IWFReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& file, const LPCVOID& buf,
|
||||
const DWORD& nToWrite, const LPDWORD& nWritten)
|
||||
{
|
||||
MOZ_ASSERT(nWritten);
|
||||
IWFDelegateReqHandler::Marshal(aTuple, file,
|
||||
nsDependentCSubstring(static_cast<const char*>(buf), nToWrite));
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IWFReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& file,
|
||||
LPCVOID& buf, DWORD& nToWrite, LPDWORD& nWritten)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
if (!IWFDelegateReqHandler::Unmarshal(aScd, aTuple, file, str)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aScd.AllocateString(str, buf, false);
|
||||
nToWrite = str.Length();
|
||||
nWritten = aScd.Allocate<DWORD>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IWFReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& file,
|
||||
const LPCVOID& buf, const DWORD& nToWrite,
|
||||
const LPDWORD& nWritten)
|
||||
{
|
||||
// For server-side validation, the HINTERNET deserialization will have
|
||||
// required it to already be looked up in the IdToPtrMap. At that point,
|
||||
// any call is valid.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(file));
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
struct InternetWriteFileFB::Response::Info::ShouldMarshal<3> { static const bool value = true; };
|
||||
|
||||
/* InternetSetOptionA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetSetOptionA,
|
||||
decltype(InternetSetOptionA)> InternetSetOptionAFB;
|
||||
|
||||
typedef InternetSetOptionAFB::Request ISOAReqHandler;
|
||||
typedef RequestHandler<ID_InternetSetOptionA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, nsDependentCSubstring)> ISOADelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void ISOAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h, const DWORD& opt,
|
||||
const LPVOID& buf, const DWORD& bufLen)
|
||||
{
|
||||
ISOADelegateReqHandler::Marshal(aTuple, h, opt,
|
||||
nsDependentCSubstring(static_cast<const char*>(buf), bufLen));
|
||||
}
|
||||
|
||||
template<>
|
||||
bool ISOAReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
DWORD& opt, LPVOID& buf, DWORD& bufLen)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
if (!ISOADelegateReqHandler::Unmarshal(aScd, aTuple, h, opt, str)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aScd.AllocateString(str, buf, false);
|
||||
bufLen = str.Length();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool ISOAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h, const DWORD& opt,
|
||||
const LPVOID& buf, const DWORD& bufLen)
|
||||
{
|
||||
// For server-side validation, the HINTERNET deserialization will have
|
||||
// required it to already be looked up in the IdToPtrMap. At that point,
|
||||
// any call is valid.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* HttpAddRequestHeadersA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpAddRequestHeadersA,
|
||||
decltype(HttpAddRequestHeadersA)> HttpAddRequestHeadersAFB;
|
||||
|
||||
typedef HttpAddRequestHeadersAFB::Request HARHAReqHandler;
|
||||
|
||||
template<>
|
||||
bool HARHAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const LPCSTR& head, const DWORD& headLen,
|
||||
const DWORD& mods)
|
||||
{
|
||||
// For server-side validation, the HINTERNET deserialization will have
|
||||
// required it to already be looked up in the IdToPtrMap. At that point,
|
||||
// any call is valid.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* HttpOpenRequestA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpOpenRequestA,
|
||||
decltype(HttpOpenRequestA)> HttpOpenRequestAFB;
|
||||
|
||||
typedef HttpOpenRequestAFB::Request HORAReqHandler;
|
||||
typedef RequestHandler<ID_HttpOpenRequestA,
|
||||
HINTERNET HOOK_CALL (HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR,
|
||||
nsTArray<nsCString>, DWORD, DWORD_PTR)> HORADelegateReqHandler;
|
||||
|
||||
template<>
|
||||
void HORAReqHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
const LPCSTR& verb, const LPCSTR& obj,
|
||||
const LPCSTR& ver, const LPCSTR& ref,
|
||||
LPCSTR * const & acceptTypes, const DWORD& flags,
|
||||
const DWORD_PTR& cxt)
|
||||
{
|
||||
nsTArray<nsCString> arrayAcceptTypes;
|
||||
LPCSTR * curAcceptType = acceptTypes;
|
||||
if (curAcceptType) {
|
||||
while (*curAcceptType) {
|
||||
arrayAcceptTypes.AppendElement(nsCString(*curAcceptType));
|
||||
++curAcceptType;
|
||||
}
|
||||
}
|
||||
HORADelegateReqHandler::Marshal(aTuple, h, verb, obj, ver, ref,
|
||||
arrayAcceptTypes, flags, cxt);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HORAReqHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
LPCSTR& verb, LPCSTR& obj, LPCSTR& ver,
|
||||
LPCSTR& ref, LPCSTR *& acceptTypes,
|
||||
DWORD& flags, DWORD_PTR& cxt)
|
||||
{
|
||||
nsTArray<nsCString> arrayAcceptTypes;
|
||||
if (!HORADelegateReqHandler::Unmarshal(aScd, aTuple, h, verb, obj, ver, ref, arrayAcceptTypes, flags, cxt)) {
|
||||
return false;
|
||||
}
|
||||
if (arrayAcceptTypes.Length() == 0) {
|
||||
acceptTypes = nullptr;
|
||||
} else {
|
||||
aScd.AllocateMemory((arrayAcceptTypes.Length() + 1) * sizeof(LPCSTR), acceptTypes);
|
||||
for (size_t i = 0; i < arrayAcceptTypes.Length(); ++i) {
|
||||
aScd.AllocateString(arrayAcceptTypes[i], acceptTypes[i]);
|
||||
}
|
||||
acceptTypes[arrayAcceptTypes.Length()] = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HORAReqHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const LPCSTR& verb, const LPCSTR& obj,
|
||||
const LPCSTR& ver, const LPCSTR& ref,
|
||||
LPCSTR * const & acceptTypes,
|
||||
const DWORD& flags, const DWORD_PTR& cxt)
|
||||
{
|
||||
// For the server-side test, the HINTERNET deserialization will have
|
||||
// required it to already be looked up in the IdToPtrMap. At that point,
|
||||
// any call is valid.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* HttpQueryInfoA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpQueryInfoA,
|
||||
decltype(HttpQueryInfoA)> HttpQueryInfoAFB;
|
||||
|
||||
typedef HttpQueryInfoAFB::Request HQIARequestHandler;
|
||||
typedef RequestHandler<ID_HttpQueryInfoA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, BOOL, DWORD, BOOL,
|
||||
DWORD)> HQIADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void HQIARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
const DWORD& lvl, const LPVOID& buf, const LPDWORD& bufLen,
|
||||
const LPDWORD& idx)
|
||||
{
|
||||
HQIADelegateRequestHandler::Marshal(aTuple, h, lvl,
|
||||
bufLen != nullptr, bufLen ? *bufLen : 0,
|
||||
idx != nullptr, idx ? *idx : 0);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HQIARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
DWORD& lvl, LPVOID& buf, LPDWORD& bufLen,
|
||||
LPDWORD& idx)
|
||||
{
|
||||
BOOL hasBufLen, hasIdx;
|
||||
DWORD tempBufLen, tempIdx;
|
||||
bool success =
|
||||
HQIADelegateRequestHandler::Unmarshal(aScd, aTuple, h, lvl, hasBufLen, tempBufLen, hasIdx, tempIdx);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bufLen = nullptr;
|
||||
if (hasBufLen) {
|
||||
aScd.AllocateMemory(tempBufLen, buf, bufLen);
|
||||
}
|
||||
|
||||
idx = nullptr;
|
||||
if (hasIdx) {
|
||||
idx = aScd.Allocate<DWORD>(tempIdx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HQIARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const DWORD& lvl, const LPVOID& buf,
|
||||
const LPDWORD& bufLen, const LPDWORD& idx)
|
||||
{
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
// Marshal all of the output parameters that we sent to the response delegate.
|
||||
template<> template<>
|
||||
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
template<> template<>
|
||||
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
|
||||
template<> template<>
|
||||
struct HttpQueryInfoAFB::Response::Info::ShouldMarshal<2> { static const bool value = true; };
|
||||
|
||||
typedef HttpQueryInfoAFB::Response HQIAResponseHandler;
|
||||
typedef ResponseHandler<ID_HttpQueryInfoA,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring,
|
||||
DWORD, DWORD)> HQIADelegateResponseHandler;
|
||||
|
||||
template<>
|
||||
void HQIAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
const DWORD& lvl, const LPVOID& buf, const LPDWORD& bufLen,
|
||||
const LPDWORD& idx)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
if (buf && ret) {
|
||||
MOZ_ASSERT(bufLen);
|
||||
str.Assign(static_cast<const char*>(buf), *bufLen);
|
||||
}
|
||||
// Note that we send the bufLen separately to handle the case where buf wasn't
|
||||
// allocated or large enough to hold the entire return value. bufLen is then
|
||||
// the required buffer size.
|
||||
HQIADelegateResponseHandler::Marshal(aTuple, ret, str,
|
||||
bufLen ? *bufLen : 0, idx ? *idx : 0);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HQIAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
|
||||
DWORD& lvl, LPVOID& buf, LPDWORD& bufLen,
|
||||
LPDWORD& idx)
|
||||
{
|
||||
DWORD totalBufLen = *bufLen;
|
||||
nsDependentCSubstring str;
|
||||
DWORD tempBufLen, tempIdx;
|
||||
bool success =
|
||||
HQIADelegateResponseHandler::Unmarshal(aTuple, ret, str, tempBufLen, tempIdx);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bufLen) {
|
||||
*bufLen = tempBufLen;
|
||||
}
|
||||
if (idx) {
|
||||
*idx = tempIdx;
|
||||
}
|
||||
|
||||
if (buf && ret) {
|
||||
// When HttpQueryInfo returns strings, the buffer length will not include
|
||||
// the null terminator. Rather than (brittle-y) trying to determine if the
|
||||
// return buffer is a string, we always tack on a null terminator if the
|
||||
// buffer has room for it.
|
||||
MOZ_ASSERT(str.Length() == *bufLen);
|
||||
memcpy(buf, str.Data(), str.Length());
|
||||
if (str.Length() < totalBufLen) {
|
||||
char* cbuf = static_cast<char*>(buf);
|
||||
cbuf[str.Length()] = '\0';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* HttpSendRequestA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpSendRequestA,
|
||||
decltype(HttpSendRequestA)> HttpSendRequestAFB;
|
||||
|
||||
typedef HttpSendRequestAFB::Request HSRARequestHandler;
|
||||
typedef RequestHandler<ID_HttpSendRequestA,
|
||||
BOOL HOOK_CALL (HINTERNET, nsDependentCSubstring,
|
||||
nsDependentCSubstring)> HSRADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void HSRARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
const LPCSTR& head, const DWORD& headLen,
|
||||
const LPVOID& opt, const DWORD& optLen)
|
||||
{
|
||||
nsDependentCSubstring headStr;
|
||||
headStr.SetIsVoid(head == nullptr);
|
||||
if (head) {
|
||||
// HttpSendRequest allows headLen == -1L for length of a null terminated string.
|
||||
DWORD ncHeadLen = headLen;
|
||||
if (ncHeadLen == -1L) {
|
||||
ncHeadLen = strlen(head);
|
||||
}
|
||||
headStr.Rebind(head, ncHeadLen);
|
||||
}
|
||||
nsDependentCSubstring optStr;
|
||||
optStr.SetIsVoid(opt == nullptr);
|
||||
if (opt) {
|
||||
optStr.Rebind(static_cast<const char*>(opt), optLen);
|
||||
}
|
||||
HSRADelegateRequestHandler::Marshal(aTuple, h, headStr, optStr);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HSRARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
LPCSTR& head, DWORD& headLen, LPVOID& opt,
|
||||
DWORD& optLen)
|
||||
{
|
||||
nsDependentCSubstring headStr;
|
||||
nsDependentCSubstring optStr;
|
||||
bool success = HSRADelegateRequestHandler::Unmarshal(aScd, aTuple, h, headStr, optStr);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (headStr.IsVoid()) {
|
||||
head = nullptr;
|
||||
MOZ_ASSERT(headLen == 0);
|
||||
} else {
|
||||
aScd.AllocateString(headStr, head, false);
|
||||
headLen = headStr.Length();
|
||||
}
|
||||
|
||||
if (optStr.IsVoid()) {
|
||||
opt = nullptr;
|
||||
MOZ_ASSERT(optLen == 0);
|
||||
} else {
|
||||
aScd.AllocateString(optStr, opt, false);
|
||||
optLen = optStr.Length();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool HSRARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const LPCSTR& head, const DWORD& headLen,
|
||||
const LPVOID& opt, const DWORD& optLen)
|
||||
{
|
||||
// If we are server side then we were already validated since we had to be
|
||||
// looked up in the "uint64_t <-> HINTERNET" hashtable.
|
||||
// In the client, we check that this is a dummy handle.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
/* HttpSendRequestExA */
|
||||
|
||||
typedef FunctionBroker<ID_HttpSendRequestExA,
|
||||
decltype(HttpSendRequestExA)> HttpSendRequestExAFB;
|
||||
|
||||
typedef RequestInfo<ID_HttpSendRequestExA> HSRExAReqInfo;
|
||||
|
||||
template<> template<>
|
||||
struct HSRExAReqInfo::FixedValue<2> { static const LPINTERNET_BUFFERSA value; };
|
||||
const LPINTERNET_BUFFERSA HSRExAReqInfo::FixedValue<2>::value = nullptr;
|
||||
|
||||
// Docs for HttpSendRequestExA say this parameter 'must' be zero but Flash
|
||||
// passes other values.
|
||||
// template<> template<>
|
||||
// struct HSRExAReqInfo::FixedValue<3> { static const DWORD value = 0; };
|
||||
|
||||
template<> template<>
|
||||
struct HSRExAReqInfo::FixedValue<4> { static const DWORD_PTR value; };
|
||||
const DWORD_PTR HSRExAReqInfo::FixedValue<4>::value = 0;
|
||||
|
||||
/* InternetQueryOptionA */
|
||||
|
||||
typedef FunctionBroker<ID_InternetQueryOptionA,
|
||||
decltype(InternetQueryOptionA)> InternetQueryOptionAFB;
|
||||
|
||||
typedef InternetQueryOptionAFB::Request IQOARequestHandler;
|
||||
typedef RequestHandler<ID_InternetQueryOptionA,
|
||||
BOOL HOOK_CALL (HINTERNET, DWORD, DWORD)> IQOADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void IQOARequestHandler::Marshal(IpdlTuple& aTuple, const HINTERNET& h,
|
||||
const DWORD& opt, const LPVOID& buf, const LPDWORD& bufLen)
|
||||
{
|
||||
MOZ_ASSERT(bufLen);
|
||||
IQOADelegateRequestHandler::Marshal(aTuple, h, opt, buf ? *bufLen : 0);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IQOARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, HINTERNET& h,
|
||||
DWORD& opt, LPVOID& buf, LPDWORD& bufLen)
|
||||
{
|
||||
DWORD tempBufLen;
|
||||
bool success =
|
||||
IQOADelegateRequestHandler::Unmarshal(aScd, aTuple, h, opt, tempBufLen);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aScd.AllocateMemory(tempBufLen, buf, bufLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IQOARequestHandler::ShouldBroker(Endpoint endpoint, const HINTERNET& h,
|
||||
const DWORD& opt, const LPVOID& buf,
|
||||
const LPDWORD& bufLen)
|
||||
{
|
||||
// If we are server side then we were already validated since we had to be
|
||||
// looked up in the "uint64_t <-> HINTERNET" hashtable.
|
||||
// In the client, we check that this is a dummy handle.
|
||||
return (endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h));
|
||||
}
|
||||
|
||||
// Marshal all of the output parameters that we sent to the response delegate.
|
||||
template<> template<>
|
||||
struct InternetQueryOptionAFB::Response::Info::ShouldMarshal<0> { static const bool value = true; };
|
||||
template<> template<>
|
||||
struct InternetQueryOptionAFB::Response::Info::ShouldMarshal<1> { static const bool value = true; };
|
||||
|
||||
typedef InternetQueryOptionAFB::Response IQOAResponseHandler;
|
||||
typedef ResponseHandler<ID_InternetQueryOptionA,
|
||||
BOOL HOOK_CALL (nsDependentCSubstring, DWORD)> IQOADelegateResponseHandler;
|
||||
|
||||
template<>
|
||||
void IQOAResponseHandler::Marshal(IpdlTuple& aTuple, const BOOL& ret, const HINTERNET& h,
|
||||
const DWORD& opt, const LPVOID& buf, const LPDWORD& bufLen)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
if (buf && ret) {
|
||||
MOZ_ASSERT(*bufLen);
|
||||
str.Assign(static_cast<const char*>(buf), *bufLen);
|
||||
}
|
||||
IQOADelegateResponseHandler::Marshal(aTuple, ret, str, *bufLen);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool IQOAResponseHandler::Unmarshal(const IpdlTuple& aTuple, BOOL& ret, HINTERNET& h,
|
||||
DWORD& opt, LPVOID& buf, LPDWORD& bufLen)
|
||||
{
|
||||
nsDependentCSubstring str;
|
||||
bool success =
|
||||
IQOADelegateResponseHandler::Unmarshal(aTuple, ret, str, *bufLen);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf && ret) {
|
||||
MOZ_ASSERT(str.Length() == *bufLen);
|
||||
memcpy(buf, str.Data(), str.Length());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* InternetErrorDlg */
|
||||
|
||||
typedef FunctionBroker<ID_InternetErrorDlg,
|
||||
decltype(InternetErrorDlg)> InternetErrorDlgFB;
|
||||
|
||||
typedef RequestInfo<ID_InternetErrorDlg> IEDReqInfo;
|
||||
|
||||
template<> template<>
|
||||
struct IEDReqInfo::FixedValue<4> { static LPVOID* const value; };
|
||||
LPVOID* const IEDReqInfo::FixedValue<4>::value = nullptr;
|
||||
|
||||
typedef InternetErrorDlgFB::Request IEDReqHandler;
|
||||
|
||||
template<>
|
||||
bool IEDReqHandler::ShouldBroker(Endpoint endpoint, const HWND& hwnd,
|
||||
const HINTERNET& h, const DWORD& err,
|
||||
const DWORD& flags, LPVOID* const & data)
|
||||
{
|
||||
const DWORD SUPPORTED_FLAGS =
|
||||
FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
|
||||
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_NO_UI;
|
||||
|
||||
// We broker if (1) the handle h is brokered (odd in client),
|
||||
// (2) we support the requested action flags and (3) there is no user
|
||||
// data, which wouldn't make sense for our supported flags anyway.
|
||||
return ((endpoint == SERVER) || IsOdd(reinterpret_cast<uint64_t>(h))) &&
|
||||
(!(flags & ~SUPPORTED_FLAGS)) && (data == nullptr);
|
||||
}
|
||||
|
||||
/* AcquireCredentialsHandleA */
|
||||
|
||||
typedef FunctionBroker<ID_AcquireCredentialsHandleA,
|
||||
decltype(AcquireCredentialsHandleA)> AcquireCredentialsHandleAFB;
|
||||
|
||||
typedef RequestInfo<ID_AcquireCredentialsHandleA> ACHAReqInfo;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<0> { static const LPSTR value; };
|
||||
const LPSTR ACHAReqInfo::FixedValue<0>::value = nullptr;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<1> { static const LPSTR value; };
|
||||
const LPSTR ACHAReqInfo::FixedValue<1>::value = UNISP_NAME_A;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<2> { static const unsigned long value; };
|
||||
const unsigned long ACHAReqInfo::FixedValue<2>::value = SECPKG_CRED_OUTBOUND;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<3> { static void* const value; };
|
||||
void* const ACHAReqInfo::FixedValue<3>::value = nullptr;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<5> { static const SEC_GET_KEY_FN value; };
|
||||
const SEC_GET_KEY_FN ACHAReqInfo::FixedValue<5>::value = nullptr;
|
||||
|
||||
template<> template<>
|
||||
struct ACHAReqInfo::FixedValue<6> { static void* const value; };
|
||||
void* const ACHAReqInfo::FixedValue<6>::value = nullptr;
|
||||
|
||||
typedef AcquireCredentialsHandleAFB::Request ACHARequestHandler;
|
||||
typedef RequestHandler<ID_AcquireCredentialsHandleA,
|
||||
SECURITY_STATUS HOOK_CALL (LPSTR, LPSTR, unsigned long,
|
||||
void*, PSCHANNEL_CRED, SEC_GET_KEY_FN,
|
||||
void*)> ACHADelegateRequestHandler;
|
||||
|
||||
template<>
|
||||
void ACHARequestHandler::Marshal(IpdlTuple& aTuple, const LPSTR& principal,
|
||||
const LPSTR& pkg, const unsigned long& credUse,
|
||||
const PVOID& logonId, const PVOID& auth,
|
||||
const SEC_GET_KEY_FN& getKeyFn,
|
||||
const PVOID& getKeyArg, const PCredHandle& cred,
|
||||
const PTimeStamp& expiry)
|
||||
{
|
||||
const PSCHANNEL_CRED& scCred = reinterpret_cast<const PSCHANNEL_CRED&>(auth);
|
||||
ACHADelegateRequestHandler::Marshal(aTuple, principal, pkg, credUse, logonId,
|
||||
scCred, getKeyFn, getKeyArg);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool ACHARequestHandler::Unmarshal(ServerCallData& aScd, const IpdlTuple& aTuple, LPSTR& principal,
|
||||
LPSTR& pkg, unsigned long& credUse,
|
||||
PVOID& logonId, PVOID& auth, SEC_GET_KEY_FN& getKeyFn,
|
||||
PVOID& getKeyArg, PCredHandle& cred, PTimeStamp& expiry)
|
||||
{
|
||||
PSCHANNEL_CRED& scCred = reinterpret_cast<PSCHANNEL_CRED&>(auth);
|
||||
if (!ACHADelegateRequestHandler::Unmarshal(aScd, aTuple, principal, pkg, credUse,
|
||||
logonId, scCred, getKeyFn, getKeyArg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cred = aScd.Allocate<CredHandle>();
|
||||
expiry = aScd.Allocate<::TimeStamp>();
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef ResponseInfo<ID_AcquireCredentialsHandleA> ACHARspInfo;
|
||||
|
||||
// Response phase must send output parameters
|
||||
template<> template<>
|
||||
struct ACHARspInfo::ShouldMarshal<7> { static const bool value = true; };
|
||||
template<> template<>
|
||||
struct ACHARspInfo::ShouldMarshal<8> { static const bool value = true; };
|
||||
|
||||
/* QueryCredentialsAttributesA */
|
||||
|
||||
typedef FunctionBroker<ID_QueryCredentialsAttributesA,
|
||||
decltype(QueryCredentialsAttributesA)> QueryCredentialsAttributesAFB;
|
||||
|
||||
/* FreeCredentialsHandle */
|
||||
|
||||
typedef FunctionBroker<ID_FreeCredentialsHandle,
|
||||
decltype(FreeCredentialsHandle)> FreeCredentialsHandleFB;
|
||||
|
||||
typedef FreeCredentialsHandleFB::Request FCHReq;
|
||||
|
||||
template<>
|
||||
bool FCHReq::ShouldBroker(Endpoint endpoint, const PCredHandle& h)
|
||||
{
|
||||
// If we are server side then we were already validated since we had to be
|
||||
// looked up in the "uint64_t <-> CredHandle" hashtable.
|
||||
// In the client, we check that this is a dummy handle.
|
||||
return (endpoint == SERVER) ||
|
||||
((h->dwLower == h->dwUpper) && IsOdd(static_cast<uint64_t>(h->dwLower)));
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define FUN_HOOK(x) static_cast<FunctionHook*>(x)
|
||||
|
||||
void
|
||||
AddBrokeredFunctionHooks(FunctionHookArray& aHooks)
|
||||
{
|
||||
@ -149,6 +912,61 @@ AddBrokeredFunctionHooks(FunctionHookArray& aHooks)
|
||||
aHooks[ID_GetOpenFileNameW] =
|
||||
FUN_HOOK(new GetOpenFileNameWFB("comdlg32.dll", "GetOpenFileNameW",
|
||||
&GetOpenFileNameW));
|
||||
aHooks[ID_InternetOpenA] =
|
||||
FUN_HOOK(new InternetOpenAFB("wininet.dll", "InternetOpenA", &InternetOpenA));
|
||||
aHooks[ID_InternetConnectA] =
|
||||
FUN_HOOK(new InternetConnectAFB("wininet.dll", "InternetConnectA",
|
||||
&InternetConnectA));
|
||||
aHooks[ID_InternetCloseHandle] =
|
||||
FUN_HOOK(new InternetCloseHandleFB("wininet.dll", "InternetCloseHandle",
|
||||
&InternetCloseHandle));
|
||||
aHooks[ID_InternetQueryDataAvailable] =
|
||||
FUN_HOOK(new InternetQueryDataAvailableFB("wininet.dll",
|
||||
"InternetQueryDataAvailable",
|
||||
&InternetQueryDataAvailable));
|
||||
aHooks[ID_InternetReadFile] =
|
||||
FUN_HOOK(new InternetReadFileFB("wininet.dll", "InternetReadFile",
|
||||
&InternetReadFile));
|
||||
aHooks[ID_InternetWriteFile] =
|
||||
FUN_HOOK(new InternetWriteFileFB("wininet.dll", "InternetWriteFile",
|
||||
&InternetWriteFile));
|
||||
aHooks[ID_InternetSetOptionA] =
|
||||
FUN_HOOK(new InternetSetOptionAFB("wininet.dll", "InternetSetOptionA",
|
||||
&InternetSetOptionA));
|
||||
aHooks[ID_HttpAddRequestHeadersA] =
|
||||
FUN_HOOK(new HttpAddRequestHeadersAFB("wininet.dll",
|
||||
"HttpAddRequestHeadersA",
|
||||
&HttpAddRequestHeadersA));
|
||||
aHooks[ID_HttpOpenRequestA] =
|
||||
FUN_HOOK(new HttpOpenRequestAFB("wininet.dll", "HttpOpenRequestA",
|
||||
&HttpOpenRequestA));
|
||||
aHooks[ID_HttpQueryInfoA] =
|
||||
FUN_HOOK(new HttpQueryInfoAFB("wininet.dll", "HttpQueryInfoA",
|
||||
&HttpQueryInfoA));
|
||||
aHooks[ID_HttpSendRequestA] =
|
||||
FUN_HOOK(new HttpSendRequestAFB("wininet.dll", "HttpSendRequestA",
|
||||
&HttpSendRequestA));
|
||||
aHooks[ID_HttpSendRequestExA] =
|
||||
FUN_HOOK(new HttpSendRequestExAFB("wininet.dll", "HttpSendRequestExA",
|
||||
&HttpSendRequestExA));
|
||||
aHooks[ID_InternetQueryOptionA] =
|
||||
FUN_HOOK(new InternetQueryOptionAFB("wininet.dll", "InternetQueryOptionA",
|
||||
&InternetQueryOptionA));
|
||||
aHooks[ID_InternetErrorDlg] =
|
||||
FUN_HOOK(new InternetErrorDlgFB("wininet.dll", "InternetErrorDlg",
|
||||
InternetErrorDlg));
|
||||
aHooks[ID_AcquireCredentialsHandleA] =
|
||||
FUN_HOOK(new AcquireCredentialsHandleAFB("sspicli.dll",
|
||||
"AcquireCredentialsHandleA",
|
||||
&AcquireCredentialsHandleA));
|
||||
aHooks[ID_QueryCredentialsAttributesA] =
|
||||
FUN_HOOK(new QueryCredentialsAttributesAFB("sspicli.dll",
|
||||
"QueryCredentialsAttributesA",
|
||||
&QueryCredentialsAttributesA));
|
||||
aHooks[ID_FreeCredentialsHandle] =
|
||||
FUN_HOOK(new FreeCredentialsHandleFB("sspicli.dll",
|
||||
"FreeCredentialsHandle",
|
||||
&FreeCredentialsHandle));
|
||||
#endif // defined(XP_WIN)
|
||||
}
|
||||
|
||||
|
@ -350,6 +350,13 @@ public:
|
||||
aBuf = tempBuf;
|
||||
}
|
||||
|
||||
// Run the given destructor on the given memory, for special cases where
|
||||
// memory is allocated elsewhere but must still be freed.
|
||||
void PostDestructor(void* aMem, DestructorType* aDestructor)
|
||||
{
|
||||
mList.AppendElement(FreeItem(aMem, aDestructor));
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// Allocate memory and a DWORD block-length, storing them in the
|
||||
// corresponding parameters.
|
||||
@ -753,6 +760,20 @@ inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, PSCHANNEL_CRED&
|
||||
Copy(aDest, aSrc);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void EndpointHandler<SERVER>::Copy(ServerCallData* aScd, LPINTERNET_BUFFERSA& aDest, const IPCInternetBuffers& aSrc)
|
||||
{
|
||||
MOZ_ASSERT(!aDest);
|
||||
aSrc.CopyTo(aDest);
|
||||
ServerCallData::DestructorType* destructor =
|
||||
[](void* aObj) {
|
||||
LPINTERNET_BUFFERSA inetBuf = static_cast<LPINTERNET_BUFFERSA>(aObj);
|
||||
IPCInternetBuffers::FreeBuffers(inetBuf);
|
||||
FreeDestructor(inetBuf);
|
||||
};
|
||||
aScd->PostDestructor(aDest, destructor);
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// PhaseHandler is a RequestHandler or a ResponseHandler.
|
||||
|
@ -8,11 +8,29 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
#include <schannel.h>
|
||||
|
||||
/* these defines are missing from mingw headers */
|
||||
#ifndef SP_PROT_TLS1_1_CLIENT
|
||||
#define SP_PROT_TLS1_1_CLIENT 0x00000200
|
||||
#endif
|
||||
|
||||
#ifndef SP_PROT_TLS1_2_CLIENT
|
||||
#define SP_PROT_TLS1_2_CLIENT 0x00000800
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
mozilla::LazyLogModule sPluginHooksLog("PluginHooks");
|
||||
|
||||
static const DWORD SCHANNEL_SUPPORTED_PROTOCOLS =
|
||||
SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
|
||||
|
||||
static const DWORD SCHANNEL_SUPPORTED_FLAGS =
|
||||
SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
|
||||
SCH_CRED_REVOCATION_CHECK_END_CERT;
|
||||
|
||||
void
|
||||
OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn)
|
||||
{
|
||||
@ -203,6 +221,138 @@ OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const
|
||||
aLpofn->nFileExtension = mFileExtension;
|
||||
}
|
||||
|
||||
void
|
||||
IPCSchannelCred::CopyFrom(const PSCHANNEL_CRED& aSCred)
|
||||
{
|
||||
// We assert that the aSCred fields take supported values.
|
||||
// If they do not then we ignore the values we were given.
|
||||
MOZ_ASSERT(aSCred->dwVersion == SCHANNEL_CRED_VERSION);
|
||||
MOZ_ASSERT(aSCred->cCreds == 0);
|
||||
MOZ_ASSERT(aSCred->paCred == nullptr);
|
||||
MOZ_ASSERT(aSCred->hRootStore == nullptr);
|
||||
MOZ_ASSERT(aSCred->cMappers == 0);
|
||||
MOZ_ASSERT(aSCred->aphMappers == nullptr);
|
||||
MOZ_ASSERT(aSCred->cSupportedAlgs == 0);
|
||||
MOZ_ASSERT(aSCred->palgSupportedAlgs == nullptr);
|
||||
MOZ_ASSERT((aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS) ==
|
||||
aSCred->grbitEnabledProtocols);
|
||||
mEnabledProtocols =
|
||||
aSCred->grbitEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
|
||||
mMinStrength = aSCred->dwMinimumCipherStrength;
|
||||
mMaxStrength = aSCred->dwMaximumCipherStrength;
|
||||
MOZ_ASSERT(aSCred->dwSessionLifespan == 0);
|
||||
MOZ_ASSERT((aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS) == aSCred->dwFlags);
|
||||
mFlags = aSCred->dwFlags & SCHANNEL_SUPPORTED_FLAGS;
|
||||
MOZ_ASSERT(aSCred->dwCredFormat == 0);
|
||||
}
|
||||
|
||||
void
|
||||
IPCSchannelCred::CopyTo(PSCHANNEL_CRED& aSCred) const
|
||||
{
|
||||
// Validate values as they come from an untrusted process.
|
||||
memset(aSCred, 0, sizeof(SCHANNEL_CRED));
|
||||
aSCred->dwVersion = SCHANNEL_CRED_VERSION;
|
||||
aSCred->grbitEnabledProtocols =
|
||||
mEnabledProtocols & SCHANNEL_SUPPORTED_PROTOCOLS;
|
||||
aSCred->dwMinimumCipherStrength = mMinStrength;
|
||||
aSCred->dwMaximumCipherStrength = mMaxStrength;
|
||||
aSCred->dwFlags = mFlags & SCHANNEL_SUPPORTED_FLAGS;
|
||||
}
|
||||
|
||||
void
|
||||
IPCInternetBuffers::CopyFrom(const LPINTERNET_BUFFERSA& aBufs)
|
||||
{
|
||||
mBuffers.Clear();
|
||||
|
||||
LPINTERNET_BUFFERSA inetBuf = aBufs;
|
||||
while (inetBuf) {
|
||||
MOZ_ASSERT(inetBuf->dwStructSize == sizeof(INTERNET_BUFFERSA));
|
||||
Buffer* ipcBuf = mBuffers.AppendElement();
|
||||
|
||||
ipcBuf->mHeader.SetIsVoid(inetBuf->lpcszHeader == nullptr);
|
||||
if (inetBuf->lpcszHeader) {
|
||||
ipcBuf->mHeader.Assign(inetBuf->lpcszHeader, inetBuf->dwHeadersLength);
|
||||
}
|
||||
ipcBuf->mHeaderTotal = inetBuf->dwHeadersTotal;
|
||||
|
||||
ipcBuf->mBuffer.SetIsVoid(inetBuf->lpvBuffer == nullptr);
|
||||
if (inetBuf->lpvBuffer) {
|
||||
ipcBuf->mBuffer.Assign(static_cast<char*>(inetBuf->lpvBuffer),
|
||||
inetBuf->dwBufferLength);
|
||||
}
|
||||
ipcBuf->mBufferTotal = inetBuf->dwBufferTotal;
|
||||
inetBuf = inetBuf->Next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IPCInternetBuffers::CopyTo(LPINTERNET_BUFFERSA& aBufs) const
|
||||
{
|
||||
MOZ_ASSERT(!aBufs);
|
||||
|
||||
LPINTERNET_BUFFERSA lastBuf = nullptr;
|
||||
for (size_t idx = 0; idx < mBuffers.Length(); ++idx) {
|
||||
const Buffer& ipcBuf = mBuffers[idx];
|
||||
LPINTERNET_BUFFERSA newBuf =
|
||||
static_cast<LPINTERNET_BUFFERSA>(moz_xcalloc(1, sizeof(INTERNET_BUFFERSA)));
|
||||
if (idx == 0) {
|
||||
aBufs = newBuf;
|
||||
} else {
|
||||
MOZ_ASSERT(lastBuf);
|
||||
lastBuf->Next = newBuf;
|
||||
lastBuf = newBuf;
|
||||
}
|
||||
|
||||
newBuf->dwStructSize = sizeof(INTERNET_BUFFERSA);
|
||||
|
||||
newBuf->dwHeadersTotal = ipcBuf.mHeaderTotal;
|
||||
if (!ipcBuf.mHeader.IsVoid()) {
|
||||
newBuf->lpcszHeader =
|
||||
static_cast<LPCSTR>(moz_xmalloc(ipcBuf.mHeader.Length()));
|
||||
memcpy(const_cast<char*>(newBuf->lpcszHeader), ipcBuf.mHeader.Data(),
|
||||
ipcBuf.mHeader.Length());
|
||||
newBuf->dwHeadersLength = ipcBuf.mHeader.Length();
|
||||
}
|
||||
|
||||
newBuf->dwBufferTotal = ipcBuf.mBufferTotal;
|
||||
if (!ipcBuf.mBuffer.IsVoid()) {
|
||||
newBuf->lpvBuffer = moz_xmalloc(ipcBuf.mBuffer.Length());
|
||||
memcpy(newBuf->lpvBuffer, ipcBuf.mBuffer.Data(),
|
||||
ipcBuf.mBuffer.Length());
|
||||
newBuf->dwBufferLength = ipcBuf.mBuffer.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
IPCInternetBuffers::FreeBuffers(LPINTERNET_BUFFERSA& aBufs)
|
||||
{
|
||||
if (!aBufs) {
|
||||
return;
|
||||
}
|
||||
while (aBufs) {
|
||||
LPINTERNET_BUFFERSA temp = aBufs->Next;
|
||||
free(const_cast<char*>(aBufs->lpcszHeader));
|
||||
free(aBufs->lpvBuffer);
|
||||
free(aBufs);
|
||||
aBufs = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IPCPrintDlg::CopyFrom(const LPPRINTDLGW& aDlg)
|
||||
{
|
||||
// DLP: Trouble -- my prior impl "worked" but didn't return anything
|
||||
// AFAIR. So... ??? But it printed a page!!! How?!
|
||||
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
|
||||
}
|
||||
|
||||
void
|
||||
IPCPrintDlg::CopyTo(LPPRINTDLGW& aDlg) const
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("TODO: DLP:");
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -4,7 +4,13 @@
|
||||
#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 {
|
||||
@ -22,6 +28,24 @@ enum FunctionHookId
|
||||
, 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_InternetQueryOptionA
|
||||
, ID_InternetErrorDlg
|
||||
, ID_AcquireCredentialsHandleA
|
||||
, ID_QueryCredentialsAttributesA
|
||||
, ID_FreeCredentialsHandle
|
||||
, ID_PrintDlgW
|
||||
, ID_FunctionHookCount
|
||||
#else // defined(XP_WIN)
|
||||
ID_FunctionHookCount
|
||||
@ -60,6 +84,8 @@ inline nsCString FormatBlob(const nsACString& aParam)
|
||||
// Values indicate GetOpenFileNameW and GetSaveFileNameW.
|
||||
enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC };
|
||||
|
||||
typedef nsTArray<nsCString> StringArray;
|
||||
|
||||
// IPC-capable version of the Windows OPENFILENAMEW struct.
|
||||
typedef struct _OpenFileNameIPC
|
||||
{
|
||||
@ -133,6 +159,60 @@ typedef struct _OpenFileNameRetIPC
|
||||
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);
|
||||
}
|
||||
};
|
||||
nsTArray<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
|
||||
@ -146,6 +226,9 @@ using mozilla::plugins::FunctionHookId;
|
||||
|
||||
using mozilla::plugins::OpenFileNameIPC;
|
||||
using mozilla::plugins::OpenFileNameRetIPC;
|
||||
using mozilla::plugins::IPCSchannelCred;
|
||||
using mozilla::plugins::IPCInternetBuffers;
|
||||
using mozilla::plugins::IPCPrintDlg;
|
||||
using mozilla::plugins::NativeWindowHandle;
|
||||
using mozilla::plugins::StringArray;
|
||||
|
||||
@ -250,6 +333,118 @@ struct ParamTraits<mozilla::plugins::GetFileNameFunc> :
|
||||
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 <>
|
||||
|
Loading…
Reference in New Issue
Block a user