Back to index

lightning-sunbird  0.9+nobinonly
nsMsgContentPolicy.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Scott MacGregor <scott@scott-macgregor.org>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsMsgContentPolicy.h"
00040 #include "nsIServiceManager.h"
00041 #include "nsIDocShellTreeItem.h"
00042 #include "nsIPrefService.h"
00043 #include "nsIPrefBranch2.h"
00044 #include "nsIURI.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsCRT.h"
00047 #include "nsIRDFService.h"
00048 #include "nsIRDFResource.h"
00049 #include "nsIMsgHeaderParser.h"
00050 #include "nsIAbMDBDirectory.h"
00051 #include "nsIAbMDBCard.h"
00052 #include "nsIAbCard.h"
00053 #include "nsIMsgMailNewsUrl.h"
00054 #include "nsIMsgWindow.h"
00055 #include "nsIMimeMiscStatus.h"
00056 #include "nsIMsgMessageService.h"
00057 #include "nsIMsgIncomingServer.h"
00058 #include "nsIRssIncomingServer.h"
00059 #include "nsIMsgHdr.h"
00060 #include "nsMsgUtils.h"
00061 
00062 #include "nsIMsgComposeService.h"
00063 #include "nsIMsgCompose.h"
00064 #include "nsMsgCompCID.h"
00065 
00066 // needed by the content load policy manager
00067 #include "nsIExternalProtocolService.h"
00068 #include "nsCExternalHandlerService.h"
00069 
00070 // needed for the cookie policy manager
00071 #include "nsNetUtil.h"
00072 #include "nsICookie2.h"
00073 #include "nsICookieManager2.h"
00074 
00075 // needed for mailnews content load policy manager
00076 #include "nsIDOMElement.h"
00077 #include "nsIDOMDocument.h"
00078 #include "nsIDOMWindowInternal.h"
00079 #include "nsIDocShell.h"
00080 #include "nsIWebNavigation.h"
00081 #include "nsIDocShellTreeNode.h"
00082 #include "nsContentPolicyUtils.h"
00083 #include "nsIDOMHTMLImageElement.h"
00084 
00085 static const char kBlockRemoteImages[] = "mailnews.message_display.disable_remote_image";
00086 static const char kAllowPlugins[] = "mailnews.message_display.allow.plugins";
00087 static const char kTrustedDomains[] =  "mail.trusteddomains";
00088 
00089 // Per message headder flags to keep track of whether the user is allowing remote
00090 // content for a particular message. 
00091 // if you change or add more values to these constants, be sure to modify
00092 // the corresponding definitions in mailWindowOverlay.js
00093 #define kNoRemoteContentPolicy 0
00094 #define kBlockRemoteContent 1
00095 #define kAllowRemoteContent 2
00096 
00097 NS_IMPL_ISUPPORTS3(nsMsgContentPolicy, 
00098                    nsIContentPolicy,
00099                    nsIObserver,
00100                    nsISupportsWeakReference)
00101 
00102 nsMsgContentPolicy::nsMsgContentPolicy()
00103 {
00104   mAllowPlugins = PR_FALSE;
00105   mBlockRemoteImages = PR_TRUE;
00106 }
00107 
00108 nsMsgContentPolicy::~nsMsgContentPolicy()
00109 {
00110   // hey, we are going away...clean up after ourself....unregister our observer
00111   nsresult rv;
00112   nsCOMPtr<nsIPrefBranch2> prefInternal = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
00113   if (NS_SUCCEEDED(rv))
00114   {
00115     prefInternal->RemoveObserver(kBlockRemoteImages, this);
00116     prefInternal->RemoveObserver(kAllowPlugins, this);
00117   }
00118 }
00119 
00120 nsresult nsMsgContentPolicy::Init()
00121 {
00122   nsresult rv;
00123 
00124   // register ourself as an observer on the mail preference to block remote images
00125   nsCOMPtr<nsIPrefBranch2> prefInternal = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
00126   NS_ENSURE_SUCCESS(rv, rv);
00127 
00128   prefInternal->AddObserver(kBlockRemoteImages, this, PR_TRUE);
00129   prefInternal->AddObserver(kAllowPlugins, this, PR_TRUE);
00130 
00131   prefInternal->GetBoolPref(kAllowPlugins, &mAllowPlugins);
00132   prefInternal->GetCharPref(kTrustedDomains, getter_Copies(mTrustedMailDomains));
00133   prefInternal->GetBoolPref(kBlockRemoteImages, &mBlockRemoteImages);
00134   return NS_OK;
00135 }
00136 
00141 nsresult nsMsgContentPolicy::AllowRemoteContentForSender(nsIMsgDBHdr * aMsgHdr, PRBool * aAllowForSender)
00142 {
00143   NS_ENSURE_ARG_POINTER(aMsgHdr); 
00144   
00145   nsresult rv;
00146   *aAllowForSender = PR_FALSE;  
00147 
00148   // extract the e-mail address from the msg hdr
00149   nsXPIDLCString author;
00150   rv = aMsgHdr->GetAuthor(getter_Copies(author));
00151   NS_ENSURE_SUCCESS(rv, rv);
00152 
00153   nsCOMPtr<nsIMsgHeaderParser> headerParser = do_GetService("@mozilla.org/messenger/headerparser;1", &rv);
00154   NS_ENSURE_SUCCESS(rv, rv);
00155 
00156   nsXPIDLCString emailAddress; 
00157   rv = headerParser->ExtractHeaderAddressMailboxes(nsnull, author, getter_Copies(emailAddress));
00158   NS_ENSURE_SUCCESS(rv, rv);
00159 
00160   // Use the RDF service to walk through the list of local directories
00161   nsCOMPtr<nsIRDFService> rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv);
00162   NS_ENSURE_SUCCESS(rv, rv);
00163     
00164   nsCOMPtr <nsIRDFResource> resource;
00165   rv = rdfService->GetResource(NS_LITERAL_CSTRING("moz-abdirectory://"), getter_AddRefs(resource));
00166   NS_ENSURE_SUCCESS(rv, rv);
00167 
00168   nsCOMPtr <nsIAbDirectory> directory = do_QueryInterface(resource, &rv);
00169   NS_ENSURE_SUCCESS(rv, rv);
00170 
00171   nsCOMPtr<nsISimpleEnumerator> enumerator;
00172   rv = directory->GetChildNodes(getter_AddRefs(enumerator));
00173   NS_ENSURE_SUCCESS(rv, rv);
00174 
00175   nsCOMPtr<nsISupports> supports;
00176   nsCOMPtr<nsIAbMDBDirectory> mdbDirectory;
00177   nsCOMPtr<nsIAbCard> cardForAddress;
00178   PRBool hasMore;
00179 
00180   while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore && !cardForAddress)
00181   {
00182     rv = enumerator->GetNext(getter_AddRefs(supports));
00183     NS_ENSURE_SUCCESS(rv, rv);
00184     mdbDirectory = do_QueryInterface(supports);
00185     if (mdbDirectory)
00186       mdbDirectory->CardForEmailAddress(emailAddress, getter_AddRefs(cardForAddress));
00187   }
00188   
00189   // if we found a card from the sender, 
00190   if (cardForAddress)
00191     cardForAddress->GetAllowRemoteContent(aAllowForSender);
00192 
00193   return NS_OK;
00194 }
00195 
00200 PRBool nsMsgContentPolicy::IsTrustedDomain(nsIURI * aContentLocation)
00201 {
00202   PRBool trustedDomain = PR_FALSE;
00203   // get the host name of the server hosting the remote image
00204   nsCAutoString host;
00205   nsresult rv = aContentLocation->GetHost(host);
00206 
00207   if (NS_SUCCEEDED(rv) && !mTrustedMailDomains.IsEmpty()) 
00208     trustedDomain = MsgHostDomainIsTrusted(host, mTrustedMailDomains);
00209 
00210   return trustedDomain;
00211 }
00212 
00213 
00214 NS_IMETHODIMP
00215 nsMsgContentPolicy::ShouldLoad(PRUint32          aContentType,
00216                                nsIURI           *aContentLocation,
00217                                nsIURI           *aRequestingLocation,
00218                                nsISupports      *aRequestingContext,
00219                                const nsACString &aMimeGuess,
00220                                nsISupports      *aExtra,
00221                                PRInt16          *aDecision)
00222 {
00223   nsresult rv = NS_OK;
00224   *aDecision = nsIContentPolicy::ACCEPT;
00225 
00226   NS_ENSURE_ARG_POINTER(aContentLocation);
00227 
00228   // NOTE: Not using NS_ENSURE_ARG_POINTER because this is a legitimate case
00229   // that can happen.
00230   if (!aRequestingLocation)
00231     return NS_ERROR_INVALID_POINTER;
00232 
00233 #ifndef MOZ_THUNDERBIRD
00234   // Go find out if we are dealing with mailnews. Anything else
00235   // isn't our concern and we accept content.
00236   nsCOMPtr<nsIDocShell> docshell;
00237   rv = GetRootDocShellForContext(aRequestingContext, getter_AddRefs(docshell));
00238   NS_ENSURE_SUCCESS(rv, rv);
00239 
00240   PRUint32 appType;
00241   rv = docshell->GetAppType(&appType);
00242   // We only want to deal with mailnews
00243   if (NS_FAILED(rv) || appType != nsIDocShell::APP_TYPE_MAIL)
00244     return NS_OK;
00245 #endif
00246 
00247   if (aContentType == nsIContentPolicy::TYPE_OBJECT)
00248   {
00249     // only allow the plugin to load if the allow plugins pref has been set
00250     if (!mAllowPlugins)
00251       *aDecision = nsIContentPolicy::REJECT_TYPE;
00252     return NS_OK;
00253   }
00254 
00255   // if aRequestingLocation is chrome or resource, allow aContentLocation to load
00256   PRBool isChrome;
00257   PRBool isRes;
00258 
00259   rv = aRequestingLocation->SchemeIs("chrome", &isChrome);
00260   rv |= aRequestingLocation->SchemeIs("resource", &isRes);
00261 
00262   if (NS_SUCCEEDED(rv) && (isChrome || isRes))
00263     return rv;
00264 
00265   // Now default to reject so early returns via NS_ENSURE_SUCCESS 
00266   // cause content to be rejected.
00267   *aDecision = nsIContentPolicy::REJECT_REQUEST;
00268   // From here on out, be very careful about returning error codes.
00269   // An error code will cause the content policy manager to ignore our
00270   // decision. In most cases, if we get an error code, it's something
00271   // we didn't expect which means we should be rejecting the request anyway...
00272 
00273   // if aContentLocation is a protocol we handle (imap, pop3, mailbox, etc)
00274   // or is a chrome url, then allow the load
00275   nsCAutoString contentScheme;
00276   PRBool isExposedProtocol = PR_FALSE;
00277   rv = aContentLocation->GetScheme(contentScheme);
00278   NS_ENSURE_SUCCESS(rv, NS_OK);
00279 
00280 #ifdef MOZ_THUNDERBIRD
00281   nsCOMPtr<nsIExternalProtocolService> extProtService = do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
00282   rv = extProtService->IsExposedProtocol(contentScheme.get(), &isExposedProtocol);
00283   NS_ENSURE_SUCCESS(rv, NS_OK);
00284 #else
00285   if (contentScheme.LowerCaseEqualsLiteral("mailto") ||
00286       contentScheme.LowerCaseEqualsLiteral("news") ||
00287       contentScheme.LowerCaseEqualsLiteral("snews") ||
00288       contentScheme.LowerCaseEqualsLiteral("nntp") ||
00289       contentScheme.LowerCaseEqualsLiteral("imap") ||
00290       contentScheme.LowerCaseEqualsLiteral("addbook") ||
00291       contentScheme.LowerCaseEqualsLiteral("pop") ||
00292       contentScheme.LowerCaseEqualsLiteral("mailbox") ||
00293       contentScheme.LowerCaseEqualsLiteral("about"))
00294     isExposedProtocol = PR_TRUE;
00295 #endif
00296 
00297   rv = aContentLocation->SchemeIs("chrome", &isChrome);
00298   rv |= aContentLocation->SchemeIs("resource", &isRes);
00299 
00300   if (isExposedProtocol || (NS_SUCCEEDED(rv) && (isChrome || isRes)))
00301   {
00302     *aDecision = nsIContentPolicy::ACCEPT;
00303     return NS_OK;
00304   }
00305 
00306   // never load unexposed protocols except for http, https and file. 
00307   // Protocols like ftp, gopher are always blocked.
00308   PRBool isHttp;
00309   PRBool isHttps;
00310   PRBool isFile;
00311   rv = aContentLocation->SchemeIs("http", &isHttp);
00312   rv |= aContentLocation->SchemeIs("https", &isHttps);
00313   rv |= aContentLocation->SchemeIs("file", &isFile);
00314   if (NS_FAILED(rv) || (!isHttp && !isHttps && !isFile))
00315     return NS_OK;
00316 
00317   // If we are allowing all remote content...
00318   if (!mBlockRemoteImages)
00319   {
00320     *aDecision = nsIContentPolicy::ACCEPT;
00321     return NS_OK;
00322   }
00323 
00324   // Extract the windowtype to handle compose windows separately from mail
00325   nsCOMPtr<nsIDocShell> rootDocShell;
00326   rv = GetRootDocShellForContext(aRequestingContext, getter_AddRefs(rootDocShell));
00327   NS_ENSURE_SUCCESS(rv, NS_OK);
00328    
00329   // get the dom document element
00330   nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(rootDocShell, &rv);
00331   NS_ENSURE_SUCCESS(rv, NS_OK);
00332 
00333   nsCOMPtr<nsIDOMElement> windowEl;
00334   rv = domDocument->GetDocumentElement(getter_AddRefs(windowEl));
00335   NS_ENSURE_SUCCESS(rv, NS_OK);
00336 
00337   nsAutoString windowType;
00338   rv = windowEl->GetAttribute(NS_LITERAL_STRING("windowtype"), windowType);
00339   NS_ENSURE_SUCCESS(rv, NS_OK);
00340 
00341   if (windowType.Equals(NS_LITERAL_STRING("msgcompose")))
00342     ComposeShouldLoad(rootDocShell, aRequestingContext, aContentLocation, aDecision);
00343   else
00344   {
00345     // the remote image could be nested in any number of iframes. For those cases, we don't really
00346     // care about the value of aRequestingLocation. We care about the parent message pane nsIURI so
00347     // use that if we can find it. For the non nesting case, mailRequestingLocation and aRequestingLocation
00348     // should end up being the same object.
00349     nsCOMPtr<nsIURI> mailRequestingLocation;
00350     GetMessagePaneURI(rootDocShell, getter_AddRefs(mailRequestingLocation));
00351     
00352     MailShouldLoad(mailRequestingLocation ? mailRequestingLocation.get() : aRequestingLocation, 
00353                    aContentLocation, aDecision);
00354   }
00355 
00356   return NS_OK;
00357 }
00358 
00365 nsresult nsMsgContentPolicy::AllowRemoteContentForMsgHdr(nsIMsgDBHdr * aMsgHdr, nsIURI * aRequestingLocation, nsIURI * aContentLocation, PRInt16 *aDecision)
00366 {
00367   NS_ENSURE_ARG_POINTER(aMsgHdr);
00368 
00369   PRBool allowRemoteContent = PR_FALSE;
00370 
00371   // Case #1, check the db hdr for the remote content policy on this particular message
00372   PRUint32 remoteContentPolicy = kNoRemoteContentPolicy;
00373   aMsgHdr->GetUint32Property("remoteContentPolicy", &remoteContentPolicy);
00374 
00375   // Case #2, check if the message is in an RSS folder
00376   PRBool isRSS = PR_FALSE;
00377   IsRSSArticle(aRequestingLocation, &isRSS);
00378 
00379   // Case #3, author is in our white list..
00380   PRBool allowForSender = PR_FALSE;
00381   AllowRemoteContentForSender(aMsgHdr, &allowForSender);
00382 
00383   // Case #4, the domain for the remote image is in our white list
00384   PRBool trustedDomain = IsTrustedDomain(aContentLocation);
00385 
00386   *aDecision = (isRSS || remoteContentPolicy == kAllowRemoteContent || allowForSender || trustedDomain) 
00387                ? nsIContentPolicy::ACCEPT : nsIContentPolicy::REJECT_REQUEST;
00388 
00389   if (*aDecision == nsIContentPolicy::REJECT_REQUEST && !remoteContentPolicy) // kNoRemoteContentPolicy means we have never set a value on the message
00390     aMsgHdr->SetUint32Property("remoteContentPolicy", kBlockRemoteContent);
00391 
00392   return NS_OK; // always return success
00393 }
00394 
00399 nsresult nsMsgContentPolicy::MailShouldLoad(nsIURI * aRequestingLocation, nsIURI * aContentLocation, PRInt16 * aDecision)
00400 {
00401   NS_ENSURE_TRUE(aRequestingLocation, NS_OK);
00402 
00403   // Allow remote content when using a remote start page in the message pane.
00404   // aRequestingLocation is the url currently loaded in the message pane. 
00405   // If that's an http / https url (as opposed to a mail url) then we 
00406   // must be loading a start page and not a message.
00407   PRBool isHttp;
00408   PRBool isHttps;
00409   nsresult rv = aRequestingLocation->SchemeIs("http", &isHttp);
00410   rv |= aRequestingLocation->SchemeIs("https", &isHttps);
00411   if (NS_SUCCEEDED(rv) && (isHttp || isHttps))
00412   {
00413     *aDecision = nsIContentPolicy::ACCEPT;
00414     return NS_OK;
00415   }
00416 
00417 
00418   // (1) examine the msg hdr value for the remote content policy on this particular message to
00419   //     see if this particular message has special rights to bypass the remote content check
00420   // (2) special case RSS urls, always allow them to load remote images since the user explicitly
00421   //     subscribed to the feed.
00422   // (3) Check the personal address book and use it as a white list for senders
00423   //     who are allowed to send us remote images
00424 
00425   // get the msg hdr for the message URI we are actually loading
00426   nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(aRequestingLocation, &rv);
00427   NS_ENSURE_SUCCESS(rv, rv);
00428 
00429   nsXPIDLCString resourceURI;
00430   msgUrl->GetUri(getter_Copies(resourceURI));
00431 
00432   // get the msg service for this URI
00433   nsCOMPtr<nsIMsgMessageService> msgService;
00434   rv = GetMessageServiceFromURI(resourceURI.get(), getter_AddRefs(msgService));
00435   NS_ENSURE_SUCCESS(rv, rv);
00436 
00437   nsCOMPtr<nsIMsgDBHdr> msgHdr;
00438   rv = msgService->MessageURIToMsgHdr(resourceURI, getter_AddRefs(msgHdr));
00439   NS_ENSURE_SUCCESS(rv, rv);
00440 
00441   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(aRequestingLocation, &rv);
00442   NS_ENSURE_SUCCESS(rv, rv);
00443 
00444   AllowRemoteContentForMsgHdr(msgHdr, aRequestingLocation, aContentLocation, aDecision);
00445 
00446   if (*aDecision == nsIContentPolicy::REJECT_REQUEST)
00447   {
00448     // now we need to call out the msg sink informing it that this message has remote content
00449     nsCOMPtr<nsIMsgWindow> msgWindow;
00450     rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow)); 
00451     if (msgWindow)
00452     {
00453       nsCOMPtr<nsIMsgHeaderSink> msgHdrSink;
00454       rv = msgWindow->GetMsgHeaderSink(getter_AddRefs(msgHdrSink));
00455       if (msgHdrSink)
00456         msgHdrSink->OnMsgHasRemoteContent(msgHdr); // notify the UI to show the remote content hdr bar so the user can overide
00457     }
00458   }
00459 
00460   return NS_OK;
00461 }
00462 
00467 nsresult nsMsgContentPolicy::ComposeShouldLoad(nsIDocShell * aRootDocShell, nsISupports * aRequestingContext,
00468                                                nsIURI * aContentLocation, PRInt16 * aDecision)
00469 {
00470   nsresult rv;
00471 
00472   PRBool authorInWhiteList = PR_FALSE;
00473   PRBool trustedDomain = PR_FALSE;
00474 
00475   nsCOMPtr<nsIDOMWindowInternal> window(do_GetInterface(aRootDocShell, &rv));
00476   NS_ENSURE_SUCCESS(rv, NS_OK);
00477 
00478   nsCOMPtr<nsIMsgComposeService> composeService (do_GetService(NS_MSGCOMPOSESERVICE_CONTRACTID, &rv));
00479   NS_ENSURE_SUCCESS(rv, NS_OK);
00480 
00481   nsCOMPtr<nsIMsgCompose> msgCompose;
00482   rv = composeService->GetMsgComposeForWindow(window, getter_AddRefs(msgCompose));
00483   NS_ENSURE_SUCCESS(rv, NS_OK);
00484 
00485   nsXPIDLCString originalMsgURI;
00486   msgCompose->GetOriginalMsgURI(getter_Copies(originalMsgURI));
00487   NS_ENSURE_SUCCESS(rv, NS_OK);
00488 
00489   MSG_ComposeType composeType;
00490   rv = msgCompose->GetType(&composeType);
00491   NS_ENSURE_SUCCESS(rv, NS_OK);
00492 
00493   // Only allow remote content for new mail compositions.
00494   // Block remote content for all other types (drafts, templates, forwards, replies, etc)
00495   // unless there is an associated msgHdr which allows the load, or unless the image is being
00496   // added by the user and not the quoted message content...
00497   if (composeType == nsIMsgCompType::New)
00498     *aDecision = nsIContentPolicy::ACCEPT;
00499   else if (!originalMsgURI.IsEmpty())
00500   {
00501     nsCOMPtr<nsIMsgDBHdr> msgHdr;
00502     rv = GetMsgDBHdrFromURI(originalMsgURI.get(), getter_AddRefs(msgHdr));
00503     NS_ENSURE_SUCCESS(rv, NS_OK);
00504     AllowRemoteContentForMsgHdr(msgHdr, nsnull, aContentLocation, aDecision);
00505 
00506     // Special case image elements. When replying to a message, we want to allow the 
00507     // user to add remote images to the message. But we don't want remote images
00508     // that are a part of the quoted content to load. Fortunately, after the quoted message
00509     // has been inserted into the document, mail compose flags remote content elements that came 
00510     // from the original message with a moz-do-not-send attribute. 
00511     if (*aDecision == nsIContentPolicy::REJECT_REQUEST)
00512     {
00513       PRBool insertingQuotedContent = PR_TRUE;
00514       msgCompose->GetInsertingQuotedContent(&insertingQuotedContent);
00515       nsCOMPtr<nsIDOMHTMLImageElement> imageElement = do_QueryInterface(aRequestingContext);
00516       if (!insertingQuotedContent && imageElement)
00517       {
00518         PRBool doNotSendAttrib;
00519         if (NS_SUCCEEDED(imageElement->HasAttribute(NS_LITERAL_STRING("moz-do-not-send"), &doNotSendAttrib)) && 
00520             !doNotSendAttrib)
00521            *aDecision = nsIContentPolicy::ACCEPT;
00522       }
00523     }
00524   }
00525 
00526   return NS_OK;
00527 }
00528 
00532 nsresult nsMsgContentPolicy::GetRootDocShellForContext(nsISupports * aRequestingContext, nsIDocShell ** aDocShell)
00533 {
00534   NS_ENSURE_ARG_POINTER(aRequestingContext);
00535   nsresult rv;
00536 
00537   nsIDocShell *shell = NS_CP_GetDocShellFromContext(aRequestingContext);
00538   nsCOMPtr<nsIDocShellTreeItem> docshellTreeItem(do_QueryInterface(shell, &rv));
00539   NS_ENSURE_SUCCESS(rv, rv);
00540 
00541   nsCOMPtr<nsIDocShellTreeItem> rootItem;
00542   // we want the app docshell, so don't use GetSameTypeRootTreeItem
00543   rv = docshellTreeItem->GetRootTreeItem(getter_AddRefs(rootItem));
00544   NS_ENSURE_SUCCESS(rv, rv);
00545 
00546   return rootItem->QueryInterface(NS_GET_IID(nsIDocShell), (void**) aDocShell);
00547 }
00548 
00556 nsresult nsMsgContentPolicy::GetMessagePaneURI(nsIDocShell * aRootDocShell, nsIURI ** aURI)
00557 {
00558   nsresult rv;
00559   nsCOMPtr<nsIDocShellTreeNode> rootDocShellAsNode(do_QueryInterface(aRootDocShell, &rv));
00560   NS_ENSURE_SUCCESS(rv, rv);
00561 
00562   nsCOMPtr<nsIDocShellTreeItem> childAsItem;
00563   rv = rootDocShellAsNode->FindChildWithName(NS_LITERAL_STRING("messagepane").get(),
00564                                                PR_TRUE, PR_FALSE, nsnull, nsnull, getter_AddRefs(childAsItem));
00565   NS_ENSURE_SUCCESS(rv, rv);
00566   
00567   nsCOMPtr<nsIWebNavigation> webNavigation (do_QueryInterface(childAsItem, &rv));
00568   NS_ENSURE_SUCCESS(rv, rv);
00569   
00570   return webNavigation->GetCurrentURI(aURI);
00571 }
00572 
00573 NS_IMETHODIMP
00574 nsMsgContentPolicy::ShouldProcess(PRUint32          aContentType,
00575                                   nsIURI           *aContentLocation,
00576                                   nsIURI           *aRequestingLocation,
00577                                   nsISupports      *aRequestingContext,
00578                                   const nsACString &aMimeGuess,
00579                                   nsISupports      *aExtra,
00580                                   PRInt16          *aDecision)
00581 {
00582   *aDecision = nsIContentPolicy::ACCEPT;
00583   return NS_OK;
00584 }
00585 
00586 NS_IMETHODIMP nsMsgContentPolicy::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
00587 {
00588   if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) 
00589   {
00590     NS_LossyConvertUCS2toASCII pref(aData);
00591 
00592     nsresult rv;
00593 
00594     nsCOMPtr<nsIPrefBranch2> prefBranchInt = do_QueryInterface(aSubject, &rv);
00595     NS_ENSURE_SUCCESS(rv, rv);
00596 
00597     if (pref.Equals(kBlockRemoteImages))
00598       prefBranchInt->GetBoolPref(kBlockRemoteImages, &mBlockRemoteImages);
00599   }
00600 
00601   return NS_OK;
00602 }
00603 
00604 NS_IMPL_ISUPPORTS1(nsMsgCookiePolicy, nsICookiePermission)
00605 
00606 
00607 NS_IMETHODIMP nsMsgCookiePolicy::SetAccess(nsIURI         *aURI,
00608                                            nsCookieAccess  aAccess)
00609 {
00610   // we don't support cookie access lists for mail
00611   return NS_OK;
00612 }
00613 
00614 NS_IMETHODIMP nsMsgCookiePolicy::CanAccess(nsIURI         *aURI,
00615                                             nsIURI         *aFirstURI,
00616                                             nsIChannel     *aChannel,
00617                                             nsCookieAccess *aResult)
00618 {
00619   // by default we deny all cookies in mail
00620   *aResult = ACCESS_DENY;
00621   NS_ENSURE_ARG_POINTER(aChannel);
00622 
00623   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem;
00624   NS_QueryNotificationCallbacks(aChannel, docShellTreeItem);
00625 
00626   NS_ENSURE_TRUE(docShellTreeItem, NS_OK);
00627   PRInt32 itemType;
00628   docShellTreeItem->GetItemType(&itemType);
00629 
00630   // allow chome docshells to set cookies
00631   if (itemType == nsIDocShellTreeItem::typeChrome)
00632     *aResult = ACCESS_DEFAULT;
00633   else // allow RSS articles in content to access cookies
00634   {
00635     NS_ENSURE_TRUE(aFirstURI, NS_OK);  
00636     PRBool isRSS = PR_FALSE;
00637     IsRSSArticle(aFirstURI, &isRSS);
00638     if (isRSS)
00639       *aResult = ACCESS_DEFAULT;
00640   }
00641 
00642   return NS_OK;
00643 }
00644 
00645 NS_IMETHODIMP nsMsgCookiePolicy::CanSetCookie(nsIURI     *aURI,
00646                                               nsIChannel *aChannel,
00647                                               nsICookie2 *aCookie,
00648                                               PRBool     *aIsSession,
00649                                               PRInt64    *aExpiry,
00650                                               PRBool     *aResult)
00651 {
00652   *aResult = PR_TRUE;
00653   return NS_OK;
00654 }