예제 #1
0
SerializedLoadContext::SerializedLoadContext(nsIChannel* aChannel)
{
  if (!aChannel) {
    Init(nullptr);
    return;
  }

  nsCOMPtr<nsILoadContext> loadContext;
  NS_QueryNotificationCallbacks(aChannel, loadContext);
  Init(loadContext);

  if (!loadContext) {
    // Attempt to retrieve the private bit from the channel if it has been
    // overriden.
    bool isPrivate = false;
    bool isOverriden = false;
    nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(aChannel);
    if (pbChannel &&
        NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate,
                                                       &isOverriden)) &&
        isOverriden) {
      mUsePrivateBrowsing = isPrivate;
      mIsPrivateBitValid = true;
    }
    mOriginAttributes.SyncAttributesWithPrivateBrowsing(mUsePrivateBrowsing);
  }
}
NS_IMETHODIMP nsMsgCookiePolicy::CanAccess(nsIURI         *aURI,
        nsIChannel     *aChannel,
        nsCookieAccess *aResult)
{
    // by default we deny all cookies in mail
    *aResult = ACCESS_DENY;
    NS_ENSURE_ARG_POINTER(aChannel);

    nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem;
    NS_QueryNotificationCallbacks(aChannel, docShellTreeItem);

    NS_ENSURE_TRUE(docShellTreeItem, NS_OK);
    PRInt32 itemType;
    docShellTreeItem->GetItemType(&itemType);

    // allow chrome docshells to set cookies
    if (itemType == nsIDocShellTreeItem::typeChrome)
        *aResult = ACCESS_DEFAULT;
    else // allow RSS articles in content to access cookies
    {
        NS_ENSURE_TRUE(aURI, NS_OK);
        PRBool isRSS = PR_FALSE;
        IsRSSArticle(aURI, &isRSS);
        if (isRSS)
            *aResult = ACCESS_DEFAULT;
    }

    return NS_OK;
}
NS_IMETHODIMP
FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext)
{
  LOG(("FTPChannelChild::AsyncOpen [this=%x]\n", this));

  NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
  NS_ENSURE_ARG_POINTER(listener);
  NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
  NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);

  // Port checked in parent, but duplicate here so we can return with error
  // immediately, as we've done since before e10s.
  nsresult rv;
  rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate,
                                                 // because in the child ipdl,
                                                 // a typedef URI is defined...
  if (NS_FAILED(rv))
    return rv;

  // FIXME: like bug 558623, merge constructor+SendAsyncOpen into 1 IPC msg
  gNeckoChild->SendPFTPChannelConstructor(this);
  mListener = listener;
  mListenerContext = aContext;

  // add ourselves to the load group. 
  if (mLoadGroup)
    mLoadGroup->AddRequest(this, nsnull);

  // Get info from nsILoadContext, if any
  bool haveLoadContext = false;
  bool isContent = false;
  bool usePrivateBrowsing = false;
  bool isInBrowserElement = false;
  PRUint32 appId = 0;
  nsCOMPtr<nsILoadContext> loadContext;
  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                NS_GET_IID(nsILoadContext),
                                getter_AddRefs(loadContext));
  if (loadContext) {
    haveLoadContext = true;
    loadContext->GetIsContent(&isContent);
    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
    loadContext->GetIsInBrowserElement(&isInBrowserElement);
    loadContext->GetAppId(&appId);
  }

  SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID,
                IPC::InputStream(mUploadStream), haveLoadContext, isContent,
                usePrivateBrowsing, isInBrowserElement, appId);

  // The socket transport layer in the chrome process now has a logical ref to
  // us until OnStopRequest is called.
  AddIPDLReference();

  mIsPending = true;
  mWasOpened = true;

  return rv;
}
예제 #4
0
SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
{
  nsCOMPtr<nsILoadContext> loadContext;
  if (aChannel) {
    NS_QueryNotificationCallbacks(aChannel, loadContext);
  }
  Init(loadContext);
}
예제 #5
0
NS_IMETHODIMP
nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
  mLoadGroup = aLoadGroup;
  NS_QueryNotificationCallbacks(mCallbacks,
                                mLoadGroup,
                                NS_GET_IID(nsIProgressEventSink),
                                getter_AddRefs(mProgressSink));
  return NS_OK;
}
예제 #6
0
NS_IMETHODIMP
nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
  mCallbacks = aNotificationCallbacks;
  NS_QueryNotificationCallbacks(mCallbacks,
                                mLoadGroup,
                                NS_GET_IID(nsIProgressEventSink),
                                getter_AddRefs(mProgressSink));
  return NS_OK;
}
예제 #7
0
SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
    : mIsContent(false),
      mUseRemoteTabs(false),
      mUseRemoteSubframes(false),
      mUseTrackingProtection(false) {
  nsCOMPtr<nsILoadContext> loadContext;
  if (aChannel) {
    NS_QueryNotificationCallbacks(aChannel, loadContext);
  }
  Init(loadContext);
}
NS_IMETHODIMP
nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
  mCallbacks = aNotificationCallbacks;
  NS_QueryNotificationCallbacks(mCallbacks,
                                mLoadGroup,
                                NS_GET_IID(nsIProgressEventSink),
                                getter_AddRefs(mProgressSink));

  // Will never change unless SetNotificationCallbacks called again, so cache
  mPrivateBrowsing = NS_UsePrivateBrowsing(this);

  return NS_OK;
}
static void
GetAppIdAndBrowserStatus(nsIChannel* aChan, uint32_t* aAppId, bool* aInBrowserElem)
{
    nsCOMPtr<nsILoadContext> loadContext;
    if (aChan) {
        NS_QueryNotificationCallbacks(aChan, loadContext);
    }
    if (!loadContext) {
        *aAppId = NECKO_NO_APP_ID;
        *aInBrowserElem = false;
    } else {
        loadContext->GetAppId(aAppId);
        loadContext->GetIsInBrowserElement(aInBrowserElem);
    }
}
예제 #10
0
/* void asyncOpen (in nsIStreamListener aListener, in nsISupports aContext); */
NS_IMETHODIMP
WyciwygChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
{
  LOG(("WyciwygChannelChild::AsyncOpen [this=%x]\n", this));

  // The only places creating wyciwyg: channels should be
  // HTMLDocument::OpenCommon and session history.  Both should be setting an
  // owner.
  NS_PRECONDITION(mOwner, "Must have a principal");
  NS_ENSURE_STATE(mOwner);

  NS_ENSURE_ARG_POINTER(aListener);
  NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);

  mListener = aListener;
  mListenerContext = aContext;
  mIsPending = true;

  if (mLoadGroup)
    mLoadGroup->AddRequest(this, nullptr);

  // Get info from nsILoadContext, if any
  bool haveLoadContext = false;
  bool isContent = false;
  bool usePrivateBrowsing = false;
  bool isInBrowserElement = false;
  PRUint32 appId = 0;
  nsCAutoString extendedOrigin;
  nsCOMPtr<nsILoadContext> loadContext;
  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                NS_GET_IID(nsILoadContext),
                                getter_AddRefs(loadContext));
  if (loadContext) {
    haveLoadContext = true;
    loadContext->GetIsContent(&isContent);
    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
    loadContext->GetIsInBrowserElement(&isInBrowserElement);
    loadContext->GetAppId(&appId);
    loadContext->GetExtendedOrigin(mURI, extendedOrigin);
  }

  SendAsyncOpen(IPC::URI(mOriginalURI), mLoadFlags, haveLoadContext, isContent,
                usePrivateBrowsing, isInBrowserElement, appId, extendedOrigin);

  mState = WCC_OPENED;

  return NS_OK;
}
예제 #11
0
NS_IMETHODIMP
nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
    if (!CanSetLoadGroup(aLoadGroup)) {
        return NS_ERROR_FAILURE;
    }

    mLoadGroup = aLoadGroup;
    NS_QueryNotificationCallbacks(mCallbacks,
                                  mLoadGroup,
                                  NS_GET_IID(nsIProgressEventSink),
                                  getter_AddRefs(mProgressSink));
    mPrivateBrowsing = NS_UsePrivateBrowsing(this);
    NS_GetAppInfo(this, &mAppId, &mInBrowser);
    return NS_OK;
}
예제 #12
0
// static
nsresult
nsChannelClassifier::NotifyTrackingProtectionDisabled(nsIChannel *aChannel)
{
    // Can be called in EITHER the parent or child process.
    nsCOMPtr<nsIParentChannel> parentChannel;
    NS_QueryNotificationCallbacks(aChannel, parentChannel);
    if (parentChannel) {
      // This channel is a parent-process proxy for a child process request.
      // Tell the child process channel to do this instead.
      parentChannel->NotifyTrackingProtectionDisabled();
      return NS_OK;
    }

    nsresult rv;
    nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
        do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<mozIDOMWindowProxy> win;
    rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, getter_AddRefs(win));
    NS_ENSURE_SUCCESS(rv, rv);

    auto* pwin = nsPIDOMWindowOuter::From(win);
    nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
    if (!docShell) {
      return NS_OK;
    }
    nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
    NS_ENSURE_TRUE(doc, NS_OK);

    // Notify nsIWebProgressListeners of this security event.
    // Can be used to change the UI state.
    nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell, &rv);
    NS_ENSURE_SUCCESS(rv, NS_OK);
    uint32_t state = 0;
    nsCOMPtr<nsISecureBrowserUI> securityUI;
    docShell->GetSecurityUI(getter_AddRefs(securityUI));
    if (!securityUI) {
      return NS_OK;
    }
    doc->SetHasTrackingContentLoaded(true);
    securityUI->GetState(&state);
    state |= nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT;
    eventSink->OnSecurityChange(nullptr, state);

    return NS_OK;
}
예제 #13
0
NS_IMETHODIMP
nsWyciwygChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
  if (!CanSetLoadGroup(aLoadGroup)) {
    return NS_ERROR_FAILURE;
  }

  mLoadGroup = aLoadGroup;
  NS_QueryNotificationCallbacks(mCallbacks,
                                mLoadGroup,
                                NS_GET_IID(nsIProgressEventSink),
                                getter_AddRefs(mProgressSink));
  UpdatePrivateBrowsing();
  NS_GetOriginAttributes(this, mOriginAttributes);

  return NS_OK;
}
예제 #14
0
NS_IMETHODIMP
nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
  if (!CanSetCallbacks(aNotificationCallbacks)) {
    return NS_ERROR_FAILURE;
  }

  mCallbacks = aNotificationCallbacks;
  NS_QueryNotificationCallbacks(mCallbacks,
                                mLoadGroup,
                                NS_GET_IID(nsIProgressEventSink),
                                getter_AddRefs(mProgressSink));

  UpdatePrivateBrowsing();
  NS_GetOriginAttributes(this, mOriginAttributes);

  return NS_OK;
}
예제 #15
0
NS_IMETHODIMP
nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{
    if (!CanSetCallbacks(aNotificationCallbacks)) {
        return NS_ERROR_FAILURE;
    }

    mCallbacks = aNotificationCallbacks;
    NS_QueryNotificationCallbacks(mCallbacks,
                                  mLoadGroup,
                                  NS_GET_IID(nsIProgressEventSink),
                                  getter_AddRefs(mProgressSink));

    mPrivateBrowsing = NS_UsePrivateBrowsing(this);
    NS_GetAppInfo(this, &mAppId, &mInBrowser);

    return NS_OK;
}
예제 #16
0
NS_IMETHODIMP
nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
{
    LOG(("nsJARChannel::AsyncOpen [this=%x]\n", this));

    NS_ENSURE_ARG_POINTER(listener);
    NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);

    mJarFile = nsnull;
    mIsUnsafe = PR_TRUE;

    // Initialize mProgressSink
    NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);

    nsresult rv = EnsureJarInput(PR_FALSE);
    if (NS_FAILED(rv)) return rv;

    // These variables must only be set if we're going to trigger an
    // OnStartRequest, either from AsyncRead or OnDownloadComplete.
    mListener = listener;
    mListenerContext = ctx;
    mIsPending = PR_TRUE;
    if (mJarInput) {
        // create input stream pump and call AsyncRead as a block
        rv = NS_NewInputStreamPump(getter_AddRefs(mPump), mJarInput);
        if (NS_SUCCEEDED(rv))
            rv = mPump->AsyncRead(this, nsnull);

        // If we failed to create the pump or initiate the AsyncRead,
        // then we need to clear these variables.
        if (NS_FAILED(rv)) {
            mIsPending = PR_FALSE;
            mListenerContext = nsnull;
            mListener = nsnull;
            return rv;
        }
    }

    if (mLoadGroup)
        mLoadGroup->AddRequest(this, nsnull);

    return NS_OK;
}
예제 #17
0
NS_IMETHODIMP
nsGopherChannel::OnTransportStatus(nsITransport *trans, nsresult status,
                                   PRUint64 progress, PRUint64 progressMax)
{
    if (!mProgressSink)
        NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);

    // suppress status notification if channel is no longer pending!
    if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
        NS_ConvertUTF8toUTF16 host(mHost);
        mProgressSink->OnStatus(this, nsnull, status, host.get());

        if (status == nsISocketTransport::STATUS_RECEIVING_FROM ||
            status == nsISocketTransport::STATUS_SENDING_TO) {
            mProgressSink->OnProgress(this, nsnull, progress, progressMax);
        }
    }
    return NS_OK;
}
예제 #18
0
NS_IMETHODIMP
ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin)
{
  NS_ENSURE_ARG(aWin);

  nsresult rv;
  // Find the associated window and its parent window.
  nsCOMPtr<nsILoadContext> ctx;
  NS_QueryNotificationCallbacks(aChannel, ctx);
  if (!ctx) {
    return NS_ERROR_INVALID_ARG;
  }

  nsCOMPtr<nsIDOMWindow> window;
  rv = ctx->GetAssociatedWindow(getter_AddRefs(window));
  if (!window) {
    return NS_ERROR_INVALID_ARG;
  }

  rv = window->GetTop(aWin);
  return rv;
}
예제 #19
0
NS_IMETHODIMP
ThirdPartyUtil::GetTopWindowForChannel(nsIChannel* aChannel, nsIDOMWindow** aWin)
{
  NS_ENSURE_ARG(aWin);

  // Find the associated window and its parent window.
  nsCOMPtr<nsILoadContext> ctx;
  NS_QueryNotificationCallbacks(aChannel, ctx);
  if (!ctx) {
    return NS_ERROR_INVALID_ARG;
  }

  nsCOMPtr<nsIDOMWindow> window;
  ctx->GetAssociatedWindow(getter_AddRefs(window));
  nsCOMPtr<nsPIDOMWindow> top = do_QueryInterface(window);
  if (!top) {
    return NS_ERROR_INVALID_ARG;
  }
  
  top = top->GetTop();
  top.forget(aWin);
  return NS_OK;
}
NS_IMETHODIMP
nsAsyncRedirectVerifyHelper::Run()
{
    /* If the channel got canceled after it fired AsyncOnChannelRedirect
     * and before we got here, mostly because docloader load has been canceled,
     * we must completely ignore this notification and prevent any further
     * notification.
     */
    if (IsOldChannelCanceled()) {
        ExplicitCallback(NS_BINDING_ABORTED);
        return NS_OK;
    }

    // First, the global observer
    NS_ASSERTION(gIOService, "Must have an IO service at this point");
    LOG(("nsAsyncRedirectVerifyHelper::Run() calling gIOService..."));
    nsresult rv = gIOService->AsyncOnChannelRedirect(mOldChan, mNewChan,
                                                     mFlags, this);
    if (NS_FAILED(rv)) {
        ExplicitCallback(rv);
        return NS_OK;
    }

    // Now, the per-channel observers
    nsCOMPtr<nsIChannelEventSink> sink;
    NS_QueryNotificationCallbacks(mOldChan, sink);
    if (sink) {
        LOG(("nsAsyncRedirectVerifyHelper::Run() calling sink..."));
        rv = DelegateOnChannelRedirect(sink, mOldChan, mNewChan, mFlags);
    }

    // All invocations to AsyncOnChannelRedirect has been done - call
    // InitCallback() to flag this
    InitCallback();
    return NS_OK;
}
예제 #21
0
/**
 * This function is called when username or password are requested from user.
 * This function is called in main thread as async request from dbus.
 * @param mount_op mount operation
 * @param message message to show to user
 * @param default_user preffered user
 * @param default_domain domain name
 * @param flags what type of information is required
 * @param user_data nsIChannel
 */
static void
mount_operation_ask_password (GMountOperation   *mount_op,
                              const char        *message,
                              const char        *default_user,
                              const char        *default_domain,
                              GAskPasswordFlags flags,
                              gpointer          user_data)
{
  nsIChannel *channel = (nsIChannel *) user_data;
  if (!channel) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  // We can't handle request for domain
  if (flags & G_ASK_PASSWORD_NEED_DOMAIN) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }

  nsCOMPtr<nsIAuthPrompt> prompt;
  NS_QueryNotificationCallbacks(channel, prompt);

  // If no auth prompt, then give up.  We could failover to using the
  // WindowWatcher service, but that might defeat a consumer's purposeful
  // attempt to disable authentication (for whatever reason).
  if (!prompt) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  // Parse out the host and port...
  nsCOMPtr<nsIURI> uri;
  channel->GetURI(getter_AddRefs(uri));
  if (!uri) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }

  nsAutoCString scheme, hostPort;
  uri->GetScheme(scheme);
  uri->GetHostPort(hostPort);

  // It doesn't make sense for either of these strings to be empty.  What kind
  // of funky URI is this?
  if (scheme.IsEmpty() || hostPort.IsEmpty()) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  // Construct the single signon key.  Altering the value of this key will
  // cause people's remembered passwords to be forgotten.  Think carefully
  // before changing the way this key is constructed.
  nsAutoString key, realm;

  NS_ConvertUTF8toUTF16 dispHost(scheme);
  dispHost.AppendLiteral("://");
  dispHost.Append(NS_ConvertUTF8toUTF16(hostPort));

  key = dispHost;
  if (*default_domain != '\0')
  {
    // We assume the realm string is ASCII.  That might be a bogus assumption,
    // but we have no idea what encoding GnomeVFS is using, so for now we'll
    // limit ourselves to ISO-Latin-1.  XXX What is a better solution?
    realm.Append('"');
    realm.Append(NS_ConvertASCIItoUTF16(default_domain));
    realm.Append('"');
    key.Append(' ');
    key.Append(realm);
  }
  // Construct the message string...
  //
  // We use Necko's string bundle here.  This code really should be encapsulated
  // behind some Necko API, after all this code is based closely on the code in
  // nsHttpChannel.cpp.
  nsCOMPtr<nsIStringBundleService> bundleSvc =
      do_GetService(NS_STRINGBUNDLE_CONTRACTID);
  if (!bundleSvc) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  nsCOMPtr<nsIStringBundle> bundle;
  bundleSvc->CreateBundle("chrome://global/locale/commonDialogs.properties",
                          getter_AddRefs(bundle));
  if (!bundle) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  nsAutoString nsmessage;

  if (flags & G_ASK_PASSWORD_NEED_PASSWORD) {
    if (flags & G_ASK_PASSWORD_NEED_USERNAME) {
      if (!realm.IsEmpty()) {
        const char16_t *strings[] = { realm.get(), dispHost.get() };
        bundle->FormatStringFromName(MOZ_UTF16("EnterLoginForRealm2"),
                                     strings, 2, getter_Copies(nsmessage));
      } else {
        const char16_t *strings[] = { dispHost.get() };
        bundle->FormatStringFromName(MOZ_UTF16("EnterUserPasswordFor2"),
                                     strings, 1, getter_Copies(nsmessage));
      }
    } else {
      NS_ConvertUTF8toUTF16 userName(default_user);
      const char16_t *strings[] = { userName.get(), dispHost.get() };
      bundle->FormatStringFromName(MOZ_UTF16("EnterPasswordFor"),
                                   strings, 2, getter_Copies(nsmessage));
    }
  } else {
    g_warning("Unknown mount operation request (flags: %x)", flags);
  }

  if (nsmessage.IsEmpty()) {
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    return;
  }
  // Prompt the user...
  nsresult rv;
  bool retval = false;
  char16_t *user = nullptr, *pass = nullptr;
  if (default_user) {
    // user will be freed by PromptUsernameAndPassword
    user = ToNewUnicode(NS_ConvertUTF8toUTF16(default_user));
  }
  if (flags & G_ASK_PASSWORD_NEED_USERNAME) {
    rv = prompt->PromptUsernameAndPassword(nullptr, nsmessage.get(),
                                           key.get(),
                                           nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
                                           &user, &pass, &retval);
  } else {
    rv = prompt->PromptPassword(nullptr, nsmessage.get(),
                                key.get(),
                                nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
                                &pass, &retval);
  }
  if (NS_FAILED(rv) || !retval) {  //  was || user == '\0' || pass == '\0'
    g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_ABORTED);
    free(user);
    free(pass);
    return;
  }
  /* GIO should accept UTF8 */
  g_mount_operation_set_username(mount_op, NS_ConvertUTF16toUTF8(user).get());
  g_mount_operation_set_password(mount_op, NS_ConvertUTF16toUTF8(pass).get());
  free(user);
  free(pass);
  g_mount_operation_reply(mount_op, G_MOUNT_OPERATION_HANDLED);
}
bool
nsHttpChannelAuthProvider::ConfirmAuth(const nsString &bundleKey,
                                       bool            doYesNoPrompt)
{
    // skip prompting the user if
    //   1) we've already prompted the user
    //   2) we're not a toplevel channel
    //   3) the userpass length is less than the "phishy" threshold

    uint32_t loadFlags;
    nsresult rv = mAuthChannel->GetLoadFlags(&loadFlags);
    if (NS_FAILED(rv))
        return true;

    if (mSuppressDefensiveAuth ||
        !(loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI))
        return true;

    nsCAutoString userPass;
    rv = mURI->GetUserPass(userPass);
    if (NS_FAILED(rv) ||
        (userPass.Length() < gHttpHandler->PhishyUserPassLength()))
        return true;

    // we try to confirm by prompting the user.  if we cannot do so, then
    // assume the user said ok.  this is done to keep things working in
    // embedded builds, where the string bundle might not be present, etc.

    nsCOMPtr<nsIStringBundleService> bundleService =
            do_GetService(NS_STRINGBUNDLE_CONTRACTID);
    if (!bundleService)
        return true;

    nsCOMPtr<nsIStringBundle> bundle;
    bundleService->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(bundle));
    if (!bundle)
        return true;

    nsCAutoString host;
    rv = mURI->GetHost(host);
    if (NS_FAILED(rv))
        return true;

    nsCAutoString user;
    rv = mURI->GetUsername(user);
    if (NS_FAILED(rv))
        return true;

    NS_ConvertUTF8toUTF16 ucsHost(host), ucsUser(user);
    const PRUnichar *strs[2] = { ucsHost.get(), ucsUser.get() };

    nsXPIDLString msg;
    bundle->FormatStringFromName(bundleKey.get(), strs, 2, getter_Copies(msg));
    if (!msg)
        return true;

    nsCOMPtr<nsIInterfaceRequestor> callbacks;
    rv = mAuthChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
    if (NS_FAILED(rv))
        return true;

    nsCOMPtr<nsILoadGroup> loadGroup;
    rv = mAuthChannel->GetLoadGroup(getter_AddRefs(loadGroup));
    if (NS_FAILED(rv))
        return true;

    nsCOMPtr<nsIPrompt> prompt;
    NS_QueryNotificationCallbacks(callbacks, loadGroup, NS_GET_IID(nsIPrompt),
                                  getter_AddRefs(prompt));
    if (!prompt)
        return true;

    // do not prompt again
    mSuppressDefensiveAuth = true;

    bool confirmed;
    if (doYesNoPrompt) {
        int32_t choice;
        // The actual value is irrelevant but we shouldn't be handing out
        // malformed JSBools to XPConnect.
        bool checkState = false;
        rv = prompt->ConfirmEx(nullptr, msg,
                               nsIPrompt::BUTTON_POS_1_DEFAULT +
                               nsIPrompt::STD_YES_NO_BUTTONS,
                               nullptr, nullptr, nullptr, nullptr,
                               &checkState, &choice);
        if (NS_FAILED(rv))
            return true;

        confirmed = choice == 0;
    }
    else {
        rv = prompt->Confirm(nullptr, msg, &confirmed);
        if (NS_FAILED(rv))
            return true;
    }

    return confirmed;
}
// static
nsresult
nsChannelClassifier::SetBlockedTrackingContent(nsIChannel *channel)
{
  // Can be called in EITHER the parent or child process.
  nsCOMPtr<nsIParentChannel> parentChannel;
  NS_QueryNotificationCallbacks(channel, parentChannel);
  if (parentChannel) {
    // This channel is a parent-process proxy for a child process request. The
    // actual channel will be notified via the status passed to
    // nsIRequest::Cancel and do this for us.
    return NS_OK;
  }

  nsresult rv;
  nsCOMPtr<mozIDOMWindowProxy> win;
  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
    do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, NS_OK);
  rv = thirdPartyUtil->GetTopWindowForChannel(channel, getter_AddRefs(win));
  NS_ENSURE_SUCCESS(rv, NS_OK);
  auto* pwin = nsPIDOMWindowOuter::From(win);
  nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
  if (!docShell) {
    return NS_OK;
  }
  nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
  NS_ENSURE_TRUE(doc, NS_OK);

  // This event might come after the user has navigated to another page.
  // To prevent showing the TrackingProtection UI on the wrong page, we need to
  // check that the loading URI for the channel is the same as the URI currently
  // loaded in the document.
  if (!SameLoadingURI(doc, channel)) {
    return NS_OK;
  }

  // Notify nsIWebProgressListeners of this security event.
  // Can be used to change the UI state.
  nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell, &rv);
  NS_ENSURE_SUCCESS(rv, NS_OK);
  uint32_t state = 0;
  nsCOMPtr<nsISecureBrowserUI> securityUI;
  docShell->GetSecurityUI(getter_AddRefs(securityUI));
  if (!securityUI) {
    return NS_OK;
  }
  doc->SetHasTrackingContentBlocked(true);
  securityUI->GetState(&state);
  state |= nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
  eventSink->OnSecurityChange(nullptr, state);

  // Log a warning to the web console.
  nsCOMPtr<nsIURI> uri;
  channel->GetURI(getter_AddRefs(uri));
  NS_ConvertUTF8toUTF16 spec(uri->GetSpecOrDefault());
  const char16_t* params[] = { spec.get() };
  nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                  NS_LITERAL_CSTRING("Tracking Protection"),
                                  doc,
                                  nsContentUtils::eNECKO_PROPERTIES,
                                  "TrackingUriBlocked",
                                  params, ArrayLength(params));

  return NS_OK;
}
static void
ProxiedAuthCallback(gconstpointer in,
                    gsize         in_size,
                    gpointer      out,
                    gsize         out_size,
                    gpointer      callback_data)
{
  GnomeVFSModuleCallbackAuthenticationIn *authIn =
      (GnomeVFSModuleCallbackAuthenticationIn *) in;
  GnomeVFSModuleCallbackAuthenticationOut *authOut =
      (GnomeVFSModuleCallbackAuthenticationOut *) out;

  LOG(("gnomevfs: ProxiedAuthCallback [uri=%s]\n", authIn->uri));

  // Without a channel, we have no way of getting a prompter.
  nsIChannel *channel = (nsIChannel *) callback_data;
  if (!channel)
    return;

  nsCOMPtr<nsIAuthPrompt> prompt;
  NS_QueryNotificationCallbacks(channel, prompt);

  // If no auth prompt, then give up.  We could failover to using the
  // WindowWatcher service, but that might defeat a consumer's purposeful
  // attempt to disable authentication (for whatever reason).
  if (!prompt)
    return;

  // Parse out the host and port...
  nsCOMPtr<nsIURI> uri;
  channel->GetURI(getter_AddRefs(uri));
  if (!uri)
    return;

#ifdef DEBUG
  {
    //
    // Make sure authIn->uri is consistent with the channel's URI.
    //
    // XXX This check is probably not IDN safe, and it might incorrectly
    //     fire as a result of escaping differences.  It's unclear what
    //     kind of transforms GnomeVFS might have applied to the URI spec
    //     that we originally gave to it.  In spite of the likelihood of
    //     false hits, this check is probably still valuable.
    //
    nsAutoCString spec;
    uri->GetSpec(spec);
    int uriLen = strlen(authIn->uri);
    if (!StringHead(spec, uriLen).Equals(nsDependentCString(authIn->uri, uriLen)))
    {
      LOG(("gnomevfs: [spec=%s authIn->uri=%s]\n", spec.get(), authIn->uri));
      NS_ERROR("URI mismatch");
    }
  }
#endif

  nsAutoCString scheme, hostPort;
  uri->GetScheme(scheme);
  uri->GetHostPort(hostPort);

  // It doesn't make sense for either of these strings to be empty.  What kind
  // of funky URI is this?
  if (scheme.IsEmpty() || hostPort.IsEmpty())
    return;

  // Construct the single signon key.  Altering the value of this key will
  // cause people's remembered passwords to be forgotten.  Think carefully
  // before changing the way this key is constructed.
  nsAutoString key, realm;

  NS_ConvertUTF8toUTF16 dispHost(scheme);
  dispHost.AppendLiteral("://");
  dispHost.Append(NS_ConvertUTF8toUTF16(hostPort));

  key = dispHost;
  if (authIn->realm)
  {
    // We assume the realm string is ASCII.  That might be a bogus assumption,
    // but we have no idea what encoding GnomeVFS is using, so for now we'll
    // limit ourselves to ISO-Latin-1.  XXX What is a better solution?
    realm.Append('"');
    realm.Append(NS_ConvertASCIItoUTF16(authIn->realm));
    realm.Append('"');
    key.Append(' ');
    key.Append(realm);
  }

  // Construct the message string...
  //
  // We use Necko's string bundle here.  This code really should be encapsulated
  // behind some Necko API, after all this code is based closely on the code in
  // nsHttpChannel.cpp.

  nsCOMPtr<nsIStringBundleService> bundleSvc =
      do_GetService(NS_STRINGBUNDLE_CONTRACTID);
  if (!bundleSvc)
    return;

  nsCOMPtr<nsIStringBundle> bundle;
  bundleSvc->CreateBundle("chrome://global/locale/commonDialogs.properties",
                          getter_AddRefs(bundle));
  if (!bundle)
    return;

  nsString message;
  if (!realm.IsEmpty())
  {
    const char16_t *strings[] = { realm.get(), dispHost.get() };
    bundle->FormatStringFromName(MOZ_UTF16("EnterUserPasswordForRealm"),
                                 strings, 2, getter_Copies(message));
  }
  else
  {
    const char16_t *strings[] = { dispHost.get() };
    bundle->FormatStringFromName(MOZ_UTF16("EnterUserPasswordFor"),
                                 strings, 1, getter_Copies(message));
  }
  if (message.IsEmpty())
    return;

  // Prompt the user...
  nsresult rv;
  bool retval = false;
  char16_t *user = nullptr, *pass = nullptr;

  rv = prompt->PromptUsernameAndPassword(nullptr, message.get(),
                                         key.get(),
                                         nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
                                         &user, &pass, &retval);
  if (NS_FAILED(rv))
    return;
  if (!retval || !user || !pass)
    return;

  // XXX We need to convert the UTF-16 username and password from our dialog to
  // strings that GnomeVFS can understand.  It's unclear what encoding GnomeVFS
  // expects, so for now we assume 7-bit ASCII.  Hopefully, we can get a better
  // solution at some point.

  // One copy is never enough...
  authOut->username = g_strdup(NS_LossyConvertUTF16toASCII(user).get());
  authOut->password = g_strdup(NS_LossyConvertUTF16toASCII(pass).get());

  nsMemory::Free(user);
  nsMemory::Free(pass);
}
NS_IMETHODIMP 
nsCookiePermission::CanSetCookie(nsIURI     *aURI,
                                 nsIChannel *aChannel,
                                 nsICookie2 *aCookie,
                                 bool       *aIsSession,
                                 PRInt64    *aExpiry,
                                 bool       *aResult)
{
  NS_ASSERTION(aURI, "null uri");

  *aResult = kDefaultPolicy;

  // Lazily initialize ourselves
  if (!EnsureInitialized())
    return NS_ERROR_UNEXPECTED;

  PRUint32 perm;
  mPermMgr->TestPermission(aURI, kPermissionType, &perm);
  switch (perm) {
  case nsICookiePermission::ACCESS_SESSION:
    *aIsSession = true;

  case nsIPermissionManager::ALLOW_ACTION: // ACCESS_ALLOW
    *aResult = true;
    break;

  case nsIPermissionManager::DENY_ACTION:  // ACCESS_DENY
    *aResult = false;
    break;

  default:
    // the permission manager has nothing to say about this cookie -
    // so, we apply the default prefs to it.
    NS_ASSERTION(perm == nsIPermissionManager::UNKNOWN_ACTION, "unknown permission");
    
    // now we need to figure out what type of accept policy we're dealing with
    // if we accept cookies normally, just bail and return
    if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) {
      *aResult = true;
      return NS_OK;
    }
    
    // declare this here since it'll be used in all of the remaining cases
    PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC;
    PRInt64 delta = *aExpiry - currentTime;
    
    // check whether the user wants to be prompted
    if (mCookiesLifetimePolicy == ASK_BEFORE_ACCEPT) {
      // if it's a session cookie and the user wants to accept these 
      // without asking, or if we are in private browsing mode, just
      // accept the cookie and return
      if ((*aIsSession && mCookiesAlwaysAcceptSession) ||
          InPrivateBrowsing()) {
        *aResult = true;
        return NS_OK;
      }
      
      // default to rejecting, in case the prompting process fails
      *aResult = false;

      nsCAutoString hostPort;
      aURI->GetHostPort(hostPort);

      if (!aCookie) {
         return NS_ERROR_UNEXPECTED;
      }
      // If there is no host, use the scheme, and append "://",
      // to make sure it isn't a host or something.
      // This is done to make the dialog appear for javascript cookies from
      // file:// urls, and make the text on it not too weird. (bug 209689)
      if (hostPort.IsEmpty()) {
        aURI->GetScheme(hostPort);
        if (hostPort.IsEmpty()) {
          // still empty. Just return the default.
          return NS_OK;
        }
        hostPort = hostPort + NS_LITERAL_CSTRING("://");
      }

      // we don't cache the cookiePromptService - it's not used often, so not
      // worth the memory.
      nsresult rv;
      nsCOMPtr<nsICookiePromptService> cookiePromptService =
          do_GetService(NS_COOKIEPROMPTSERVICE_CONTRACTID, &rv);
      if (NS_FAILED(rv)) return rv;

      // try to get a nsIDOMWindow from the channel...
      nsCOMPtr<nsIDOMWindow> parent;
      if (aChannel) {
        nsCOMPtr<nsILoadContext> ctx;
        NS_QueryNotificationCallbacks(aChannel, ctx);
        if (ctx) {
          ctx->GetAssociatedWindow(getter_AddRefs(parent));
        }
      }

      // get some useful information to present to the user:
      // whether a previous cookie already exists, and how many cookies this host
      // has set
      bool foundCookie = false;
      PRUint32 countFromHost;
      nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv);
      if (NS_SUCCEEDED(rv)) {
        nsCAutoString rawHost;
        aCookie->GetRawHost(rawHost);
        rv = cookieManager->CountCookiesFromHost(rawHost, &countFromHost);

        if (NS_SUCCEEDED(rv) && countFromHost > 0)
          rv = cookieManager->CookieExists(aCookie, &foundCookie);
      }
      if (NS_FAILED(rv)) return rv;

      // check if the cookie we're trying to set is already expired, and return;
      // but only if there's no previous cookie, because then we need to delete the previous
      // cookie. we need this check to avoid prompting the user for already-expired cookies.
      if (!foundCookie && !*aIsSession && delta <= 0) {
        // the cookie has already expired. accept it, and let the backend figure
        // out it's expired, so that we get correct logging & notifications.
        *aResult = true;
        return rv;
      }

      bool rememberDecision = false;
      PRInt32 dialogRes = nsICookiePromptService::DENY_COOKIE;
      rv = cookiePromptService->CookieDialog(parent, aCookie, hostPort, 
                                             countFromHost, foundCookie,
                                             &rememberDecision, &dialogRes);
      if (NS_FAILED(rv)) return rv;

      *aResult = !!dialogRes;
      if (dialogRes == nsICookiePromptService::ACCEPT_SESSION_COOKIE)
        *aIsSession = true;

      if (rememberDecision) {
        switch (dialogRes) {
          case nsICookiePromptService::DENY_COOKIE:
            mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::DENY_ACTION,
                          nsIPermissionManager::EXPIRE_NEVER, 0);
            break;
          case nsICookiePromptService::ACCEPT_COOKIE:
            mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::ALLOW_ACTION,
                          nsIPermissionManager::EXPIRE_NEVER, 0);
            break;
          case nsICookiePromptService::ACCEPT_SESSION_COOKIE:
            mPermMgr->Add(aURI, kPermissionType, nsICookiePermission::ACCESS_SESSION,
                          nsIPermissionManager::EXPIRE_NEVER, 0);
            break;
          default:
            break;
        }
      }
    } else {
      // we're not prompting, so we must be limiting the lifetime somehow
      // if it's a session cookie, we do nothing
      if (!*aIsSession && delta > 0) {
        if (mCookiesLifetimePolicy == ACCEPT_SESSION) {
          // limit lifetime to session
          *aIsSession = true;
        } else if (delta > mCookiesLifetimeSec) {
          // limit lifetime to specified time
          *aExpiry = currentTime + mCookiesLifetimeSec;
        }
      }
    }
  }

  return NS_OK;
}
예제 #26
0
NS_IMETHODIMP
nsCookiePermission::CanAccess(nsIURI         *aURI,
                              nsIURI         *aFirstURI,
                              nsIChannel     *aChannel,
                              nsCookieAccess *aResult)
{
#ifdef MOZ_MAIL_NEWS
  // disable cookies in mailnews if user's prefs say so
  if (mCookiesDisabledForMailNews) {
    //
    // try to examine the "app type" of the docshell owning this request.  if
    // we find a docshell in the heirarchy of type APP_TYPE_MAIL, then assume
    // this URI is being loaded from within mailnews.
    //
    // XXX this is a pretty ugly hack at the moment since cookies really
    // shouldn't have to talk to the docshell directly.  ultimately, we want
    // to talk to some more generic interface, which the docshell would also
    // implement.  but, the basic mechanism here of leveraging the channel's
    // (or loadgroup's) notification callbacks attribute seems ideal as it
    // avoids the problem of having to modify all places in the code which
    // kick off network requests.
    //
    PRUint32 appType = nsIDocShell::APP_TYPE_UNKNOWN;
    if (aChannel) {
      nsCOMPtr<nsIDocShellTreeItem> item, parent;
      NS_QueryNotificationCallbacks(aChannel, parent);
      if (parent) {
        do {
            item = parent;
            nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(item);
            if (docshell)
              docshell->GetAppType(&appType);
        } while (appType != nsIDocShell::APP_TYPE_MAIL &&
                 NS_SUCCEEDED(item->GetParent(getter_AddRefs(parent))) &&
                 parent);
      }
    }
    if ((appType == nsIDocShell::APP_TYPE_MAIL) ||
        (aFirstURI && IsFromMailNews(aFirstURI)) ||
        IsFromMailNews(aURI)) {
      *aResult = ACCESS_DENY;
      return NS_OK;
    }
  }
#endif // MOZ_MAIL_NEWS
  
  // finally, check with permission manager...
  nsresult rv = mPermMgr->TestPermission(aURI, kPermissionType, (PRUint32 *) aResult);
  if (NS_SUCCEEDED(rv)) {
    switch (*aResult) {
    // if we have one of the publicly-available values, just return it
    case nsIPermissionManager::UNKNOWN_ACTION: // ACCESS_DEFAULT
    case nsIPermissionManager::ALLOW_ACTION:   // ACCESS_ALLOW
    case nsIPermissionManager::DENY_ACTION:    // ACCESS_DENY
      break;

    // ACCESS_SESSION means the cookie can be accepted; the session 
    // downgrade will occur in CanSetCookie().
    case nsICookiePermission::ACCESS_SESSION:
      *aResult = ACCESS_ALLOW;
      break;

    // ack, an unknown type! just use the defaults.
    default:
      *aResult = ACCESS_DEFAULT;
    }
  }

  return rv;
}
예제 #27
0
nsresult
nsGopherChannel::SendRequest()
{
    nsresult rv = NS_OK;

    // Note - you have to keep this as a class member, because the char input
    // stream doesn't copy its buffer
    mRequest.Assign(mSelector);

    // So, we use the selector as is unless it is a search url
    if (mType=='7') {
        // Note that we don't use the "standard" nsIURL parsing stuff here
        // because the only special character is ?, and its possible to search
        // for a string containing a #, and so on
        
        // XXX - should this find the last or first entry?
        // '?' is valid in both the search string and the url
        // so no matter what this does, it may be incorrect
        // This only affects people codeing the query directly into the URL
        PRInt32 pos = mRequest.RFindChar('?');
        if (pos == -1) {
            // We require a query string here - if we don't have one,
            // then we need to ask the user
            nsCOMPtr<nsIPrompt> prompter;
            NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, prompter);
            if (!prompter) {
                NS_ERROR("We need a prompter!");
                return NS_ERROR_FAILURE;
            }

            if (!mStringBundle) {

                nsCOMPtr<nsIStringBundleService> bundleSvc =
                        do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
                if (NS_FAILED(rv)) return rv;

                rv = bundleSvc->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(mStringBundle));
                if (NS_FAILED(rv)) return rv;

            }

            nsXPIDLString  promptTitle;
            nsXPIDLString  promptText;

            if (mStringBundle)
                rv = mStringBundle->GetStringFromName(NS_LITERAL_STRING("GopherPromptTitle").get(),
                                                      getter_Copies(promptTitle));

            if (NS_FAILED(rv) || !mStringBundle)
                promptTitle.AssignLiteral("Search");


            if (mStringBundle)
                rv = mStringBundle->GetStringFromName(NS_LITERAL_STRING("GopherPromptText").get(),
                                                      getter_Copies(promptText));

            if (NS_FAILED(rv) || !mStringBundle)
                promptText.AssignLiteral("Enter a search term:");


            nsXPIDLString search;
            PRBool res;
            prompter->Prompt(promptTitle.get(),
                              promptText.get(),
                              getter_Copies(search),
                              NULL,
                              NULL,
                              &res);
            if (!res || !(*search.get()))
                return NS_ERROR_FAILURE;
    
            mRequest.Append('\t');
            AppendUTF16toUTF8(search, mRequest); // XXX Is UTF-8 the right thing?

            // and update our uri
            nsCAutoString spec;
            rv = mUrl->GetAsciiSpec(spec);
            if (NS_FAILED(rv))
                return rv;

            spec.Append('?');
            AppendUTF16toUTF8(search, spec);
            rv = mUrl->SetSpec(spec);
            if (NS_FAILED(rv))
                return rv;
        } else {
            // Just replace it with a tab
            mRequest.SetCharAt('\t',pos);
        }
    }

    mRequest.Append(CRLF);
    
    PR_LOG(gGopherLog,PR_LOG_DEBUG,
           ("Sending: %s\n", mRequest.get()));

    // open a buffered, blocking output stream.  (it should never block because
    // the buffer is big enough for our entire request.)
    nsCOMPtr<nsIOutputStream> output;
    rv = mTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
                                      mRequest.Length(), 1,
                                      getter_AddRefs(output));
    if (NS_FAILED(rv)) return rv;

    PRUint32 n;
    rv = output->Write(mRequest.get(), mRequest.Length(), &n);
    if (NS_FAILED(rv)) return rv;

    if (n != mRequest.Length())
        return NS_ERROR_UNEXPECTED;

    return NS_OK;
}
예제 #28
0
// Determine if the URI associated with aChannel or any URI of the window
// hierarchy associated with the channel is foreign with respect to aSecondURI.
// See docs for mozIThirdPartyUtil.
NS_IMETHODIMP 
ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
                                    nsIURI* aURI,
                                    bool* aResult)
{
  NS_ENSURE_ARG(aChannel);
  NS_ASSERTION(aResult, "null outparam pointer");

  nsresult rv;
  bool doForce = false;
  nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
    do_QueryInterface(aChannel);
  if (httpChannelInternal) {
    rv = httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce);
    NS_ENSURE_SUCCESS(rv, rv);

    // If aURI was not supplied, and we're forcing, then we're by definition
    // not foreign. If aURI was supplied, we still want to check whether it's
    // foreign with respect to the channel URI. (The forcing only applies to
    // whatever window hierarchy exists above the channel.)
    if (doForce && !aURI) {
      *aResult = false;
      return NS_OK;
    }
  }

  // Obtain the URI from the channel, and its base domain.
  nsCOMPtr<nsIURI> channelURI;
  aChannel->GetURI(getter_AddRefs(channelURI));
  NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);

  nsCString channelDomain;
  rv = GetBaseDomain(channelURI, channelDomain);
  if (NS_FAILED(rv))
    return rv;

  if (aURI) {
    // Determine whether aURI is foreign with respect to channelURI.
    bool result;
    rv = IsThirdPartyInternal(channelDomain, aURI, &result);
    if (NS_FAILED(rv))
     return rv;

    // If it's foreign, or we're forcing, we're done.
    if (result || doForce) {
      *aResult = result;
      return NS_OK;
    }
  }

  // Find the associated window and its parent window.
  nsCOMPtr<nsILoadContext> ctx;
  NS_QueryNotificationCallbacks(aChannel, ctx);
  if (!ctx) return NS_ERROR_INVALID_ARG;

  // If there is no window, the consumer kicking off the load didn't provide one
  // to the channel. This is limited to loads of certain types of resources. If
  // those loads require cookies, the forceAllowThirdPartyCookie property should
  // be set on the channel.
  nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
  ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
  if (!ourWin) return NS_ERROR_INVALID_ARG;

  // We use GetScriptableParent rather than GetParent because we consider
  // <iframe mozbrowser/mozapp> to be a top-level frame.
  ourWin->GetScriptableParent(getter_AddRefs(parentWin));
  NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);

  // Check whether this is the document channel for this window (representing a
  // load of a new page). In that situation we want to avoid comparing
  // channelURI to ourWin, since what's in ourWin right now will be replaced as
  // the channel loads.  This covers the case of a freshly kicked-off load
  // (e.g. the user typing something in the location bar, or clicking on a
  // bookmark), where the window's URI hasn't yet been set, and will be bogus.
  // It also covers situations where a subframe is navigated to someting that
  // is same-origin with all its ancestors.  This is a bit of a nasty hack, but
  // we will hopefully flag these channels better later.
  nsLoadFlags flags;
  rv = aChannel->GetLoadFlags(&flags);
  NS_ENSURE_SUCCESS(rv, rv);

  if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
    if (SameCOMIdentity(ourWin, parentWin)) {
      // We only need to compare aURI to the channel URI -- the window's will be
      // bogus. We already know the answer.
      *aResult = false;
      return NS_OK;
    }

    // Make sure to still compare to ourWin's ancestors
    ourWin = parentWin;
  }

  // Check the window hierarchy. This covers most cases for an ordinary page
  // load from the location bar.
  return IsThirdPartyWindow(ourWin, channelURI, aResult);
}
예제 #29
0
NS_IMETHODIMP
nsBaseChannel::GetInterface(const nsIID &iid, void **result)
{
  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, iid, result);
  return *result ? NS_OK : NS_ERROR_NO_INTERFACE; 
}
NS_IMETHODIMP 
nsCookiePermission::GetOriginatingURI(nsIChannel  *aChannel,
                                      nsIURI     **aURI)
{
  /* to find the originating URI, we use the loadgroup of the channel to obtain
   * the window owning the load, and from there, we find the top same-type
   * window and its URI. there are several possible cases:
   *
   * 1) no channel.
   *
   * 2) a channel with the "force allow third party cookies" option set.
   *    since we may not have a window, we return the channel URI in this case.
   *
   * 3) a channel, but no window. this can occur when the consumer kicking
   *    off the load doesn't provide one to the channel, and should be limited
   *    to loads of certain types of resources.
   *
   * 4) a window equal to the top window of same type, with the channel its
   *    document channel. this covers the case of a freshly kicked-off load
   *    (e.g. the user typing something in the location bar, or clicking on a
   *    bookmark), where the window's URI hasn't yet been set, and will be
   *    bogus. we return the channel URI in this case.
   *
   * 5) Anything else. this covers most cases for an ordinary page load from
   *    the location bar, and will catch nested frames within a page, image
   *    loads, etc. we return the URI of the root window's document's principal
   *    in this case.
   */

  *aURI = nullptr;

  // case 1)
  if (!aChannel)
    return NS_ERROR_NULL_POINTER;

  // case 2)
  nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(aChannel);
  if (httpChannelInternal)
  {
    bool doForce = false;
    if (NS_SUCCEEDED(httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce)) && doForce)
    {
      // return the channel's URI (we may not have a window)
      aChannel->GetURI(aURI);
      if (!*aURI)
        return NS_ERROR_NULL_POINTER;

      return NS_OK;
    }
  }

  // find the associated window and its top window
  nsCOMPtr<nsILoadContext> ctx;
  NS_QueryNotificationCallbacks(aChannel, ctx);
  nsCOMPtr<nsIDOMWindow> topWin, ourWin;
  if (ctx) {
    ctx->GetTopWindow(getter_AddRefs(topWin));
    ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
  }

  // case 3)
  if (!topWin)
    return NS_ERROR_INVALID_ARG;

  // case 4)
  if (ourWin == topWin) {
    // Check whether this is the document channel for this window (representing
    // a load of a new page).  This is a bit of a nasty hack, but we will
    // hopefully flag these channels better later.
    nsLoadFlags flags;
    aChannel->GetLoadFlags(&flags);

    if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
      // get the channel URI - the window's will be bogus
      aChannel->GetURI(aURI);
      if (!*aURI)
        return NS_ERROR_NULL_POINTER;

      return NS_OK;
    }
  }

  // case 5) - get the originating URI from the top window's principal
  nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin);
  NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED);

  nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
  NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
  
  prin->GetURI(aURI);

  if (!*aURI)
    return NS_ERROR_NULL_POINTER;

  // all done!
  return NS_OK;
}