NS_IMETHODIMP
nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
    NS_ENSURE_ARG_POINTER(uri);

    // about:what you ask?
    nsCOMPtr<nsIAboutModule> aboutMod;
    nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod));

    nsAutoCString path;
    nsresult rv2 = NS_GetAboutModuleName(uri, path);
    if (NS_SUCCEEDED(rv2) && path.EqualsLiteral("srcdoc")) {
        // about:srcdoc is meant to be unresolvable, yet is included in the 
        // about lookup tables so that it can pass security checks when used in
        // a srcdoc iframe.  To ensure that it stays unresolvable, we pretend
        // that it doesn't exist.
      rv = NS_ERROR_FACTORY_NOT_REGISTERED;
    }

    if (NS_SUCCEEDED(rv)) {
        // The standard return case:
        rv = aboutMod->NewChannel(uri, result);
        if (NS_SUCCEEDED(rv)) {
            // If this URI is safe for untrusted content, enforce that its
            // principal be based on the channel's originalURI by setting the
            // owner to null.
            // Note: this relies on aboutMod's newChannel implementation
            // having set the proper originalURI, which probably isn't ideal.
            if (IsSafeForUntrustedContent(aboutMod, uri)) {
                (*result)->SetOwner(nullptr);
            }

            nsRefPtr<nsNestedAboutURI> aboutURI;
            nsresult rv2 = uri->QueryInterface(kNestedAboutURICID,
                                               getter_AddRefs(aboutURI));
            if (NS_SUCCEEDED(rv2) && aboutURI->GetBaseURI()) {
                nsCOMPtr<nsIWritablePropertyBag2> writableBag =
                    do_QueryInterface(*result);
                if (writableBag) {
                    writableBag->
                        SetPropertyAsInterface(NS_LITERAL_STRING("baseURI"),
                                               aboutURI->GetBaseURI());
                }
            }
        }
        return rv;
    }

    // mumble...

    if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) {
        // This looks like an about: we don't know about.  Convert
        // this to an invalid URI error.
        rv = NS_ERROR_MALFORMED_URI;
    }

    return rv;
}
Пример #2
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
{
    NS_ENSURE_ARG_POINTER(aURI);
    NS_ASSERTION(result, "must not be null");

    nsresult rv;

    nsCAutoString path;
    rv = NS_GetAboutModuleName(aURI, path);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
    if (NS_FAILED(rv))
        return rv;

    for (int i=0; i<kRedirTotal; i++) 
    {
        if (!strcmp(path.get(), kRedirMap[i].id))
        {
            nsCOMPtr<nsIChannel> tempChannel;
            rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url),
                                       nsnull, nsnull, getter_AddRefs(tempChannel));
            if (NS_FAILED(rv))
                return rv;

            tempChannel->SetOriginalURI(aURI);

            // Keep the page from getting unnecessary privileges unless it needs them
            if (kRedirMap[i].flags &
                nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT)
            {
                nsCOMPtr<nsIScriptSecurityManager> securityManager = 
                         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
                if (NS_FAILED(rv))
                    return rv;
            
                nsCOMPtr<nsIPrincipal> principal;
                rv = securityManager->GetCodebasePrincipal(aURI, getter_AddRefs(principal));
                if (NS_FAILED(rv))
                    return rv;
            
                rv = tempChannel->SetOwner(principal);
                if (NS_FAILED(rv))
                    return rv;
            }

            NS_ADDREF(*result = tempChannel);
            return rv;
        }
    }

    NS_ERROR("nsAboutRedirector called for unknown case");
    return NS_ERROR_ILLEGAL_VALUE;
}
Пример #3
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI* aURI,
                              nsILoadInfo* aLoadInfo,
                              nsIChannel** aResult)
{
  NS_ENSURE_ARG_POINTER(aURI);
  NS_ASSERTION(aResult, "must not be null");

  nsAutoCString path;
  nsresult rv = NS_GetAboutModuleName(aURI, path);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
  NS_ENSURE_SUCCESS(rv, rv);

  for (int i = 0; i < kRedirTotal; i++) {
    if (!strcmp(path.get(), kRedirMap[i].id)) {
      nsCOMPtr<nsIChannel> tempChannel;
      nsCOMPtr<nsIURI> tempURI;
      rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
      NS_ENSURE_SUCCESS(rv, rv);

      // If tempURI links to an external URI (i.e. something other than
      // chrome:// or resource://) then set the LOAD_REPLACE flag on the
      // channel which forces the channel owner to reflect the displayed
      // URL rather then being the systemPrincipal.
      bool isUIResource = false;
      rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
                               &isUIResource);
      NS_ENSURE_SUCCESS(rv, rv);

      bool isAboutBlank = NS_IsAboutBlank(tempURI);

      nsLoadFlags loadFlags = isUIResource || isAboutBlank
                    ? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
                    : static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);

      rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
                                 tempURI,
                                 aLoadInfo,
                                 nullptr, // aLoadGroup
                                 nullptr, // aCallbacks
                                 loadFlags);
      NS_ENSURE_SUCCESS(rv, rv);

      tempChannel->SetOriginalURI(aURI);

      tempChannel.forget(aResult);
      return rv;
    }
  }

  NS_ERROR("nsAboutRedirector called for unknown case");
  return NS_ERROR_ILLEGAL_VALUE;
}
Пример #4
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI* aURI,
                              nsILoadInfo* aLoadInfo,
                              nsIChannel** result)
{
    NS_ENSURE_ARG_POINTER(aURI);
    NS_ASSERTION(result, "must not be null");

    nsAutoCString path;
    nsresult rv = NS_GetAboutModuleName(aURI, path);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
    NS_ENSURE_SUCCESS(rv, rv);


    for (int i=0; i<kRedirTotal; i++) 
    {
        if (!strcmp(path.get(), kRedirMap[i].id))
        {
            nsCOMPtr<nsIChannel> tempChannel;
            nsCOMPtr<nsIURI> tempURI;
            rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
            NS_ENSURE_SUCCESS(rv, rv);
            // Bug 1087720 (and Bug 1099296):
            // Once all callsites have been updated to call NewChannel2()
            // instead of NewChannel() we should have a non-null loadInfo
            // consistently. Until then we have to branch on the loadInfo.
            if (aLoadInfo) {
              rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
                                         tempURI,
                                         aLoadInfo);
            }
            else {
              rv = ioService->NewChannelFromURI(tempURI,
                                                getter_AddRefs(tempChannel));
            }
            if (NS_FAILED(rv))
                return rv;

            tempChannel->SetOriginalURI(aURI);

            NS_ADDREF(*result = tempChannel);
            return rv;
        }
    }

    NS_ERROR("nsAboutRedirector called for unknown case");
    return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
{
    NS_ENSURE_ARG_POINTER(aURI);
    NS_ASSERTION(result, "must not be null");

    nsresult rv;

    nsAutoCString path;
    rv = NS_GetAboutModuleName(aURI, path);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
    if (NS_FAILED(rv))
        return rv;

    for (int i=0; i<kRedirTotal; i++) 
    {
        if (!strcmp(path.get(), kRedirMap[i].id))
        {
            nsCOMPtr<nsIChannel> tempChannel;
            rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url),
                                       nullptr, nullptr, getter_AddRefs(tempChannel));
            if (NS_FAILED(rv))
                return rv;

            tempChannel->SetOriginalURI(aURI);

            // Keep the page from getting unnecessary privileges unless it needs them
            if (kRedirMap[i].flags &
                nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT)
            {
                // Setting the owner to null means that we'll go through the normal
                // path in GetChannelPrincipal and create a codebase principal based
                // on the channel's originalURI
                rv = tempChannel->SetOwner(nullptr);
                if (NS_FAILED(rv))
                    return rv;
            }

            NS_ADDREF(*result = tempChannel);
            return rv;
        }
    }

    NS_ERROR("nsAboutRedirector called for unknown case");
    return NS_ERROR_ILLEGAL_VALUE;
}
Пример #6
0
NS_IMETHODIMP
nsAboutRedirector::GetURIFlags(nsIURI* aURI, uint32_t* aResult) {
  NS_ENSURE_ARG_POINTER(aURI);

  nsAutoCString name;
  nsresult rv = NS_GetAboutModuleName(aURI, name);
  NS_ENSURE_SUCCESS(rv, rv);

  for (int i = 0; i < kRedirTotal; i++) {
    if (name.EqualsASCII(kRedirMap[i].id)) {
      *aResult = kRedirMap[i].flags;
      return NS_OK;
    }
  }

  NS_ERROR("nsAboutRedirector called for unknown case");
  return NS_ERROR_ILLEGAL_VALUE;
}
Пример #7
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI* aURI,
                              nsILoadInfo* aLoadInfo,
                              nsIChannel** aResult)
{
  NS_ENSURE_ARG_POINTER(aURI);
  NS_ASSERTION(aResult, "must not be null");

  nsAutoCString path;
  nsresult rv = NS_GetAboutModuleName(aURI, path);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
  NS_ENSURE_SUCCESS(rv, rv);

  for (int i = 0; i < kRedirTotal; i++) {
    if (!strcmp(path.get(), kRedirMap[i].id)) {
      nsCOMPtr<nsIChannel> tempChannel;
      nsCOMPtr<nsIURI> tempURI;
      rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
      NS_ENSURE_SUCCESS(rv, rv);
      rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
                                 tempURI,
                                 aLoadInfo);
      if (NS_FAILED(rv)) {
        return rv;
      }

      tempChannel->SetOriginalURI(aURI);

      tempChannel.forget(aResult);
      return rv;
    }
  }

  NS_ERROR("nsAboutRedirector called for unknown case");
  return NS_ERROR_ILLEGAL_VALUE;
}
Пример #8
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
{
    NS_ENSURE_ARG_POINTER(aURI);
    NS_ASSERTION(result, "must not be null");

    nsresult rv;

    nsAutoCString path;
    rv = NS_GetAboutModuleName(aURI, path);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
    if (NS_FAILED(rv))
        return rv;

    for (int i=0; i<kRedirTotal; i++) 
    {
        if (!strcmp(path.get(), kRedirMap[i].id))
        {
            nsCOMPtr<nsIChannel> tempChannel;
            rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url),
                                       nullptr, nullptr, getter_AddRefs(tempChannel));
            if (NS_FAILED(rv))
                return rv;

            tempChannel->SetOriginalURI(aURI);

            NS_ADDREF(*result = tempChannel);
            return rv;
        }
    }

    NS_ERROR("nsAboutRedirector called for unknown case");
    return NS_ERROR_ILLEGAL_VALUE;
}
Пример #9
0
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
                              nsIChannel** aResult) {
  NS_ENSURE_ARG_POINTER(aURI);
  NS_ENSURE_ARG_POINTER(aLoadInfo);
  NS_ASSERTION(aResult, "must not be null");

  nsAutoCString path;
  nsresult rv = NS_GetAboutModuleName(aURI, path);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
  NS_ENSURE_SUCCESS(rv, rv);

  if (path.EqualsASCII("crashparent") || path.EqualsASCII("crashcontent")) {
    nsCOMPtr<nsIChannel> channel = new CrashChannel(aURI);
    channel.forget(aResult);
    return NS_OK;
  }

#ifdef ABOUT_CONFIG_BLOCKED_GV
  // We don't want to allow access to about:config from
  // GeckoView on release or beta, but it's fine for Fennec.
  if (path.EqualsASCII("config") && !mozilla::jni::IsFennec()) {
    return NS_ERROR_NOT_AVAILABLE;
  }
#endif

  for (int i = 0; i < kRedirTotal; i++) {
    if (!strcmp(path.get(), kRedirMap[i].id)) {
      nsCOMPtr<nsIChannel> tempChannel;
      nsCOMPtr<nsIURI> tempURI;
      rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
      NS_ENSURE_SUCCESS(rv, rv);

      rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), tempURI,
                                 aLoadInfo);
      NS_ENSURE_SUCCESS(rv, rv);

      // If tempURI links to an external URI (i.e. something other than
      // chrome:// or resource://) then set result principal URI on the
      // load info which forces the channel principal to reflect the displayed
      // URL rather then being the systemPrincipal.
      bool isUIResource = false;
      rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
                               &isUIResource);
      NS_ENSURE_SUCCESS(rv, rv);

      bool isAboutBlank = NS_IsAboutBlank(tempURI);

      if (!isUIResource && !isAboutBlank) {
        aLoadInfo->SetResultPrincipalURI(tempURI);
      }

      tempChannel->SetOriginalURI(aURI);

      tempChannel.forget(aResult);
      return rv;
    }
  }

  NS_ERROR("nsAboutRedirector called for unknown case");
  return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsAboutProtocolHandler::NewChannel2(nsIURI* uri,
                                    nsILoadInfo* aLoadInfo,
                                    nsIChannel** result)
{
    NS_ENSURE_ARG_POINTER(uri);

    // about:what you ask?
    nsCOMPtr<nsIAboutModule> aboutMod;
    nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod));

    nsAutoCString path;
    nsresult rv2 = NS_GetAboutModuleName(uri, path);
    if (NS_SUCCEEDED(rv2) && path.EqualsLiteral("srcdoc")) {
        // about:srcdoc is meant to be unresolvable, yet is included in the 
        // about lookup tables so that it can pass security checks when used in
        // a srcdoc iframe.  To ensure that it stays unresolvable, we pretend
        // that it doesn't exist.
      rv = NS_ERROR_FACTORY_NOT_REGISTERED;
    }

    if (NS_SUCCEEDED(rv)) {
        // The standard return case:
        rv = aboutMod->NewChannel(uri, aLoadInfo, result);
        if (NS_SUCCEEDED(rv)) {
            // Not all implementations of nsIAboutModule::NewChannel()
            // set the LoadInfo on the newly created channel yet, as
            // an interim solution we set the LoadInfo here if not
            // available on the channel. Bug 1087720
            nsCOMPtr<nsILoadInfo> loadInfo = (*result)->GetLoadInfo();
            if (aLoadInfo != loadInfo) {
                if (loadInfo) {
                    NS_ASSERTION(false,
                        "nsIAboutModule->newChannel(aURI, aLoadInfo) needs to set LoadInfo");
                    const char16_t* params[] = {
                        u"nsIAboutModule->newChannel(aURI)",
                        u"nsIAboutModule->newChannel(aURI, aLoadInfo)"
                    };
                    nsContentUtils::ReportToConsole(
                        nsIScriptError::warningFlag,
                        NS_LITERAL_CSTRING("Security by Default"),
                        nullptr, // aDocument
                        nsContentUtils::eNECKO_PROPERTIES,
                        "APIDeprecationWarning",
                        params, mozilla::ArrayLength(params));
                }
                (*result)->SetLoadInfo(aLoadInfo);
            }

            // If this URI is safe for untrusted content, enforce that its
            // principal be based on the channel's originalURI by setting the
            // owner to null.
            // Note: this relies on aboutMod's newChannel implementation
            // having set the proper originalURI, which probably isn't ideal.
            if (IsSafeForUntrustedContent(aboutMod, uri)) {
                (*result)->SetOwner(nullptr);
            }

            RefPtr<nsNestedAboutURI> aboutURI;
            nsresult rv2 = uri->QueryInterface(kNestedAboutURICID,
                                               getter_AddRefs(aboutURI));
            if (NS_SUCCEEDED(rv2) && aboutURI->GetBaseURI()) {
                nsCOMPtr<nsIWritablePropertyBag2> writableBag =
                    do_QueryInterface(*result);
                if (writableBag) {
                    writableBag->
                        SetPropertyAsInterface(NS_LITERAL_STRING("baseURI"),
                                               aboutURI->GetBaseURI());
                }
            }
        }
        return rv;
    }

    // mumble...

    if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) {
        // This looks like an about: we don't know about.  Convert
        // this to an invalid URI error.
        rv = NS_ERROR_MALFORMED_URI;
    }

    return rv;
}