nsresult nsWebSocketEstablishedConnection::Init(nsWebSocket *aOwner) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); NS_ABORT_IF_FALSE(!mOwner, "WebSocket's connection is already initialized"); nsresult rv; mOwner = aOwner; if (mOwner->mSecure) { mWebSocketChannel = do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv); } else { mWebSocketChannel = do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv); } NS_ENSURE_SUCCESS(rv, rv); rv = mWebSocketChannel->SetNotificationCallbacks(this); NS_ENSURE_SUCCESS(rv, rv); // add ourselves to the document's load group and // provide the http stack the loadgroup info too nsCOMPtr<nsILoadGroup> loadGroup; rv = GetLoadGroup(getter_AddRefs(loadGroup)); if (loadGroup) { rv = mWebSocketChannel->SetLoadGroup(loadGroup); NS_ENSURE_SUCCESS(rv, rv); rv = loadGroup->AddRequest(this, nsnull); NS_ENSURE_SUCCESS(rv, rv); } if (!mOwner->mRequestedProtocolList.IsEmpty()) { rv = mWebSocketChannel->SetProtocol(mOwner->mRequestedProtocolList); NS_ENSURE_SUCCESS(rv, rv); } nsCString asciiOrigin; rv = nsContentUtils::GetASCIIOrigin(mOwner->mPrincipal, asciiOrigin); NS_ENSURE_SUCCESS(rv, rv); ToLowerCase(asciiOrigin); rv = mWebSocketChannel->AsyncOpen(mOwner->mURI, asciiOrigin, this, nsnull); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
nsresult PendingLookup::SendRemoteQueryInternal() { // If we aren't supposed to do remote lookups, bail. if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED, false)) { LOG(("Remote lookups are disabled [this = %p]", this)); return NS_ERROR_NOT_AVAILABLE; } // If the remote lookup URL is empty or absent, bail. nsCString serviceUrl; NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl), NS_ERROR_NOT_AVAILABLE); if (serviceUrl.EqualsLiteral("")) { LOG(("Remote lookup URL is empty [this = %p]", this)); return NS_ERROR_NOT_AVAILABLE; } // If the blocklist or allowlist is empty (so we couldn't do local lookups), // bail nsCString table; NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &table), NS_ERROR_NOT_AVAILABLE); if (table.EqualsLiteral("")) { LOG(("Blocklist is empty [this = %p]", this)); return NS_ERROR_NOT_AVAILABLE; } #ifdef XP_WIN // The allowlist is only needed to do signature verification on Windows NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &table), NS_ERROR_NOT_AVAILABLE); if (table.EqualsLiteral("")) { LOG(("Allowlist is empty [this = %p]", this)); return NS_ERROR_NOT_AVAILABLE; } #endif LOG(("Sending remote query for application reputation [this = %p]", this)); // We did not find a local result, so fire off the query to the // application reputation service. nsCOMPtr<nsIURI> uri; nsresult rv; rv = mQuery->GetSourceURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsCString spec; rv = GetStrippedSpec(uri, spec); NS_ENSURE_SUCCESS(rv, rv); mRequest.set_url(spec.get()); uint32_t fileSize; rv = mQuery->GetFileSize(&fileSize); NS_ENSURE_SUCCESS(rv, rv); mRequest.set_length(fileSize); // We have no way of knowing whether or not a user initiated the // download. Set it to true to lessen the chance of false positives. mRequest.set_user_initiated(true); nsCString locale; NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_GENERAL_LOCALE, &locale), NS_ERROR_NOT_AVAILABLE); mRequest.set_locale(locale.get()); nsCString sha256Hash; rv = mQuery->GetSha256Hash(sha256Hash); NS_ENSURE_SUCCESS(rv, rv); mRequest.mutable_digests()->set_sha256(sha256Hash.Data()); nsString fileName; rv = mQuery->GetSuggestedFileName(fileName); NS_ENSURE_SUCCESS(rv, rv); mRequest.set_file_basename(NS_ConvertUTF16toUTF8(fileName).get()); mRequest.set_download_type(GetDownloadType(fileName)); if (mRequest.signature().trusted()) { LOG(("Got signed binary for remote application reputation check " "[this = %p]", this)); } else { LOG(("Got unsigned binary for remote application reputation check " "[this = %p]", this)); } // Serialize the protocol buffer to a string. This can only fail if we are // out of memory, or if the protocol buffer req is missing required fields // (only the URL for now). std::string serialized; if (!mRequest.SerializeToString(&serialized)) { return NS_ERROR_UNEXPECTED; } LOG(("Serialized protocol buffer [this = %p]: (length=%d) %s", this, serialized.length(), serialized.c_str())); // Set the input stream to the serialized protocol buffer nsCOMPtr<nsIStringInputStream> sstream = do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv); NS_ENSURE_SUCCESS(rv, rv); rv = sstream->SetData(serialized.c_str(), serialized.length()); NS_ENSURE_SUCCESS(rv, rv); // Set up the channel to transmit the request to the service. nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); rv = ios->NewChannel2(serviceUrl, nullptr, nullptr, nullptr, // aLoadingNode nsContentUtils::GetSystemPrincipal(), nullptr, // aTriggeringPrincipal nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, getter_AddRefs(mChannel)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv)); NS_ENSURE_SUCCESS(rv, rv); // Upload the protobuf to the application reputation service. nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = uploadChannel->ExplicitSetUploadStream(sstream, NS_LITERAL_CSTRING("application/octet-stream"), serialized.size(), NS_LITERAL_CSTRING("POST"), false); NS_ENSURE_SUCCESS(rv, rv); // Set the Safebrowsing cookie jar, so that the regular Google cookie is not // sent with this request. See bug 897516. nsCOMPtr<nsIInterfaceRequestor> loadContext = new mozilla::LoadContext(NECKO_SAFEBROWSING_APP_ID); rv = mChannel->SetNotificationCallbacks(loadContext); NS_ENSURE_SUCCESS(rv, rv); uint32_t timeoutMs = Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT, 10000); mTimeoutTimer = do_CreateInstance(NS_TIMER_CONTRACTID); mTimeoutTimer->InitWithCallback(this, timeoutMs, nsITimer::TYPE_ONE_SHOT); rv = mChannel->AsyncOpen(this, nullptr); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }