AutoPushJSContext::AutoPushJSContext(nsISupports* aSecuritySupports, JSContext *cx) : mContext(cx), mPushResult(NS_OK) { mContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if(mContextStack) { JSContext* currentCX; if(NS_SUCCEEDED(mContextStack->Peek(¤tCX))) { // Is the current context already on the stack? if(cx == currentCX) mContextStack = nsnull; else { mContextStack->Push(cx); // Leave the reference to the mContextStack to // indicate that we need to pop it in our dtor. } } } nsCOMPtr<nsIScriptSecurityManager> secMan( do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &mPushResult)); if (NS_FAILED(mPushResult)) return; nsCOMPtr<nsIPrincipal> principal; mPushResult = secMan->GetPrincipalFromContext(cx, getter_AddRefs(principal)); if (NS_FAILED(mPushResult)) { JS_ReportError(cx, "failed to get a principal"); return; } // See if JavaScript is enabled for the current window PRBool jsEnabled = PR_FALSE; mPushResult = secMan->CanExecuteScripts(cx, principal, &jsEnabled); if (!jsEnabled) mPushResult = NS_ERROR_FAILURE; memset(&mFrame, 0, sizeof(mFrame)); if (NS_SUCCEEDED(mPushResult)) { // See if there are any scripts on the stack. // If not, we need to add a dummy frame with a principal. PRBool hasScript = PR_FALSE; JSStackFrame* tempFP = cx->fp; while (tempFP) { if (tempFP->script) { hasScript = PR_TRUE; break; } tempFP = tempFP->down; }; if (!hasScript) { JSPrincipals* jsprinc; principal->GetJSPrincipals(cx, &jsprinc); mFrame.script = JS_CompileScriptForPrincipals(cx, JS_GetGlobalObject(cx), jsprinc, "", 0, "", 1); JSPRINCIPALS_DROP(cx, jsprinc); if (mFrame.script) { mFrame.down = cx->fp; cx->fp = &mFrame; } else mPushResult = NS_ERROR_OUT_OF_MEMORY; } } }
nsresult PeerConnectionMedia::InitProxy() { #if !defined(MOZILLA_EXTERNAL_LINKAGE) // Allow mochitests to disable this, since mochitest configures a fake proxy // that serves up content. bool disable = Preferences::GetBool("media.peerconnection.disable_http_proxy", false); if (disable) { mProxyResolveCompleted = true; return NS_OK; } #endif nsresult rv; nsCOMPtr<nsIProtocolProxyService> pps = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get proxy service: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } // We use the following URL to find the "default" proxy address for all HTTPS // connections. We will only attempt one HTTP(S) CONNECT per peer connection. // "example.com" is guaranteed to be unallocated and should return the best default. nsCOMPtr<nsIURI> fakeHttpsLocation; rv = NS_NewURI(getter_AddRefs(fakeHttpsLocation), "https://example.com"); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to set URI: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIScriptSecurityManager> secMan( do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get IOService: %d", __FUNCTION__, (int)rv); CSFLogError(logTag, "%s: Failed to get securityManager: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIPrincipal> systemPrincipal; rv = secMan->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get systemPrincipal: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIChannel> channel; rv = NS_NewChannel(getter_AddRefs(channel), fakeHttpsLocation, systemPrincipal, nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get channel from URI: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } RefPtr<ProtocolProxyQueryHandler> handler = new ProtocolProxyQueryHandler(this); rv = pps->AsyncResolve(channel, nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY | nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL, handler, getter_AddRefs(mProxyRequest)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to resolve protocol proxy: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } return NS_OK; }
nsresult nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) { *aLoadInfo = nsnull; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); if (!docShell) { return NS_ERROR_NOT_AVAILABLE; } nsresult result; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &result)); if (NS_FAILED(result)) return NS_ERROR_FAILURE; JSContext *cx; if (NS_FAILED(GetContextFromStack(stack, &cx))) return NS_ERROR_FAILURE; nsCOMPtr<nsISupports> owner; if (cx) { // No cx means that there's no JS running, or at least no JS that // was run through code that properly pushed a context onto the // context stack (as all code that runs JS off of web pages // does). We won't bother with security checks in this case, but // we need to create the loadinfo etc. // Get security manager. nsCOMPtr<nsIScriptSecurityManager> secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &result)); if (NS_FAILED(result)) return NS_ERROR_FAILURE; // Check to see if URI is allowed. result = secMan->CheckLoadURIFromScript(cx, aURI); if (NS_FAILED(result)) return result; // Now get the principal to use when loading the URI nsCOMPtr<nsIPrincipal> principal; if (NS_FAILED(secMan->GetSubjectPrincipal(getter_AddRefs(principal))) || !principal) return NS_ERROR_FAILURE; owner = do_QueryInterface(principal); } // Create load info nsCOMPtr<nsIDocShellLoadInfo> loadInfo; docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE); loadInfo->SetOwner(owner); // Now set the referrer on the loadinfo. We need to do this in order to get // the correct referrer URI from a document which was pushStated. nsCOMPtr<nsIURI> sourceURI; result = GetURI(getter_AddRefs(sourceURI)); if (NS_SUCCEEDED(result)) loadInfo->SetReferrer(sourceURI); loadInfo.swap(*aLoadInfo); return NS_OK; }
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers, const std::vector<NrIceTurnServer>& turn_servers, NrIceCtx::Policy policy) { nsresult rv; nsCOMPtr<nsIProtocolProxyService> pps = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get proxy service: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } // We use the following URL to find the "default" proxy address for all HTTPS // connections. We will only attempt one HTTP(S) CONNECT per peer connection. // "example.com" is guaranteed to be unallocated and should return the best default. nsCOMPtr<nsIURI> fakeHttpsLocation; rv = NS_NewURI(getter_AddRefs(fakeHttpsLocation), "https://example.com"); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to set URI: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIScriptSecurityManager> secMan( do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get IOService: %d", __FUNCTION__, (int)rv); CSFLogError(logTag, "%s: Failed to get securityManager: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIPrincipal> systemPrincipal; rv = secMan->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get systemPrincipal: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } nsCOMPtr<nsIChannel> channel; rv = NS_NewChannel(getter_AddRefs(channel), fakeHttpsLocation, systemPrincipal, nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to get channel from URI: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } RefPtr<ProtocolProxyQueryHandler> handler = new ProtocolProxyQueryHandler(this); rv = pps->AsyncResolve(channel, nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY | nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL, handler, getter_AddRefs(mProxyRequest)); if (NS_FAILED(rv)) { CSFLogError(logTag, "%s: Failed to resolve protocol proxy: %d", __FUNCTION__, (int)rv); return NS_ERROR_FAILURE; } #if !defined(MOZILLA_EXTERNAL_LINKAGE) bool ice_tcp = Preferences::GetBool("media.peerconnection.ice.tcp", false); if (!XRE_IsParentProcess()) { CSFLogError(logTag, "%s: ICE TCP not support on e10s", __FUNCTION__); ice_tcp = false; } bool default_address_only = Preferences::GetBool( "media.peerconnection.ice.default_address_only", false); #else bool ice_tcp = false; bool default_address_only = false; #endif // TODO([email protected]): need some way to set not offerer later // Looks like a bug in the NrIceCtx API. mIceCtx = NrIceCtx::Create("PC:" + mParentName, true, // Offerer mParent->GetAllowIceLoopback(), ice_tcp, mParent->GetAllowIceLinkLocal(), default_address_only, policy); if(!mIceCtx) { CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__); return NS_ERROR_FAILURE; } if (NS_FAILED(rv = mIceCtx->SetStunServers(stun_servers))) { CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__); return rv; } // Give us a way to globally turn off TURN support #if !defined(MOZILLA_EXTERNAL_LINKAGE) bool disabled = Preferences::GetBool("media.peerconnection.turn.disable", false); #else bool disabled = false; #endif if (!disabled) { if (NS_FAILED(rv = mIceCtx->SetTurnServers(turn_servers))) { CSFLogError(logTag, "%s: Failed to set turn servers", __FUNCTION__); return rv; } } else if (turn_servers.size() != 0) { CSFLogError(logTag, "%s: Setting turn servers disabled", __FUNCTION__); } if (NS_FAILED(rv = mDNSResolver->Init())) { CSFLogError(logTag, "%s: Failed to initialize dns resolver", __FUNCTION__); return rv; } if (NS_FAILED(rv = mIceCtx->SetResolver(mDNSResolver->AllocateResolver()))) { CSFLogError(logTag, "%s: Failed to get dns resolver", __FUNCTION__); return rv; } mIceCtx->SignalGatheringStateChange.connect( this, &PeerConnectionMedia::IceGatheringStateChange_s); mIceCtx->SignalConnectionStateChange.connect( this, &PeerConnectionMedia::IceConnectionStateChange_s); return NS_OK; }
nsresult nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) { *aLoadInfo = nsnull; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE); nsresult rv; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); JSContext *cx; NS_ENSURE_SUCCESS(GetContextFromStack(stack, &cx), NS_ERROR_FAILURE); nsCOMPtr<nsISupports> owner; nsCOMPtr<nsIURI> sourceURI; if (cx) { // No cx means that there's no JS running, or at least no JS that // was run through code that properly pushed a context onto the // context stack (as all code that runs JS off of web pages // does). We won't bother with security checks in this case, but // we need to create the loadinfo etc. // Get security manager. nsCOMPtr<nsIScriptSecurityManager> secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); // Check to see if URI is allowed. rv = secMan->CheckLoadURIFromScript(cx, aURI); NS_ENSURE_SUCCESS(rv, rv); // Now get the principal to use when loading the URI // First, get the principal and frame. JSStackFrame *fp; nsIPrincipal* principal = secMan->GetCxSubjectPrincipalAndFrame(cx, &fp); NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE); nsCOMPtr<nsIURI> principalURI; principal->GetURI(getter_AddRefs(principalURI)); // Make the load's referrer reflect changes to the document's URI caused by // push/replaceState, if possible. First, get the document corresponding to // fp. If the document's original URI (i.e. its URI before // push/replaceState) matches the principal's URI, use the document's // current URI as the referrer. If they don't match, use the principal's // URI. nsCOMPtr<nsIDocument> frameDoc = GetFrameDocument(cx, fp); nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI; if (frameDoc) { docOriginalURI = frameDoc->GetOriginalURI(); docCurrentURI = frameDoc->GetDocumentURI(); } bool urisEqual = false; if (docOriginalURI && docCurrentURI && principalURI) { principalURI->Equals(docOriginalURI, &urisEqual); } if (urisEqual) { sourceURI = docCurrentURI; } else { sourceURI = principalURI; } owner = do_QueryInterface(principal); } // Create load info nsCOMPtr<nsIDocShellLoadInfo> loadInfo; docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE); loadInfo->SetOwner(owner); if (sourceURI) { loadInfo->SetReferrer(sourceURI); } loadInfo.swap(*aLoadInfo); return NS_OK; }
AutoPushJSContext::AutoPushJSContext(nsISupports* aSecuritySupports, JSContext *cx) : mContext(cx), mPushResult(NS_OK) { nsCOMPtr<nsIJSContextStack> contextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); JS_BeginRequest(cx); JSContext* currentCX; if(contextStack && // Don't push if the current context is already on the stack. (NS_FAILED(contextStack->Peek(¤tCX)) || cx != currentCX) ) { if (NS_SUCCEEDED(contextStack->Push(cx))) { // Leave the reference in mContextStack to // indicate that we need to pop it in our dtor. mContextStack.swap(contextStack); } } nsCOMPtr<nsIScriptSecurityManager> secMan( do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &mPushResult)); if (NS_FAILED(mPushResult)) return; nsCOMPtr<nsIPrincipal> principal; mPushResult = secMan->GetPrincipalFromContext(cx, getter_AddRefs(principal)); if (NS_FAILED(mPushResult)) { JS_ReportError(cx, "failed to get a principal"); return; } // See if JavaScript is enabled for the current window PRBool jsEnabled = PR_FALSE; mPushResult = secMan->CanExecuteScripts(cx, principal, &jsEnabled); if (!jsEnabled) mPushResult = NS_ERROR_FAILURE; memset(&mFrame, 0, sizeof(mFrame)); if (NS_SUCCEEDED(mPushResult)) { // See if there are any scripts on the stack. // If not, we need to add a dummy frame with a principal. PRBool hasScript = PR_FALSE; JSStackFrame* tempFP = cx->fp; while (tempFP) { if (tempFP->script) { hasScript = PR_TRUE; break; } tempFP = tempFP->down; }; if (!hasScript) { JSPrincipals* jsprinc; principal->GetJSPrincipals(cx, &jsprinc); JSFunction *fun = JS_CompileFunctionForPrincipals(cx, JS_GetGlobalObject(cx), jsprinc, "anonymous", 0, nsnull, "", 0, "", 1); JSPRINCIPALS_DROP(cx, jsprinc); if (fun) { JSScript *script = JS_GetFunctionScript(cx, fun); mFrame.fun = fun; mFrame.script = script; mFrame.callee = JS_GetFunctionObject(fun); mFrame.scopeChain = JS_GetParent(cx, mFrame.callee); mFrame.down = cx->fp; mRegs.pc = script->code + script->length - 1; JS_ASSERT(static_cast<JSOp>(*mRegs.pc) == JSOP_STOP); mRegs.sp = NULL; mFrame.regs = &mRegs; cx->fp = &mFrame; } else mPushResult = NS_ERROR_OUT_OF_MEMORY; } } }