bool TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL, const bool& aUseArrayBuffers) { // We don't have browser actors in xpcshell, and hence can't run automated // tests without this loophole. if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } // Obtain App ID uint32_t appId = GetAppId(); bool inIsolatedMozBrowser = GetInIsolatedMozBrowser(); if (NS_IsAppOffline(appId)) { NS_ERROR("Can't open socket because app is offline"); FireInteralError(this, __LINE__); return true; } mSocket = new TCPSocket(nullptr, aHost, aPort, aUseSSL, aUseArrayBuffers); mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser); mSocket->SetSocketBridgeParent(this); NS_ENSURE_SUCCESS(mSocket->Init(), true); return true; }
bool TCPServerSocketParent::Init(PNeckoParent* neckoParent, const uint16_t& aLocalPort, const uint16_t& aBacklog, const nsString& aBinaryType) { mNeckoParent = neckoParent; nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } rv = mIntermediary->Listen(this, aLocalPort, aBacklog, aBinaryType, GetAppId(), getter_AddRefs(mServerSocket)); if (NS_FAILED(rv) || !mServerSocket) { FireInteralError(this, __LINE__); return true; } return true; }
bool TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL, const nsString& aBinaryType) { // We don't have browser actors in xpcshell, and hence can't run automated // tests without this loophole. if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } // Obtain App ID uint32_t appId = GetAppId(); bool inBrowser = GetInBrowser(); if (NS_IsAppOffline(appId)) { NS_ERROR("Can't open socket because app is offline"); FireInteralError(this, __LINE__); return true; } nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, appId, inBrowser, getter_AddRefs(mSocket)); if (NS_FAILED(rv) || !mSocket) { FireInteralError(this, __LINE__); return true; } return true; }
bool TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL, const nsString& aBinaryType) { // We don't have browser actors in xpcshell, and hence can't run automated // tests without this loophole. if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } // Obtain App ID uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; const PContentParent *content = Manager()->Manager(); const InfallibleTArray<PBrowserParent*>& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = static_cast<TabParent*>(browsers[0]); appId = tab->OwnAppId(); } nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } rv = mIntermediary->Open(this, aHost, aPort, aUseSSL, aBinaryType, appId, getter_AddRefs(mSocket)); if (NS_FAILED(rv) || !mSocket) { FireInteralError(this, __LINE__); return true; } return true; }
NS_IMETHODIMP TCPSocketParent::SendEvent(const nsAString& aType, JS::Handle<JS::Value> aDataVal, const nsAString& aReadyState, JSContext* aCx) { if (!mIPCOpen) { NS_WARNING("Dropping callback due to no IPC connection"); return NS_OK; } CallbackData data; if (aDataVal.isString()) { JSString* jsstr = aDataVal.toString(); nsAutoJSString str; if (!str.init(aCx, jsstr)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } data = SendableData(str); } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JS::Rooted<JSObject *> obj(aCx, &aDataVal.toObject()); if (JS_IsArrayBufferObject(obj)) { FallibleTArray<uint8_t> fallibleArr; uint32_t errLine = 0; do { JS::AutoCheckCannotGC nogc; uint32_t nbytes = JS_GetArrayBufferByteLength(obj); uint8_t* buffer = JS_GetArrayBufferData(obj, nogc); if (!buffer) { errLine = __LINE__; break; } if (!fallibleArr.InsertElementsAt(0, buffer, nbytes, fallible)) { errLine = __LINE__; break; } } while (false); if (errLine) { FireInteralError(this, errLine); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); data = SendableData(arr); } else { nsAutoJSString name; JS::Rooted<JS::Value> val(aCx); if (!JS_GetProperty(aCx, obj, "name", &val)) { NS_ERROR("No name property on supposed error object"); } else if (val.isString()) { if (!name.init(aCx, val.toString())) { NS_WARNING("couldn't initialize string"); } } data = TCPError(name); } } else { NS_ERROR("Unexpected JS value encountered"); FireInteralError(this, __LINE__); return NS_ERROR_FAILURE; } mozilla::unused << PTCPSocketParent::SendCallback(nsString(aType), data, nsString(aReadyState)); return NS_OK; }
NS_IMETHODIMP TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal, const nsAString& aReadyState, uint32_t aBuffered, JSContext* aCx) { if (!mIPCOpen) { NS_WARNING("Dropping callback due to no IPC connection"); return NS_OK; } CallbackData data; if (aDataVal.isString()) { JSString* jsstr = aDataVal.toString(); nsDependentJSString str; if (!str.init(aCx, jsstr)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } data = SendableData(str); } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JSObject* obj = &aDataVal.toObject(); if (JS_IsArrayBufferObject(obj)) { uint32_t nbytes = JS_GetArrayBufferByteLength(obj); uint8_t* buffer = JS_GetArrayBufferData(obj); if (!buffer) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); data = SendableData(arr); } else { nsDependentJSString name; JS::Rooted<JS::Value> val(aCx); if (!JS_GetProperty(aCx, obj, "name", val.address())) { NS_ERROR("No name property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!name.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } data = TCPError(name); } } else { NS_ERROR("Unexpected JS value encountered"); FireInteralError(this, __LINE__); return NS_ERROR_FAILURE; } mozilla::unused << PTCPSocketParent::SendCallback(nsString(aType), data, nsString(aReadyState), aBuffered); return NS_OK; }
bool TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost, const uint16_t& aRemotePort, const nsCString& aLocalAddr, const uint16_t& aLocalPort, const bool& aUseSSL, const bool& aUseArrayBuffers, const nsCString& aFilter) { if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { FireInteralError(this, __LINE__); return true; } nsresult rv; nsCOMPtr<nsISocketTransportService> sts = do_GetService("@mozilla.org/network/socket-transport-service;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } nsCOMPtr<nsISocketTransport> socketTransport; rv = sts->CreateTransport(nullptr, 0, aRemoteHost, aRemotePort, nullptr, getter_AddRefs(socketTransport)); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } PRNetAddr prAddr; if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) { FireInteralError(this, __LINE__); return true; } if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) { FireInteralError(this, __LINE__); return true; } mozilla::net::NetAddr addr; PRNetAddrToNetAddr(&prAddr, &addr); rv = socketTransport->Bind(&addr); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } if (!aFilter.IsEmpty()) { nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX); contractId.Append(aFilter); nsCOMPtr<nsISocketFilterHandler> filterHandler = do_GetService(contractId.get()); if (!filterHandler) { NS_ERROR("Content doesn't have a valid filter"); FireInteralError(this, __LINE__); return true; } rv = filterHandler->NewFilter(getter_AddRefs(mFilter)); if (NS_FAILED(rv)) { NS_ERROR("Cannot create filter that content specified"); FireInteralError(this, __LINE__); return true; } } // Obtain App ID uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; bool inIsolatedMozBrowser = false; const PContentParent *content = Manager()->Manager(); if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) { // appId's are for B2G only currently, where managees.Count() == 1 // This is not guaranteed currently in Desktop, so skip this there. TabParent *tab = TabParent::GetFrom(browser); appId = tab->OwnAppId(); inIsolatedMozBrowser = tab->IsIsolatedMozBrowserElement(); } mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers); mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser); mSocket->SetSocketBridgeParent(this); rv = mSocket->InitWithUnconnectedTransport(socketTransport); NS_ENSURE_SUCCESS(rv, true); return true; }
NS_IMETHODIMP TCPSocketParent::SendCallback(const nsAString& aType, const JS::Value& aDataVal, const nsAString& aReadyState, uint32_t aBuffered, JSContext* aCx) { if (!mIPCOpen) { NS_WARNING("Dropping callback due to no IPC connection"); return NS_OK; } CallbackData data; if (aDataVal.isString()) { JSString* jsstr = aDataVal.toString(); nsDependentJSString str; if (!str.init(aCx, jsstr)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } data = str; } else if (aDataVal.isUndefined() || aDataVal.isNull()) { data = mozilla::void_t(); } else if (aDataVal.isObject()) { JSObject* obj = &aDataVal.toObject(); if (JS_IsTypedArrayObject(obj)) { NS_ENSURE_TRUE(JS_IsUint8Array(obj), NS_ERROR_FAILURE); uint32_t nbytes = JS_GetTypedArrayByteLength(obj); uint8_t* buffer = JS_GetUint8ArrayData(obj); if (!buffer) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } FallibleTArray<uint8_t> fallibleArr; if (!fallibleArr.InsertElementsAt(0, buffer, nbytes)) { FireInteralError(this, __LINE__); return NS_ERROR_OUT_OF_MEMORY; } InfallibleTArray<uint8_t> arr; arr.SwapElements(fallibleArr); data = SendableData(arr); } else { nsDependentJSString message, filename; uint32_t lineNumber = 0; uint32_t columnNumber = 0; jsval val; if (!JS_GetProperty(aCx, obj, "message", &val)) { NS_ERROR("No message property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!message.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } if (!JS_GetProperty(aCx, obj, "fileName", &val)) { NS_ERROR("No fileName property on supposed error object"); } else if (JSVAL_IS_STRING(val)) { if (!filename.init(aCx, JSVAL_TO_STRING(val))) { NS_WARNING("couldn't initialize string"); } } if (!JS_GetProperty(aCx, obj, "lineNumber", &val)) { NS_ERROR("No lineNumber property on supposed error object"); } else if (JSVAL_IS_INT(val)) { lineNumber = JSVAL_TO_INT(val); } if (!JS_GetProperty(aCx, obj, "columnNumber", &val)) { NS_ERROR("No columnNumber property on supposed error object"); } else if (JSVAL_IS_INT(val)) { columnNumber = JSVAL_TO_INT(val); } data = JSError(message, filename, lineNumber, columnNumber); } } else { NS_ERROR("Unexpected JS value encountered"); FireInteralError(this, __LINE__); return NS_ERROR_FAILURE; } mozilla::unused << PTCPSocketParent::SendCallback(nsString(aType), data, nsString(aReadyState), aBuffered); return NS_OK; }