From 8d277c87e5cf246834804ac9c194e8918c5a1211 Mon Sep 17 00:00:00 2001 From: "morse%netscape.com" Date: Thu, 29 Mar 2001 02:11:48 +0000 Subject: [PATCH] bug 46783, reorg cookies module for embedding, r=valeski, sr=alecf git-svn-id: svn://10.0.0.236/trunk@90729 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/document/src/nsHTMLContentSink.cpp | 16 +- .../html/document/src/nsHTMLDocument.cpp | 24 +- mozilla/dom/src/base/nsGlobalWindow.cpp | 17 +- mozilla/extensions/cookie/Makefile.in | 22 +- mozilla/extensions/cookie/makefile.win | 37 +- mozilla/extensions/cookie/nsCookie.cpp | 2928 +---------------- mozilla/extensions/cookie/nsCookie.h | 72 +- .../extensions/cookie/nsCookieHTTPNotify.cpp | 20 +- mozilla/extensions/cookie/nsCookieManager.cpp | 121 + mozilla/extensions/cookie/nsCookieManager.h | 45 + mozilla/extensions/cookie/nsCookieService.cpp | 207 +- mozilla/extensions/cookie/nsCookieService.h | 20 +- mozilla/extensions/cookie/nsCookies.cpp | 1492 +++++++++ mozilla/extensions/cookie/nsCookies.h | 60 + mozilla/extensions/cookie/nsICookie.idl | 60 + .../extensions/cookie/nsICookieManager.idl | 45 + ...sICookieService.h => nsICookieService.idl} | 73 +- mozilla/extensions/cookie/nsIImgManager.idl | 43 + mozilla/extensions/cookie/nsIPermission.idl | 47 + .../cookie/nsIPermissionManager.idl | 46 + mozilla/extensions/cookie/nsImages.cpp | 186 ++ mozilla/extensions/cookie/nsImages.h | 33 + mozilla/extensions/cookie/nsImgManager.cpp | 58 + mozilla/extensions/cookie/nsImgManager.h | 43 + mozilla/extensions/cookie/nsModuleFactory.cpp | 84 + mozilla/extensions/cookie/nsPermission.cpp | 65 + mozilla/extensions/cookie/nsPermission.h | 51 + .../extensions/cookie/nsPermissionManager.cpp | 166 + .../extensions/cookie/nsPermissionManager.h | 48 + mozilla/extensions/cookie/nsPermissions.cpp | 697 ++++ mozilla/extensions/cookie/nsPermissions.h | 59 + mozilla/extensions/cookie/nsUtils.cpp | 331 ++ mozilla/extensions/cookie/nsUtils.h | 45 + .../content/cookieContextOverlay.xul | 38 +- .../resources/content/cookieTasksOverlay.xul | 41 +- .../extensions/cookie/tests/TestCookie.cpp | 11 +- mozilla/extensions/wallet/Makefile.in | 2 +- mozilla/extensions/wallet/build/Makefile.in | 2 - mozilla/extensions/wallet/build/makefile.win | 3 +- .../wallet/build/nsWalletViewerFactory.cpp | 4 - .../wallet/cookieviewer/CookieViewer.js | 411 +-- .../cookieviewer/CookieViewer.properties | 5 + .../wallet/cookieviewer/CookieViewer.xul | 50 +- mozilla/extensions/wallet/makefile.win | 2 +- mozilla/modules/libimg/src/if.cpp | 12 +- .../plugin/base/src/nsPluginHostImpl.cpp | 22 +- .../plugin/nglsrc/nsPluginHostImpl.cpp | 22 +- .../content/cookieTasksOverlay.xul | 41 +- .../content/imageContextOverlay.xul | 38 +- 49 files changed, 4491 insertions(+), 3474 deletions(-) create mode 100644 mozilla/extensions/cookie/nsCookieManager.cpp create mode 100644 mozilla/extensions/cookie/nsCookieManager.h create mode 100644 mozilla/extensions/cookie/nsCookies.cpp create mode 100644 mozilla/extensions/cookie/nsCookies.h create mode 100644 mozilla/extensions/cookie/nsICookie.idl create mode 100644 mozilla/extensions/cookie/nsICookieManager.idl rename mozilla/extensions/cookie/{nsICookieService.h => nsICookieService.idl} (53%) create mode 100644 mozilla/extensions/cookie/nsIImgManager.idl create mode 100644 mozilla/extensions/cookie/nsIPermission.idl create mode 100644 mozilla/extensions/cookie/nsIPermissionManager.idl create mode 100644 mozilla/extensions/cookie/nsImages.cpp create mode 100644 mozilla/extensions/cookie/nsImages.h create mode 100644 mozilla/extensions/cookie/nsImgManager.cpp create mode 100644 mozilla/extensions/cookie/nsImgManager.h create mode 100644 mozilla/extensions/cookie/nsModuleFactory.cpp create mode 100644 mozilla/extensions/cookie/nsPermission.cpp create mode 100644 mozilla/extensions/cookie/nsPermission.h create mode 100644 mozilla/extensions/cookie/nsPermissionManager.cpp create mode 100644 mozilla/extensions/cookie/nsPermissionManager.h create mode 100644 mozilla/extensions/cookie/nsPermissions.cpp create mode 100644 mozilla/extensions/cookie/nsPermissions.h create mode 100644 mozilla/extensions/cookie/nsUtils.cpp create mode 100644 mozilla/extensions/cookie/nsUtils.h diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index d404d18c257..8a28ccc3276 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -115,6 +115,8 @@ #include "nsReadableUtils.h" #include "nsWeakReference.h"//nshtmlelementfactory supports weak references +#include "nsIPrompt.h" +#include "nsIDOMWindowInternal.h" #ifdef ALLOW_ASYNCH_STYLE_SHEETS const PRBool kBlockByDefault=PR_FALSE; @@ -4500,8 +4502,18 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,nsString& aValue,nsIHTMLCont nsCOMPtr webNav = do_QueryInterface(docShell); rv = webNav->GetCurrentURI(getter_AddRefs(baseURI)); if (NS_FAILED(rv)) return rv; - - rv = cookieServ->SetCookieString(baseURI, mDocument, aValue); + char *cookie = aValue.ToNewCString(); + nsCOMPtr globalObj; + nsCOMPtr prompt; + mDocument->GetScriptGlobalObject(getter_AddRefs(globalObj)); + if (globalObj) { + nsCOMPtr window (do_QueryInterface(globalObj)); + if (window) { + window->GetPrompter(getter_AddRefs(prompt)); + } + } + rv = cookieServ->SetCookieString(baseURI, prompt, cookie); + nsCRT::free(cookie); if (NS_FAILED(rv)) return rv; } // END set-cookie diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index d941f92baf8..81842d16645 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -112,6 +112,7 @@ #include "nsHTMLParts.h" //for createelementNS #include "nsLayoutCID.h" #include "nsContentCID.h" +#include "nsIPrompt.h" #define DETECTOR_CONTRACTID_MAX 127 static char g_detector_contractid[DETECTOR_CONTRACTID_MAX + 1]; @@ -2043,8 +2044,16 @@ nsHTMLDocument::GetCookie(nsAWritableString& aCookie) nsresult result = NS_OK; nsAutoString str; NS_WITH_SERVICE(nsICookieService, service, kCookieServiceCID, &result); + char * cookie; if ((NS_OK == result) && (nsnull != service) && (nsnull != mDocumentURL)) { - result = service->GetCookieString(mDocumentURL, str); + result = service->GetCookieString(mDocumentURL, &cookie); + } + if (nsnull != cookie) { + str.AssignWithConversion(cookie); + nsCRT::free(cookie); + } else { + // No Cookie isn't an error condition. + aCookie.Truncate(); } aCookie.Assign(str); return result; @@ -2056,7 +2065,18 @@ nsHTMLDocument::SetCookie(const nsAReadableString& aCookie) nsresult result = NS_OK; NS_WITH_SERVICE(nsICookieService, service, kCookieServiceCID, &result); if ((NS_OK == result) && (nsnull != service) && (nsnull != mDocumentURL)) { - result = service->SetCookieString(mDocumentURL, this, nsAutoString(aCookie)); + char *cookie = nsString(aCookie).ToNewCString(); + nsCOMPtr globalObj; + nsCOMPtr prompt; + this->GetScriptGlobalObject(getter_AddRefs(globalObj)); + if (globalObj) { + nsCOMPtr window (do_QueryInterface(globalObj)); + if (window) { + window->GetPrompter(getter_AddRefs(prompt)); + } + } + result = service->SetCookieString(mDocumentURL, prompt, cookie); + nsCRT::free(cookie); } return result; } diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index 03e52ab5f48..eeaba5f2736 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -55,7 +55,6 @@ #include "nsIContent.h" #include "nsIContentViewerFile.h" #include "nsIContentViewerEdit.h" -#include "nsICookieService.h" #include "nsIDocShell.h" #include "nsIDocShellLoadInfo.h" #include "nsIDocShellTreeItem.h" @@ -112,7 +111,6 @@ static PRInt32 gRefCnt = 0; // CIDs static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); -static NS_DEFINE_IID(kCookieServiceCID, NS_COOKIESERVICE_CID); static NS_DEFINE_CID(kHTTPHandlerCID, NS_IHTTPHANDLER_CID); static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, @@ -4239,13 +4237,20 @@ NS_IMETHODIMP NavigatorImpl::GetCookieEnabled(PRBool *aCookieEnabled) nsresult rv = NS_OK; *aCookieEnabled = PR_FALSE; - NS_WITH_SERVICE(nsICookieService, service, kCookieServiceCID, &rv); - if (NS_FAILED(rv) || service == nsnull) + NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); + if (NS_FAILED(rv) || prefs == nsnull) return rv; - return service->CookieEnabled(aCookieEnabled); -} + PRInt32 cookieBehaviorPref; + rv = prefs->GetIntPref("network.cookie.cookieBehavior", &cookieBehaviorPref); + if (NS_FAILED(rv)) + return rv; + + const PRInt32 DONT_USE = 2; + *aCookieEnabled = (cookieBehaviorPref != DONT_USE); + return rv; +} NS_IMETHODIMP NavigatorImpl::JavaEnabled(PRBool *aReturn) { diff --git a/mozilla/extensions/cookie/Makefile.in b/mozilla/extensions/cookie/Makefile.in index dc770fa8565..3616db5337b 100644 --- a/mozilla/extensions/cookie/Makefile.in +++ b/mozilla/extensions/cookie/Makefile.in @@ -36,15 +36,31 @@ DIRS = tests endif CPPSRCS = \ - nsCookieService.cpp \ + nsModuleFactory.cpp \ nsCookie.cpp \ + nsPermission.cpp \ + nsCookieManager.cpp \ + nsCookieService.cpp \ + nsImgManager.cpp \ + nsPermissionManager.cpp \ + nsCookies.cpp \ + nsImages.cpp \ + nsPermissions.cpp \ + nsUtils.cpp \ nsCookieHTTPNotify.cpp \ $(NULL) +XPIDLSRCS = \ + nsICookieManager.idl \ + nsIImgManager.idl \ + nsIPermissionManager.idl \ + nsICookieService.idl \ + nsICookie.idl \ + nsIPermission.idl \ + $(NULL) + EXPORTS = \ - nsICookieService.h \ nsCookieHTTPNotify.h \ - nsCookie.h \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/extensions/cookie/makefile.win b/mozilla/extensions/cookie/makefile.win index 0019dc050a1..3a07cba67e2 100644 --- a/mozilla/extensions/cookie/makefile.win +++ b/mozilla/extensions/cookie/makefile.win @@ -25,24 +25,43 @@ include <$(DEPTH)/config/config.mak> DEFINES=-D_IMPL_NS_COOKIE -DWIN32_LEAN_AND_MEAN MODULE=cookie -EXPORTS = nsICookieService.h nsCookieHTTPNotify.h nsCookie.h - -CSRCS= \ - $(NULL) +EXPORTS = nsCookieHTTPNotify.h CPPSRCS= \ - nsCookieService.cpp \ + nsModuleFactory.cpp \ nsCookie.cpp \ + nsPermission.cpp \ + nsCookieManager.cpp \ + nsCookieService.cpp \ + nsImgManager.cpp \ + nsPermissionManager.cpp \ + nsCookies.cpp \ + nsImages.cpp \ + nsPermissions.cpp \ + nsUtils.cpp \ nsCookieHTTPNotify.cpp \ $(NULL) -C_OBJS= \ - $(NULL) - +XPIDLSRCS= .\nsICookieManager.idl \ + .\nsIImgManager.idl \ + .\nsIPermissionManager.idl \ + .\nsICookieService.idl \ + .\nsICookie.idl \ + .\nsIPermission.idl \ + $(NULL) CPP_OBJS= \ + .\$(OBJDIR)\nsModuleFactory.obj \ + .\$(OBJDIR)\nsCookie.obj \ + .\$(OBJDIR)\nsPermission.obj \ + .\$(OBJDIR)\nsCookieManager.obj \ .\$(OBJDIR)\nsCookieService.obj \ - .\$(OBJDIR)\nsCookie.obj \ + .\$(OBJDIR)\nsImgManager.obj \ + .\$(OBJDIR)\nsPermissionManager.obj \ + .\$(OBJDIR)\nsCookies.obj \ + .\$(OBJDIR)\nsImages.obj \ + .\$(OBJDIR)\nsPermissions.obj \ + .\$(OBJDIR)\nsUtils.obj \ .\$(OBJDIR)\nsCookieHTTPNotify.obj \ $(NULL) diff --git a/mozilla/extensions/cookie/nsCookie.cpp b/mozilla/extensions/cookie/nsCookie.cpp index a05c61ff4cc..769793cd9db 100644 --- a/mozilla/extensions/cookie/nsCookie.cpp +++ b/mozilla/extensions/cookie/nsCookie.cpp @@ -1,5 +1,5 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -18,2902 +18,88 @@ * Rights Reserved. * * Contributor(s): - * Pierre Phaneuf - * Henrik Gemal */ -#define alphabetize 1 - #include "nsCookie.h" #include "nsString.h" -#include "nsIServiceManager.h" -#include "nsFileStream.h" -#include "nsIDirectoryService.h" -#include "nsAppDirectoryServiceDefs.h" -#include "nsIFile.h" -#include "nsXPIDLString.h" -#include "nsIFileSpec.h" -#include "nsINetSupportDialogService.h" -#include "nsIURL.h" -#include "nsIStringBundle.h" -#include "nsVoidArray.h" -#include "prprf.h" -#include "xp_core.h" // for time_t -#include "nsXPIDLString.h" - -#include "nsIPref.h" -#include "nsTextFormatter.h" - -static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID); -static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); - -#define MAX_NUMBER_OF_COOKIES 300 -#define MAX_COOKIES_PER_SERVER 20 -#define MAX_BYTES_PER_COOKIE 4096 /* must be at least 1 */ -#ifndef MAX_HOST_NAME_LEN -#define MAX_HOST_NAME_LEN 64 -#endif - -static const char *kCookiesFileName = "cookies.txt"; -static const char *kCookiesPermFileName = "cookperm.txt"; - -#define image_behaviorPref "network.image.imageBehavior" -#define image_warningPref "network.image.warnAboutImages" -#define cookie_behaviorPref "network.cookie.cookieBehavior" -#define cookie_warningPref "network.cookie.warnAboutCookies" -#define cookie_strictDomainsPref "network.cookie.strictDomains" -#define cookie_lifetimePref "network.cookie.lifetimeOption" -#define cookie_lifetimeValue "network.cookie.lifetimeLimit" -#define cookie_localization "chrome://communicator/locale/wallet/cookie.properties" -#define COOKIE_IS_SPACE(x) ((((unsigned int) (x)) > 0x7f) ? 0 : isspace(x)) - -//#define GET_ALL_PARTS 127 -#define GET_PASSWORD_PART 64 -#define GET_USERNAME_PART 32 -#define GET_PROTOCOL_PART 16 -#define GET_HOST_PART 8 -#define GET_PATH_PART 4 -#define GET_HASH_PART 2 -#define GET_SEARCH_PART 1 - -MODULE_PRIVATE time_t -cookie_ParseDate(char *date_string); - -MODULE_PRIVATE char * -cookie_ParseURL (const char *url, int parts_requested); - -typedef struct _cookie_CookieStruct { - char * path; - char * host; - char * name; - char * cookie; - time_t expires; - time_t lastAccessed; - PRBool secure; - PRBool isDomain; /* is it a domain instead of an absolute host? */ -} cookie_CookieStruct; - -#define COOKIEPERMISSION 0 -#define IMAGEPERMISSION 1 -#define NUMBER_OF_PERMISSIONS 2 -typedef struct _permission_HostStruct { - char * host; - nsVoidArray * permissionList; -} permission_HostStruct; - -typedef struct _permission_TypeStruct { - PRInt32 type; - PRBool permission; -} permission_TypeStruct; - -typedef enum { - COOKIE_Normal, - COOKIE_Discard, - COOKIE_Trim, - COOKIE_Ask -} COOKIE_LifetimeEnum; - -PRIVATE PRBool cookie_cookiesChanged = PR_FALSE; -PRIVATE PRBool cookie_permissionsChanged = PR_FALSE; -PRIVATE PRBool cookie_rememberChecked; -PRIVATE PRBool image_rememberChecked; -PRIVATE COOKIE_BehaviorEnum cookie_behavior = COOKIE_Accept; -PRIVATE PRBool cookie_warning = PR_FALSE; -PRIVATE COOKIE_BehaviorEnum image_behavior = COOKIE_Accept; -PRIVATE PRBool image_warning = PR_FALSE; -PRIVATE COOKIE_LifetimeEnum cookie_lifetimeOpt = COOKIE_Normal; -PRIVATE time_t cookie_lifetimeLimit = 90*24*60*60; - -PRIVATE nsVoidArray * cookie_cookieList=0; -PRIVATE nsVoidArray * cookie_permissionList=0; - -#define REAL_DIALOG 1 - -static -time_t -get_current_time() - /* - We call this routine instead of |time()| because the latter returns - different values on the Mac than on all other platforms (i.e., based on - the Mac's 1900 epoch, vs all others 1970). We can't call |PR_Now| - directly, since the value is 64bits and too hard to manipulate. - Hence, this cross-platform convenience routine. - */ - { - PRInt64 usecPerSec; - LL_I2L(usecPerSec, 1000000L); - - PRTime now_useconds = PR_Now(); - - PRInt64 now_seconds; - LL_DIV(now_seconds, now_useconds, usecPerSec); - - time_t current_time_in_seconds; - LL_L2I(current_time_in_seconds, now_seconds); - - return current_time_in_seconds; - } - -/* StrAllocCopy and StrAllocCat should really be defined elsewhere */ -#include "plstr.h" #include "prmem.h" -#undef StrAllocCopy -#define StrAllocCopy(dest, src) Local_SACopy (&(dest), src) -char * -Local_SACopy(char **destination, const char *source) -{ - if(*destination) { - PL_strfree(*destination); - *destination = 0; - } - *destination = PL_strdup(source); - return *destination; + +// nsCookie Implementation + +NS_IMPL_ISUPPORTS2(nsCookie, nsICookie, nsISupportsWeakReference); + +nsCookie::nsCookie() { + NS_INIT_REFCNT(); } -#undef StrAllocCat -#define StrAllocCat(dest, src) Local_SACat (&(dest), src) -char * -Local_SACat(char **destination, const char *source) -{ - if (source && *source) { - if (*destination) { - int length = PL_strlen (*destination); - *destination = (char *) PR_Realloc(*destination, length + PL_strlen(source) + 1); - if (*destination == NULL) { - return(NULL); - } - PL_strcpy (*destination + length, source); - } else { - *destination = PL_strdup(source); - } - } - return *destination; +nsCookie::nsCookie + (char * name, + char * value, + PRBool isDomain, + char * host, + char * path, + PRBool isSecure, + PRUint64 expires) { + cookieName = name; + cookieValue = value; + cookieIsDomain = isDomain; + cookieHost = host; + cookiePath = path; + cookieIsSecure = isSecure; + cookieExpires = expires; + NS_INIT_REFCNT(); } -PRIVATE PRUnichar* -cookie_Localize(char* genericString) { - nsresult ret; - nsAutoString v; - - /* create a bundle for the localization */ - NS_WITH_SERVICE(nsIStringBundleService, pStringService, kStringBundleServiceCID, &ret); - if (NS_FAILED(ret)) { -#ifdef DEBUG - printf("cannot get string service\n"); -#endif - return v.ToNewUnicode(); - } - nsCOMPtr locale; - nsCOMPtr bundle; - ret = pStringService->CreateBundle(cookie_localization, locale, getter_AddRefs(bundle)); - if (NS_FAILED(ret)) { -#ifdef DEBUG - printf("cannot create instance\n"); -#endif - return v.ToNewUnicode(); - } - - /* localize the given string */ - nsString strtmp; strtmp.AssignWithConversion(genericString); - const PRUnichar *ptrtmp = strtmp.GetUnicode(); - nsXPIDLString ptrv; - ret = bundle->GetStringFromName(ptrtmp, getter_Copies(ptrv)); - v = ptrv; - if (NS_FAILED(ret)) { -#ifdef DEBUG - printf("cannot get string from name\n"); -#endif - return v.ToNewUnicode(); - } - return v.ToNewUnicode(); +nsCookie::~nsCookie(void) { + nsCRT::free(cookieName); + nsCRT::free(cookieValue); + nsCRT::free(cookieHost); + nsCRT::free(cookiePath); } -PRBool -cookie_CheckConfirmYN(nsIPrompt *aPrompter, PRUnichar * szMessage, PRUnichar * szCheckMessage, PRBool* checkValue) { - - nsresult res; - nsCOMPtr dialog; - - if (aPrompter) - dialog = aPrompter; - else - dialog = do_GetService(kNetSupportDialogCID); - if (!dialog) { - *checkValue = 0; - return PR_FALSE; - } - - PRInt32 buttonPressed = 1; /* in case user exits dialog by clickin X */ - PRUnichar * yes_string = cookie_Localize("Yes"); - PRUnichar * no_string = cookie_Localize("No"); - PRUnichar * confirm_string = cookie_Localize("Confirm"); - - nsString tempStr; tempStr.AssignWithConversion("chrome://global/skin/question-icon.gif"); - res = dialog->UniversalDialog( - NULL, /* title message */ - confirm_string, /* title text in top line of window */ - szMessage, /* this is the main message */ - szCheckMessage, /* This is the checkbox message */ - yes_string, /* first button text */ - no_string, /* second button text */ - NULL, /* third button text */ - NULL, /* fourth button text */ - NULL, /* first edit field label */ - NULL, /* second edit field label */ - NULL, /* first edit field initial and final value */ - NULL, /* second edit field initial and final value */ - tempStr.GetUnicode() , - checkValue, /* initial and final value of checkbox */ - 2, /* number of buttons */ - 0, /* number of edit fields */ - 0, /* is first edit field a password field */ - &buttonPressed); - - if (NS_FAILED(res)) { - *checkValue = 0; - } - if (*checkValue!=0 && *checkValue!=1) { - *checkValue = 0; /* this should never happen but it is happening!!! */ - } - Recycle(yes_string); - Recycle(no_string); - Recycle(confirm_string); - return (buttonPressed == 0); - -#ifdef yyy - /* following is an example of the most general usage of UniversalDialog */ - PRUnichar* inoutEdit1 = nsString("Edit field1 initial value").GetUnicode(); - PRUnichar* inoutEdit2 = nsString("Edit field2 initial value").GetUnicode(); - PRBool inoutCheckbox = PR_TRUE; - PRInt32 buttonPressed; - - res = dialog->UniversalDialog( - nsString("Title Message").GetUnicode(), - nsString("Dialog Title").GetUnicode(), - nsString("This is the main message").GetUnicode(), - nsString("This is the checkbox message").GetUnicode(), - nsString("First Button").GetUnicode(), - nsString("Second Button").GetUnicode(), - nsString("Third Button").GetUnicode(), - nsString("Fourth Button").GetUnicode(), - nsString("First Edit field").GetUnicode(), - nsString("Second Edit field").GetUnicode(), - &inoutEdit1, - &inoutEdit2, - nsString("chrome://global/skin/question-icon.gif").GetUnicode() , - &inoutCheckbox, - 4, /* number of buttons */ - 2, /* number of edit fields */ - 0, /* is first edit field a password field */ - &buttonPressed); -#endif - -} - -PRIVATE nsresult cookie_ProfileDirectory(nsFileSpec& dirSpec) { - - nsresult res; - nsCOMPtr aFile; - nsCOMPtr tempSpec; - - res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(aFile)); - if (NS_FAILED(res)) return res; - - // TODO: When the calling code can take an nsIFile, - // this conversion to nsFileSpec can be avoided. - nsXPIDLCString pathBuf; - aFile->GetPath(getter_Copies(pathBuf)); - res = NS_NewFileSpec(getter_AddRefs(tempSpec)); - if (NS_FAILED(res)) return res; - res = tempSpec->SetNativePath(pathBuf); - if (NS_FAILED(res)) return res; - res = tempSpec->GetFileSpec(&dirSpec); - - return res; -} - -nsresult cookie_Get(nsInputFileStream& strm, char& c) { -#define BUFSIZE 128 - static char buffer[BUFSIZE]; - static PRInt32 next = BUFSIZE, count = BUFSIZE; - - if (next == count) { - if (BUFSIZE > count) { // never say "count < ..." vc6.0 thinks this is a template beginning and crashes - next = BUFSIZE; - count = BUFSIZE; - return NS_ERROR_FAILURE; - } - count = strm.read(buffer, BUFSIZE); - next = 0; - if (count == 0) { - next = BUFSIZE; - count = BUFSIZE; - return NS_ERROR_FAILURE; - } - } - c = buffer[next++]; - return NS_OK; -} - -/* - * get a line from a file - * return -1 if end of file reached - * strip carriage returns and line feeds from end of line - */ -PRInt32 -cookie_GetLine(nsInputFileStream& strm, nsString& aLine) { - - /* read the line */ - aLine.Truncate(); - char c; - for (;;) { - if NS_FAILED(cookie_Get(strm, c)) { - return -1; - } - if (c == '\n') { - break; - } - - if (c != '\r') { - aLine.AppendWithConversion(c); - } - } - return 0; -} - - -PRIVATE void -permission_Save(); -PRIVATE void -cookie_Save(); - -PRIVATE void -permission_Free(PRInt32 hostNumber, PRInt32 type, PRBool save) { - /* get the indicated host in the list */ - if (cookie_permissionList == nsnull) { - return; - } - - permission_HostStruct * hostStruct; - permission_TypeStruct * typeStruct; - PRInt32 actualHostNumber = -1; - PRInt32 typeIndex; - - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 j=0, k=0; jElementAt(j)); - if (!hostStruct) { - return; - } - PRBool present = PR_FALSE; - PRInt32 count2 = hostStruct->permissionList->Count(); - for (typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - if (typeStruct->type == type) { - present = PR_TRUE; - break; - } - } - if (present) { - if (k == hostNumber) { - actualHostNumber = j; - break; - } - k++; - } - } - - if (actualHostNumber == -1) { - /* host not found, something is wrong */ - return; - } - - /* remove the particular type */ - hostStruct->permissionList->RemoveElementAt(typeIndex); - - /* if no types are present, remove the entry */ - PRInt32 count2 = hostStruct->permissionList->Count(); - if (count2 == 0) { - PR_FREEIF(hostStruct->permissionList); - cookie_permissionList->RemoveElementAt(actualHostNumber); - PR_FREEIF(hostStruct->host); - PR_Free(hostStruct); - } - - /* write the changes out to disk */ - if (save) { - cookie_permissionsChanged = PR_TRUE; - permission_Save(); - } -} - -/* blows away all permissions currently in the list */ -PRIVATE void -cookie_RemoveAllPermissions() { - permission_HostStruct * hostStruct; - permission_TypeStruct * typeStruct; - - /* check for NULL or empty list */ - if (cookie_permissionList == nsnull) { - return; - } - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 i = count-1; i >=0; i--) { - hostStruct = NS_STATIC_CAST - (permission_HostStruct*, cookie_permissionList->ElementAt(i)); - if (!hostStruct) { - return; - } - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex = count2-1; typeIndex >=0; typeIndex--) { - typeStruct = NS_STATIC_CAST - (permission_TypeStruct*, hostStruct->permissionList->ElementAt(typeIndex)); - permission_Free(i, typeStruct->type, PR_FALSE); - } - } - delete cookie_permissionList; - cookie_permissionList = NULL; -} - -PRBool PR_CALLBACK deleteCookie(void *aElement, void *aData) { - cookie_CookieStruct *cookie = (cookie_CookieStruct*)aElement; - PR_FREEIF(cookie->path); - PR_FREEIF(cookie->host); - PR_FREEIF(cookie->name); - PR_FREEIF(cookie->cookie); - PR_Free(cookie); - return PR_TRUE; -} - -PUBLIC void -COOKIE_RemoveAllCookies() -{ - cookie_RemoveAllPermissions(); - - if (cookie_cookieList) { - cookie_cookieList->EnumerateBackwards(deleteCookie, nsnull); - cookie_cookiesChanged = PR_TRUE; - delete cookie_cookieList; - cookie_cookieList = nsnull; - } -} - -PUBLIC void -COOKIE_DeletePersistentUserData(void) -{ - nsresult res; - - nsCOMPtr cookiesFile; - res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(cookiesFile)); - if (NS_SUCCEEDED(res)) { - res = cookiesFile->Append(kCookiesFileName); - if (NS_SUCCEEDED(res)) - (void) cookiesFile->Delete(PR_FALSE); - } - - nsCOMPtr cookiesPermFile; - res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(cookiesPermFile)); - if (NS_SUCCEEDED(res)) { - res = cookiesPermFile->Append(kCookiesPermFileName); - if (NS_SUCCEEDED(res)) - (void) cookiesPermFile->Delete(PR_FALSE); - } -} - -PRIVATE void -cookie_RemoveOldestCookie(void) { - cookie_CookieStruct * cookie_s; - cookie_CookieStruct * oldest_cookie; - - if (cookie_cookieList == nsnull) { - return; - } - - PRInt32 count = cookie_cookieList->Count(); - if (count == 0) { - return; - } - oldest_cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(0)); - PRInt32 oldestLoc = 0; - for (PRInt32 i = 1; i < count; ++i) { - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "cookie list is corrupt"); - if(cookie_s->lastAccessed < oldest_cookie->lastAccessed) { - oldest_cookie = cookie_s; - oldestLoc = i; - } - } - if(oldest_cookie) { - cookie_cookieList->RemoveElementAt(oldestLoc); - deleteCookie((void*)oldest_cookie, nsnull); - cookie_cookiesChanged = PR_TRUE; - } - -} - -/* Remove any expired cookies from memory */ -PRIVATE void -cookie_RemoveExpiredCookies() { - cookie_CookieStruct * cookie_s; - time_t cur_time = get_current_time(); - - if (cookie_cookieList == nsnull) { - return; - } - - for (PRInt32 i = cookie_cookieList->Count(); i > 0;) { - i--; - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "corrupt cookie list"); - /* Don't get rid of expire time 0 because these need to last for - * the entire session. They'll get cleared on exit. */ - if( cookie_s->expires && (cookie_s->expires < cur_time) ) { - cookie_cookieList->RemoveElementAt(i); - deleteCookie((void*)cookie_s, nsnull); - cookie_cookiesChanged = PR_TRUE; - } - } -} - -/* checks to see if the maximum number of cookies per host - * is being exceeded and deletes the oldest one in that - * case - */ -PRIVATE void -cookie_CheckForMaxCookiesFromHo(const char * cur_host) { - cookie_CookieStruct * cookie_s; - cookie_CookieStruct * oldest_cookie = 0; - int cookie_count = 0; - - if (cookie_cookieList == nsnull) { - return; - } - - PRInt32 count = cookie_cookieList->Count(); - PRInt32 oldestLoc = -1; - for (PRInt32 i = 0; i < count; ++i) { - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "corrupt cookie list"); - if(!PL_strcasecmp(cookie_s->host, cur_host)) { - cookie_count++; - if(!oldest_cookie || oldest_cookie->lastAccessed > cookie_s->lastAccessed) { - oldest_cookie = cookie_s; - oldestLoc = i; - } - } - } - if(cookie_count >= MAX_COOKIES_PER_SERVER && oldest_cookie) { - NS_ASSERTION(oldestLoc > -1, "oldestLoc got out of sync with oldest_cookie"); - cookie_cookieList->RemoveElementAt(oldestLoc); - deleteCookie((void*)oldest_cookie, nsnull); - cookie_cookiesChanged = PR_TRUE; - } -} - - -/* search for previous exact match */ -PRIVATE cookie_CookieStruct * -cookie_CheckForPrevCookie(char * path, char * hostname, char * name) { - cookie_CookieStruct * cookie_s; - if (cookie_cookieList == nsnull) { - return NULL; - } - - PRInt32 count = cookie_cookieList->Count(); - for (PRInt32 i = 0; i < count; ++i) { - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "corrupt cookie list"); - if(path && hostname && cookie_s->path && cookie_s->host && cookie_s->name - && !PL_strcmp(name, cookie_s->name) && !PL_strcmp(path, cookie_s->path) - && !PL_strcasecmp(hostname, cookie_s->host)) { - return(cookie_s); - } - } - return(NULL); -} - -/* cookie utility functions */ -PRIVATE void -cookie_SetBehaviorPref(COOKIE_BehaviorEnum x) { - cookie_behavior = x; -} - -PRIVATE void -cookie_SetWarningPref(PRBool x) { - cookie_warning = x; -} - -PRIVATE void -cookie_SetLifetimePref(COOKIE_LifetimeEnum x) { - cookie_lifetimeOpt = x; -} - -PRIVATE void -cookie_SetLifetimeLimit(PRInt32 x) { - // save limit as seconds instead of days - cookie_lifetimeLimit = x*24*60*60; -} - -PUBLIC COOKIE_BehaviorEnum -COOKIE_GetBehaviorPref() { - return cookie_behavior; -} - -PRIVATE PRBool -cookie_GetWarningPref() { - return cookie_warning; -} - -PRIVATE COOKIE_LifetimeEnum -cookie_GetLifetimePref() { - return cookie_lifetimeOpt; -} - -PRIVATE time_t -cookie_GetLifetimeTime() { - // return time after which lifetime is excessive - return get_current_time() + cookie_lifetimeLimit; -} - -#if 0 -PRIVATE PRBool -cookie_GetLifetimeAsk(time_t expireTime) { - // return true if we should ask about this cookie - return (cookie_GetLifetimePref() == COOKIE_Ask) - && (cookie_GetLifetimeTime() < expireTime); -} -#endif - -PRIVATE time_t -cookie_TrimLifetime(time_t expires) { - // return potentially-trimmed lifetime - if (cookie_GetLifetimePref() == COOKIE_Trim) { - // a limit of zero means expire cookies at end of session - if (cookie_lifetimeLimit == 0) { - return 0; - } - time_t limit = cookie_GetLifetimeTime(); - if ((unsigned)expires > (unsigned)limit) { - return limit; - } - } - return expires; -} - -MODULE_PRIVATE int PR_CALLBACK -cookie_BehaviorPrefChanged(const char * newpref, void * data) { - PRInt32 n; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetIntPref(cookie_behaviorPref, &n))) { - n = COOKIE_Accept; - } - cookie_SetBehaviorPref((COOKIE_BehaviorEnum)n); - return 0; -} - -MODULE_PRIVATE int PR_CALLBACK -cookie_WarningPrefChanged(const char * newpref, void * data) { - PRBool x; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetBoolPref(cookie_warningPref, &x))) { - x = PR_FALSE; - } - cookie_SetWarningPref(x); - return 0; -} - -/* cookie utility functions */ -PRIVATE void -image_SetBehaviorPref(COOKIE_BehaviorEnum x) { - image_behavior = x; -} - -PRIVATE void -image_SetWarningPref(PRBool x) { - image_warning = x; -} - -PRIVATE COOKIE_BehaviorEnum -image_GetBehaviorPref() { - return image_behavior; -} - -PRIVATE PRBool -image_GetWarningPref() { - return image_warning; -} - -MODULE_PRIVATE int PR_CALLBACK -image_BehaviorPrefChanged(const char * newpref, void * data) { - PRInt32 n; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetIntPref(image_behaviorPref, &n))) { - image_SetBehaviorPref(COOKIE_Accept); - } else { - image_SetBehaviorPref((COOKIE_BehaviorEnum)n); - } - return 0; -} - -MODULE_PRIVATE int PR_CALLBACK -image_WarningPrefChanged(const char * newpref, void * data) { - PRBool x; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetBoolPref(image_warningPref, &x))) { - x = PR_FALSE; - } - image_SetWarningPref(x); - return 0; -} - -MODULE_PRIVATE int PR_CALLBACK -cookie_LifetimeOptPrefChanged(const char * newpref, void * data) { - PRInt32 n; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetIntPref(cookie_lifetimePref, &n))) { - n = COOKIE_Normal; - } - cookie_SetLifetimePref((COOKIE_LifetimeEnum)n); - return 0; -} - -MODULE_PRIVATE int PR_CALLBACK -cookie_LifetimeLimitPrefChanged(const char * newpref, void * data) { - PRInt32 n; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (!NS_FAILED(prefs->GetIntPref(cookie_lifetimeValue, &n))) { - cookie_SetLifetimeLimit(n); - } - return 0; -} - -/* - * search if permission already exists - */ -nsresult -permission_CheckFromList(char * hostname, PRBool &permission, PRInt32 type) { - permission_HostStruct * hostStruct; - permission_TypeStruct * typeStruct; - - /* ignore leading period in host name */ - while (hostname && (*hostname == '.')) { - hostname++; - } - - /* return if cookie_permission list does not exist */ - if (cookie_permissionList == nsnull) { - return NS_ERROR_FAILURE; - } - - /* find host name within list */ - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 i = 0; i < count; ++i) { - hostStruct = NS_STATIC_CAST(permission_HostStruct*, cookie_permissionList->ElementAt(i)); - if (hostStruct) { - if(hostname && hostStruct->host && !PL_strcasecmp(hostname, hostStruct->host)) { - - /* search for type in the permission list for this host */ - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - if (typeStruct->type == type) { - - /* type found. Obtain the corresponding permission */ - permission = typeStruct->permission; - return NS_OK; - } - } - - /* type not found, return failure */ - return NS_ERROR_FAILURE; - } - } - } - - /* not found, return failure */ - return NS_ERROR_FAILURE; -} - -PRBool -permission_GetRememberChecked(PRInt32 type) { - if (type == COOKIEPERMISSION) { - return cookie_rememberChecked; - } else if (type == IMAGEPERMISSION) { - return image_rememberChecked; - } else { - return PR_FALSE; - } -} - -void -permission_SetRememberChecked(PRInt32 type, PRBool value) { - if (type == COOKIEPERMISSION) { - cookie_rememberChecked = value; - } else if (type == IMAGEPERMISSION) { - image_rememberChecked = value; - } -} - -nsresult -permission_Add(char * host, PRBool permission, PRInt32 type, PRBool save); - -PRBool -permission_Check( - nsIPrompt *aPrompter, - char * hostname, - PRInt32 type, - PRBool warningPref, - PRUnichar * message) -{ - PRBool permission; - - /* try to make decision based on saved permissions */ - if (NS_SUCCEEDED(permission_CheckFromList(hostname, permission, type))) { - return permission; - } - - /* see if we need to prompt */ - if(!warningPref) { - return PR_TRUE; - } - - /* we need to prompt */ - PRBool rememberChecked = permission_GetRememberChecked(type); - PRUnichar * remember_string = cookie_Localize("RememberThisDecision"); - permission = cookie_CheckConfirmYN(aPrompter, message, remember_string, &rememberChecked); - - /* see if we need to remember this decision */ - if (rememberChecked) { - char * hostname2 = NULL; - /* ignore leading periods in host name */ - char * hostnameAfterDot = hostname; - while (hostnameAfterDot && (*hostnameAfterDot == '.')) { - hostnameAfterDot++; - } - StrAllocCopy(hostname2, hostnameAfterDot); - permission_Add(hostname2, permission, type, PR_TRUE); - } - if (rememberChecked != permission_GetRememberChecked(type)) { - permission_SetRememberChecked(type, rememberChecked); - cookie_permissionsChanged = PR_TRUE; - permission_Save(); - } - return permission; -} - -PRIVATE int -cookie_SameDomain(char * currentHost, char * firstHost); - -PUBLIC nsresult -Image_CheckForPermission(char * hostname, char * firstHostname, PRBool &permission) { - - /* exit if imageblocker is not enabled */ - nsresult rv; - PRBool prefvalue = PR_FALSE; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(rv) || - NS_FAILED(prefs->GetBoolPref("imageblocker.enabled", &prefvalue)) || - !prefvalue) { - permission = (image_GetBehaviorPref() != COOKIE_DontUse); +NS_IMETHODIMP nsCookie::GetName(char * *aName) { + if (cookieName) { + *aName = (char *) nsMemory::Clone(cookieName, nsCRT::strlen(cookieName) + 1); return NS_OK; } + return NS_ERROR_NULL_POINTER; +} - /* try to make a decision based on pref settings */ - if ((image_GetBehaviorPref() == COOKIE_DontUse)) { - permission = PR_FALSE; +NS_IMETHODIMP nsCookie::GetValue(char * *aValue) { + if (cookieValue) { + *aValue = (char *) nsMemory::Clone(cookieValue, nsCRT::strlen(cookieValue) + 1); return NS_OK; } - if (image_GetBehaviorPref() == COOKIE_DontAcceptForeign) { - /* compare tails of names checking to see if they have a common domain */ - /* we do this by comparing the tails of both names where each tail includes at least one dot */ - PRInt32 dotcount = 0; - char * tailHostname = hostname + PL_strlen(hostname) - 1; - while (tailHostname > hostname) { - if (*tailHostname == '.') { - dotcount++; - } - if (dotcount == 2) { - tailHostname++; - break; - } - tailHostname--; - } - dotcount = 0; - char * tailFirstHostname = firstHostname + PL_strlen(firstHostname) - 1; - while (tailFirstHostname > firstHostname) { - if (*tailFirstHostname == '.') { - dotcount++; - } - if (dotcount == 2) { - tailFirstHostname++; - break; - } - tailFirstHostname--; - } - if (PL_strcmp(tailFirstHostname, tailHostname)) { - permission = PR_FALSE; - return NS_OK; - } - } + return NS_ERROR_NULL_POINTER; +} - /* use common routine to make decision */ - PRUnichar * message = cookie_Localize("PermissionToAcceptImage"); - PRUnichar * new_string = nsTextFormatter::smprintf(message, hostname ? hostname : ""); - permission = permission_Check(0, hostname, IMAGEPERMISSION, - image_GetWarningPref(), new_string); - PR_FREEIF(new_string); - Recycle(message); +NS_IMETHODIMP nsCookie::GetIsDomain(PRBool *aIsDomain) { + *aIsDomain = cookieIsDomain; return NS_OK; } -/* called from mkgeturl.c, NET_InitNetLib(). This sets the module local - * cookie pref variables and registers the callbacks - */ -PUBLIC void -COOKIE_RegisterCookiePrefCallbacks(void) { - PRInt32 n; - PRBool x; - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - - // Initialize for cookie_behaviorPref - if (NS_FAILED(prefs->GetIntPref(cookie_behaviorPref, &n))) { - n = COOKIE_Accept; +NS_IMETHODIMP nsCookie::GetHost(char * *aHost) { + if (cookieHost) { + *aHost = (char *) nsMemory::Clone(cookieHost, nsCRT::strlen(cookieHost) + 1); + return NS_OK; } - cookie_SetBehaviorPref((COOKIE_BehaviorEnum)n); - prefs->RegisterCallback(cookie_behaviorPref, cookie_BehaviorPrefChanged, NULL); - - // Initialize for cookie_warningPref - if (NS_FAILED(prefs->GetBoolPref(cookie_warningPref, &x))) { - x = PR_FALSE; - } - cookie_SetWarningPref(x); - prefs->RegisterCallback(cookie_warningPref, cookie_WarningPrefChanged, NULL); - - if (NS_FAILED(prefs->GetIntPref(image_behaviorPref, &n))) { - n = COOKIE_Accept; - } - image_SetBehaviorPref((COOKIE_BehaviorEnum)n); - prefs->RegisterCallback(image_behaviorPref, image_BehaviorPrefChanged, NULL); - - if (NS_FAILED(prefs->GetBoolPref(image_warningPref, &x))) { - x = PR_FALSE; - } - image_SetWarningPref(x); - prefs->RegisterCallback(image_warningPref, image_WarningPrefChanged, NULL); - - // Initialize for cookie_lifetimePref - if (NS_FAILED(prefs->GetIntPref(cookie_lifetimePref, &n))) { - n = COOKIE_Normal; - } - cookie_SetLifetimePref((COOKIE_LifetimeEnum)n); - prefs->RegisterCallback(cookie_lifetimePref, cookie_LifetimeOptPrefChanged, NULL); - - // Initialize for cookie_lifetimeValue - if (!NS_FAILED(prefs->GetIntPref(cookie_lifetimeValue, &n))) { - cookie_SetLifetimeLimit(n); - } - prefs->RegisterCallback(cookie_lifetimeValue, cookie_LifetimeLimitPrefChanged, NULL); + return NS_ERROR_NULL_POINTER; } -PRBool -cookie_IsInDomain(char* domain, char* host, int hostLength) { - int domainLength = PL_strlen(domain); - - /* - * special case for domainName = .hostName - * e.g., hostName = netscape.com - * domainName = .netscape.com - */ - if ((domainLength == hostLength+1) && (domain[0] == '.') && - !PL_strncasecmp(&domain[1], host, hostLength)) { - return PR_TRUE; +NS_IMETHODIMP nsCookie::GetPath(char * *aPath) { + if (cookiePath) { + *aPath = (char *) nsMemory::Clone(cookiePath, nsCRT::strlen(cookiePath) + 1); + return NS_OK; } - - /* - * normal case for hostName = x - * e.g., hostName = home.netscape.com - * domainName = .netscape.com - */ - if(domainLength <= hostLength && - !PL_strncasecmp(domain, &host[hostLength-domainLength], domainLength)) { - return PR_TRUE; - } - - /* tests failed, not in domain */ - return PR_FALSE; + return NS_ERROR_NULL_POINTER; } -/* returns PR_TRUE if authorization is required -** -** -** IMPORTANT: Now that this routine is multi-threaded it is up -** to the caller to free any returned string -*/ -PUBLIC char * -COOKIE_GetCookie(char * address) { - char *name=0; - cookie_CookieStruct * cookie_s; - PRBool secure = PR_FALSE; - time_t cur_time = get_current_time(); - - int host_length; - - /* return string to build */ - char * rv=0; - - /* disable cookies if the user's prefs say so */ - if(COOKIE_GetBehaviorPref() == COOKIE_DontUse) { - return NULL; - } - if (!PL_strncasecmp(address, "https", 5)) { - secure = PR_TRUE; - } - - /* search for all cookies */ - if (cookie_cookieList == nsnull) { - return NULL; - } - char *host = cookie_ParseURL(address, GET_HOST_PART); - char *path = cookie_ParseURL(address, GET_PATH_PART); - for (PRInt32 i = 0; i Count(); i++) { - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "corrupt cookie list"); - if(!cookie_s->host) continue; - - /* check the host or domain first */ - if(cookie_s->isDomain) { - char *cp; - - /* calculate the host length by looking at all characters up to a - * colon or '\0'. That way we won't include port numbers in domains - */ - for(cp=host; *cp != '\0' && *cp != ':'; cp++) { - ; /* null body */ - } - host_length = cp - host; - if(!cookie_IsInDomain(cookie_s->host, host, host_length)) { - continue; - } - } else if(PL_strcasecmp(host, cookie_s->host)) { - /* hostname matchup failed. FAIL */ - continue; - } - - /* shorter strings always come last so there can be no ambiquity */ - if(cookie_s->path && !PL_strncmp(path, cookie_s->path, PL_strlen(cookie_s->path))) { - - /* if the cookie is secure and the path isn't, dont send it */ - if (cookie_s->secure & !secure) { - continue; /* back to top of while */ - } - - /* check for expired cookies */ - if( cookie_s->expires && (cookie_s->expires < cur_time) ) { - /* expire and remove the cookie */ - cookie_cookieList->RemoveElementAt(i); - deleteCookie((void*)cookie_s, nsnull); - cookie_cookiesChanged = PR_TRUE; - continue; - } - - /* if we've already added a cookie to the return list, append a "; " so - * subsequent cookies are delimited in the final list. */ - if (rv) StrAllocCat(rv, "; "); - - if(cookie_s->name && *cookie_s->name != '\0') { - cookie_s->lastAccessed = cur_time; - StrAllocCopy(name, cookie_s->name); - StrAllocCat(name, "="); - -#ifdef PREVENT_DUPLICATE_NAMES - /* make sure we don't have a previous name mapping already in the string */ - if(!rv || !PL_strstr(rv, name)) { - StrAllocCat(rv, name); - StrAllocCat(rv, cookie_s->cookie); - } -#else - StrAllocCat(rv, name); - StrAllocCat(rv, cookie_s->cookie); -#endif /* PREVENT_DUPLICATE_NAMES */ - } else { - StrAllocCat(rv, cookie_s->cookie); - } - } - } - - PR_FREEIF(name); - PR_FREEIF(path); - PR_FREEIF(host); - - /* may be NULL */ - return(rv); -} - -/* Determines whether the inlineHost is in the same domain as the currentHost. - * For use with rfc 2109 compliance/non-compliance. - */ -PRIVATE int -cookie_SameDomain(char * currentHost, char * firstHost) { - char * dot = 0; - char * currentDomain = 0; - char * firstDomain = 0; - if(!currentHost || !firstHost) { - return 0; - } - - /* case insensitive compare */ - if(PL_strcasecmp(currentHost, firstHost) == 0) { - return 1; - } - currentDomain = PL_strchr(currentHost, '.'); - firstDomain = PL_strchr(firstHost, '.'); - if(!currentDomain || !firstDomain) { - return 0; - } - - /* check for at least two dots before continuing, if there are - * not two dots we don't have enough information to determine - * whether or not the firstDomain is within the currentDomain - */ - dot = PL_strchr(firstDomain, '.'); - if(dot) { - dot = PL_strchr(dot+1, '.'); - } else { - return 0; - } - - /* handle .com. case */ - if(!dot || (*(dot+1) == '\0')) { - return 0; - } - if(!PL_strcasecmp(firstDomain, currentDomain)) { - return 1; - } - return 0; -} - -PRBool -cookie_isForeign (char * curURL, char * firstURL) { - char * curHost = cookie_ParseURL(curURL, GET_HOST_PART); - char * firstHost = cookie_ParseURL(firstURL, GET_HOST_PART); - char * curHostColon = 0; - char * firstHostColon = 0; - - /* strip ports */ - curHostColon = PL_strchr(curHost, ':'); - if(curHostColon) { - *curHostColon = '\0'; - } - firstHostColon = PL_strchr(firstHost, ':'); - if(firstHostColon) { - *firstHostColon = '\0'; - } - - /* determine if it's foreign */ - PRBool retval = (!cookie_SameDomain(curHost, firstHost)); - - /* clean up our garbage and return */ - if(curHostColon) { - *curHostColon = ':'; - } - if(firstHostColon) { - *firstHostColon = ':'; - } - PR_FREEIF(curHost); - PR_FREEIF(firstHost); - return retval; -} - -/* returns PR_TRUE if authorization is required -** -** -** IMPORTANT: Now that this routine is multi-threaded it is up -** to the caller to free any returned string -*/ -PUBLIC char * -COOKIE_GetCookieFromHttp(char * address, char * firstAddress) { - - if ((COOKIE_GetBehaviorPref() == COOKIE_DontAcceptForeign) && - cookie_isForeign(address, firstAddress)) { - - /* - * WARNING!!! This is a different behavior than 4.x. In 4.x we used this pref to - * control the setting of cookies only. Here we are also blocking the getting of - * cookies if the pref is set. It may be that we need a separate pref to block the - * getting of cookies. But for now we are putting both under one pref since that - * is cleaner. If it turns out that this breaks some important websites, we may - * have to resort to two prefs - */ - - return NULL; - } - return COOKIE_GetCookie(address); -} - -nsresult -permission_Add(char * host, PRBool permission, PRInt32 type, PRBool save) { - /* create permission list if it does not yet exist */ - if(!cookie_permissionList) { - cookie_permissionList = new nsVoidArray(); - if(!cookie_permissionList) { - Recycle(host); - return NS_ERROR_FAILURE; - } - } - - /* find existing entry for host */ - permission_HostStruct * hostStruct; - PRBool HostFound = PR_FALSE; - PRInt32 count = cookie_permissionList->Count(); - PRInt32 i; - for (i = 0; i < count; ++i) { - hostStruct = NS_STATIC_CAST(permission_HostStruct*, cookie_permissionList->ElementAt(i)); - if (hostStruct) { - if (PL_strcasecmp(host,hostStruct->host)==0) { - - /* host found in list */ - Recycle(host); - HostFound = PR_TRUE; - break; -#ifdef alphabetize - } else if (PL_strcasecmp(host,hostStruct->host)<0) { - - /* need to insert new entry here */ - break; -#endif - } - } - } - - if (!HostFound) { - - /* create a host structure for the host */ - hostStruct = PR_NEW(permission_HostStruct); - if (!hostStruct) { - Recycle(host); - return NS_ERROR_FAILURE; - } - hostStruct->host = host; - hostStruct->permissionList = new nsVoidArray(); - if(!hostStruct->permissionList) { - PR_Free(hostStruct); - Recycle(host); - return NS_ERROR_FAILURE; - } - - /* insert host structure into the list */ - if (i == cookie_permissionList->Count()) { - cookie_permissionList->AppendElement(hostStruct); - } else { - cookie_permissionList->InsertElementAt(hostStruct, i); - } - } - - /* see if host already has an entry for this type */ - permission_TypeStruct * typeStruct; - PRBool typeFound = PR_FALSE; - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - if (typeStruct->type == type) { - - /* type found. Modify the corresponding permission */ - typeStruct->permission = permission; - typeFound = PR_TRUE; - break; - } - } - - /* create a type structure and attach it to the host structure */ - if (!typeFound) { - typeStruct = PR_NEW(permission_TypeStruct); - typeStruct->type = type; - typeStruct->permission = permission; - hostStruct->permissionList->AppendElement(typeStruct); - } - - /* write the changes out to a file */ - if (save) { - cookie_permissionsChanged = PR_TRUE; - permission_Save(); - } +NS_IMETHODIMP nsCookie::GetIsSecure(PRBool *aIsSecure) { + *aIsSecure = cookieIsSecure; return NS_OK; } -PRIVATE void -permission_Unblock(char * host, PRInt32 type) { - - /* nothing to do if permission list does not exist */ - if(!cookie_permissionList) { - return; - } - - /* find existing entry for host */ - permission_HostStruct * hostStruct; - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 hostIndex = 0; hostIndex < count; ++hostIndex) { - hostStruct = NS_STATIC_CAST(permission_HostStruct*, cookie_permissionList->ElementAt(hostIndex)); - if (hostStruct && PL_strcasecmp(host, hostStruct->host)==0) { - /* host found in list, see if it has an entry for this type */ - permission_TypeStruct * typeStruct; - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - if (typeStruct && typeStruct->type == type) { - /* type found. Remove the permission if it is PR_FALSE */ - if (typeStruct->permission == PR_FALSE) { - hostStruct->permissionList->RemoveElementAt(typeIndex); - /* if no more types are present, remove the entry */ - count2 = hostStruct->permissionList->Count(); - if (count2 == 0) { - PR_FREEIF(hostStruct->permissionList); - cookie_permissionList->RemoveElementAt(hostIndex); - PR_FREEIF(hostStruct->host); - PR_Free(hostStruct); - } - permission_Save(); - return; - } - break; - } - } - break; - } - } - return; -} - -MODULE_PRIVATE PRBool -cookie_IsFromHost(cookie_CookieStruct *cookie_s, char *host) { - if (!cookie_s || !(cookie_s->host)) { - return PR_FALSE; - } - if (cookie_s->isDomain) { - char *cp; - int host_length; - - /* calculate the host length by looking at all characters up to - * a colon or '\0'. That way we won't include port numbers - * in domains - */ - for(cp=host; *cp != '\0' && *cp != ':'; cp++) { - ; /* null body */ - } - host_length = cp - host; - - /* compare the tail end of host to cook_s->host */ - return cookie_IsInDomain(cookie_s->host, host, host_length); - } else { - return PL_strcasecmp(host, cookie_s->host) == 0; - } -} - -/* find out how many cookies this host has already set */ -PRIVATE int -cookie_Count(char * host) { - int count = 0; - cookie_CookieStruct * cookie; - if (!cookie_cookieList || !host) return 0; - - for (PRInt32 i = cookie_cookieList->Count(); i > 0;) { - i--; - cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie, "corrupt cookie list"); - if (cookie_IsFromHost(cookie, host)) count++; - } - return count; -} - -PRIVATE void -cookie_SetCookieString(char * curURL, nsIPrompt *aPrompter, char * setCookieHeader, time_t timeToExpire ); - -/* Java script is calling COOKIE_SetCookieString, netlib is calling - * this via COOKIE_SetCookieStringFromHttp. - */ -PRIVATE void -cookie_SetCookieString(char * curURL, nsIPrompt *aPrompter, char * setCookieHeader, time_t timeToExpire) { - cookie_CookieStruct * prev_cookie; - char *path_from_header=NULL, *host_from_header=NULL; - char *name_from_header=NULL, *cookie_from_header=NULL; - char *cur_path = cookie_ParseURL(curURL, GET_PATH_PART); - char *cur_host = cookie_ParseURL(curURL, GET_HOST_PART); - char *semi_colon, *ptr, *equal; - PRBool secure=PR_FALSE, isDomain=PR_FALSE; - PRBool bCookieAdded; - PRBool pref_scd = PR_FALSE; - - /* Only allow cookies to be set in the listed contexts. - * We don't want cookies being set in html mail. - */ -/* We need to come back and work on this - Neeti - type = context->type; - if(!((type==MWContextBrowser) || (type==MWContextHTMLHelp) || (type==MWContextPane))) { - PR_Free(cur_path); - PR_Free(cur_host); - return; - } -*/ - if(COOKIE_GetBehaviorPref() == COOKIE_DontUse) { - PR_Free(cur_path); - PR_Free(cur_host); - return; - } - -//printf("\nSetCookieString(URL '%s', header '%s') time %d == %s\n",curURL,setCookieHeader,timeToExpire,asctime(gmtime(&timeToExpire))); - if(cookie_GetLifetimePref() == COOKIE_Discard) { - if(cookie_GetLifetimeTime() < timeToExpire) { - PR_Free(cur_path); - PR_Free(cur_host); - return; - } - } - -//HG87358 -- @@?? - - /* terminate at any carriage return or linefeed */ - for(ptr=setCookieHeader; *ptr; ptr++) { - if(*ptr == LF || *ptr == CR) { - *ptr = '\0'; - break; - } - } - - /* parse path and expires attributes from header if present */ - semi_colon = PL_strchr(setCookieHeader, ';'); - if(semi_colon) { - /* truncate at semi-colon and advance */ - *semi_colon++ = '\0'; - - /* there must be some attributes. (hopefully) */ - if ((ptr=PL_strcasestr(semi_colon, "secure"))) { - char cPre=*(ptr-1), cPost=*(ptr+6); - if (((cPre==' ') || (cPre==';')) && (!cPost || (cPost==' ') || (cPost==';'))) { - secure = PR_TRUE; - } - } - - /* look for the path attribute */ - ptr = PL_strcasestr(semi_colon, "path="); - if(ptr) { - nsCString path(ptr+5); - path.CompressWhitespace(); - StrAllocCopy(path_from_header, path.get()); - /* terminate at first space or semi-colon */ - for(ptr=path_from_header; *ptr != '\0'; ptr++) { - if(COOKIE_IS_SPACE(*ptr) || *ptr == ';' || *ptr == ',') { - *ptr = '\0'; - break; - } - } - } - - /* look for the URI or URL attribute - * - * This might be a security hole so I'm removing - * it for now. - */ - - /* look for a domain */ - ptr = PL_strcasestr(semi_colon, "domain="); - if(ptr) { - char *domain_from_header=NULL; - char *dot, *colon; - int domain_length, cur_host_length; - - /* allocate more than we need */ - nsCString domain(ptr+7); - domain.CompressWhitespace(); - StrAllocCopy(domain_from_header, domain.get()); - - /* terminate at first space or semi-colon */ - for(ptr=domain_from_header; *ptr != '\0'; ptr++) { - if(COOKIE_IS_SPACE(*ptr) || *ptr == ';' || *ptr == ',') { - *ptr = '\0'; - break; - } - } - - /* verify that this host has the authority to set for this domain. We do - * this by making sure that the host is in the domain. We also require - * that a domain have at least two periods to prevent domains of the form - * ".com" and ".edu" - * - * Also make sure that there is more stuff after - * the second dot to prevent ".com." - */ - dot = PL_strchr(domain_from_header, '.'); - if(dot) { - dot = PL_strchr(dot+1, '.'); - } - if(!dot || *(dot+1) == '\0') { - /* did not pass two dot test. FAIL */ - PR_FREEIF(path_from_header); - PR_Free(domain_from_header); - PR_Free(cur_path); - PR_Free(cur_host); - // TRACEMSG(("DOMAIN failed two dot test")); - return; - } - - /* strip port numbers from the current host for the domain test */ - colon = PL_strchr(cur_host, ':'); - if(colon) { - *colon = '\0'; - } - domain_length = PL_strlen(domain_from_header); - cur_host_length = PL_strlen(cur_host); - - /* check to see if the host is in the domain */ - if (!cookie_IsInDomain(domain_from_header, cur_host, cur_host_length)) { - // TRACEMSG(("DOMAIN failed host within domain test." -// " Domain: %s, Host: %s", domain_from_header, cur_host)); - PR_FREEIF(path_from_header); - PR_Free(domain_from_header); - PR_Free(cur_path); - PR_Free(cur_host); - return; - } - - /* - * check that portion of host not in domain does not contain a dot - * This satisfies the fourth requirement in section 4.3.2 of the cookie - * spec rfc 2109 (see www.cis.ohio-state.edu/htbin/rfc/rfc2109.html). - * It prevents host of the form x.y.co.nz from setting cookies in the - * entire .co.nz domain. Note that this doesn't really solve the problem, - * it justs makes it more unlikely. Sites such as y.co.nz can still set - * cookies for the entire .co.nz domain. - */ - - /* - * Although this is the right thing to do(tm), it breaks too many sites. - * So only do it if the restrictCookieDomains pref is PR_TRUE. - * - */ - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, "@mozilla.org/preferences;1", &rv); - if (NS_FAILED(prefs->GetBoolPref(cookie_strictDomainsPref, &pref_scd))) { - pref_scd = PR_FALSE; - } - if ( pref_scd == PR_TRUE ) { - cur_host[cur_host_length-domain_length] = '\0'; - dot = PL_strchr(cur_host, '.'); - cur_host[cur_host_length-domain_length] = '.'; - if (dot) { - // TRACEMSG(("host minus domain failed no-dot test." -// " Domain: %s, Host: %s", domain_from_header, cur_host)); - PR_FREEIF(path_from_header); - PR_Free(domain_from_header); - PR_Free(cur_path); - PR_Free(cur_host); - return; - } - } - - /* all tests passed, copy in domain to hostname field */ - StrAllocCopy(host_from_header, domain_from_header); - isDomain = PR_TRUE; - // TRACEMSG(("Accepted domain: %s", host_from_header)); - PR_Free(domain_from_header); - } - - /* now search for the expires header - * NOTE: that this part of the parsing - * destroys the original part of the string - */ - ptr = PL_strcasestr(semi_colon, "expires="); - if(ptr) { - char *date = ptr+8; - /* terminate the string at the next semi-colon */ - for(ptr=date; *ptr != '\0'; ptr++) { - if(*ptr == ';') { - *ptr = '\0'; - break; - } - } - if(timeToExpire == 0) { - timeToExpire = cookie_ParseDate(date); - } - // TRACEMSG(("Have expires date: %ld", timeToExpire)); - } - } - if(!path_from_header) { - /* strip down everything after the last slash to get the path. */ - char * slash = PL_strrchr(cur_path, '/'); - if(slash) { - *slash = '\0'; - } - path_from_header = cur_path; - } else { - PR_Free(cur_path); - } - if(!host_from_header) { - host_from_header = cur_host; - } else { - PR_Free(cur_host); - } - - /* keep cookies under the max bytes limit */ - if(PL_strlen(setCookieHeader) > MAX_BYTES_PER_COOKIE) { - setCookieHeader[MAX_BYTES_PER_COOKIE-1] = '\0'; - } - - /* separate the name from the cookie */ - equal = PL_strchr(setCookieHeader, '='); - if (equal) - *equal = '\0'; - - nsCString cookieHeader(setCookieHeader); - cookieHeader.CompressWhitespace(); - if(equal) { - StrAllocCopy(name_from_header, cookieHeader.get()); - nsCString value(equal+1); - value.CompressWhitespace(); - StrAllocCopy(cookie_from_header, value.get()); - } else { - StrAllocCopy(cookie_from_header, cookieHeader.get()); - StrAllocCopy(name_from_header, ""); - } - - /* generate the message for the nag box */ - PRUnichar * new_string=0; - int count = cookie_Count(host_from_header); - prev_cookie = cookie_CheckForPrevCookie - (path_from_header, host_from_header, name_from_header); - PRUnichar * message; - if (prev_cookie) { - message = cookie_Localize("PermissionToModifyCookie"); - new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); - } else if (count>1) { - message = cookie_Localize("PermissionToSetAnotherCookie"); - new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : "", count); - } else if (count==1){ - message = cookie_Localize("PermissionToSetSecondCookie"); - new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); - } else { - message = cookie_Localize("PermissionToSetACookie"); - new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); - } - Recycle(message); - - //TRACEMSG(("mkaccess.c: Setting cookie: %s for host: %s for path: %s", - // cookie_from_header, host_from_header, path_from_header)); - - /* use common code to determine if we can set the cookie */ - PRBool permission = permission_Check(aPrompter, host_from_header, COOKIEPERMISSION, -// I believe this is the right place to eventually add the logic to ask -// about cookies that have excessive lifetimes, but it shouldn't be done -// until generalized per-site preferences are available. - //cookie_GetLifetimeAsk(timeToExpire) || - cookie_GetWarningPref(), - new_string); - PR_FREEIF(new_string); - if (!permission) { - PR_FREEIF(path_from_header); - PR_FREEIF(host_from_header); - PR_FREEIF(name_from_header); - PR_FREEIF(cookie_from_header); - return; - } - - /* limit the number of cookies from a specific host or domain */ - cookie_CheckForMaxCookiesFromHo(host_from_header); - - if (cookie_cookieList) { - if(cookie_cookieList->Count() > MAX_NUMBER_OF_COOKIES-1) { - cookie_RemoveOldestCookie(); - } - } - prev_cookie = cookie_CheckForPrevCookie (path_from_header, host_from_header, name_from_header); - if(prev_cookie) { - prev_cookie->expires = cookie_TrimLifetime(timeToExpire); - PR_FREEIF(prev_cookie->cookie); - PR_FREEIF(prev_cookie->path); - PR_FREEIF(prev_cookie->host); - PR_FREEIF(prev_cookie->name); - prev_cookie->cookie = cookie_from_header; - prev_cookie->path = path_from_header; - prev_cookie->host = host_from_header; - prev_cookie->name = name_from_header; - prev_cookie->secure = secure; - prev_cookie->isDomain = isDomain; - prev_cookie->lastAccessed = get_current_time(); - } else { - cookie_CookieStruct * tmp_cookie_ptr; - size_t new_len; - - /* construct a new cookie_struct */ - prev_cookie = PR_NEW(cookie_CookieStruct); - if(!prev_cookie) { - PR_FREEIF(path_from_header); - PR_FREEIF(host_from_header); - PR_FREEIF(name_from_header); - PR_FREEIF(cookie_from_header); - return; - } - - /* copy */ - prev_cookie->cookie = cookie_from_header; - prev_cookie->name = name_from_header; - prev_cookie->path = path_from_header; - prev_cookie->host = host_from_header; - prev_cookie->expires = cookie_TrimLifetime(timeToExpire); - prev_cookie->secure = secure; - prev_cookie->isDomain = isDomain; - prev_cookie->lastAccessed = get_current_time(); - if(!cookie_cookieList) { - cookie_cookieList = new nsVoidArray(); - if(!cookie_cookieList) { - PR_FREEIF(path_from_header); - PR_FREEIF(name_from_header); - PR_FREEIF(host_from_header); - PR_FREEIF(cookie_from_header); - PR_Free(prev_cookie); - return; - } - } - - /* add it to the list so that it is before any strings of smaller length */ - bCookieAdded = PR_FALSE; - new_len = PL_strlen(prev_cookie->path); - for (PRInt32 i = cookie_cookieList->Count(); i > 0;) { - i--; - tmp_cookie_ptr = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(tmp_cookie_ptr, "corrupt cookie list"); - if(new_len <= PL_strlen(tmp_cookie_ptr->path)) { - cookie_cookieList->InsertElementAt(prev_cookie, i+1); - bCookieAdded = PR_TRUE; - break; - } - } - if ( !bCookieAdded ) { - /* no shorter strings found in list */ - cookie_cookieList->AppendElement(prev_cookie); - } - } - - /* At this point we know a cookie has changed. Write the cookies to file. */ - cookie_cookiesChanged = PR_TRUE; - cookie_Save(); - return; -} - -PUBLIC void -COOKIE_SetCookieString(char * curURL, nsIPrompt *aPrompter, char * setCookieHeader) { - cookie_SetCookieString(curURL, aPrompter, setCookieHeader, 0); -} - -/* This function wrapper wraps COOKIE_SetCookieString for the purposes of - * determining whether or not a cookie is inline (we need the URL struct, - * and outputFormat to do so). this is called from NET_ParseMimeHeaders - * in mkhttp.c - * This routine does not need to worry about the cookie lock since all of - * the work is handled by sub-routines -*/ - -PUBLIC void -COOKIE_SetCookieStringFromHttp(char * curURL, char * firstURL, nsIPrompt *aPrompter, char * setCookieHeader, char * server_date) { - - /* allow for multiple cookies separated by newlines */ - char *newline = PL_strchr(setCookieHeader, '\n'); - if(newline) { - *newline = '\0'; - COOKIE_SetCookieStringFromHttp(curURL, firstURL, aPrompter, setCookieHeader, server_date); - *newline = '\n'; - COOKIE_SetCookieStringFromHttp(curURL, firstURL, aPrompter, newline+1, server_date); - return; - } - - /* If the outputFormat is not PRESENT (the url is not going to the screen), and not - * SAVE AS (shift-click) then - * the cookie being set is defined as inline so we need to do what the user wants us - * to based on his preference to deal with foreign cookies. If it's not inline, just set - * the cookie. - */ - char *ptr=NULL; - time_t gmtCookieExpires=0, expires=0, sDate; - - /* check for foreign cookie if pref says to reject such */ - if ((COOKIE_GetBehaviorPref() == COOKIE_DontAcceptForeign) && - cookie_isForeign(curURL, firstURL)) { - /* it's a foreign cookie so don't set the cookie */ - return; - } - - /* Determine when the cookie should expire. This is done by taking the difference between - * the server time and the time the server wants the cookie to expire, and adding that - * difference to the client time. This localizes the client time regardless of whether or - * not the TZ environment variable was set on the client. - */ - - /* Get the time the cookie is supposed to expire according to the attribute*/ - ptr = PL_strcasestr(setCookieHeader, "expires="); - if(ptr) { - char *date = ptr+8; - char origLast = '\0'; - for(ptr=date; *ptr != '\0'; ptr++) { - if(*ptr == ';') { - origLast = ';'; - *ptr = '\0'; - break; - } - } - expires = cookie_ParseDate(date); - *ptr=origLast; - } - if (server_date) { - sDate = cookie_ParseDate(server_date); - } else { - sDate = get_current_time(); - } - if( sDate && expires ) { - if( expires < sDate ) { - gmtCookieExpires=1; - } else { - gmtCookieExpires = expires - sDate + get_current_time(); - // if overflow - if( gmtCookieExpires < get_current_time()) { - gmtCookieExpires = (((unsigned) (~0) << 1) >> 1); // max int - } - } - } - cookie_SetCookieString(curURL, aPrompter, setCookieHeader, gmtCookieExpires); -} - -/* saves the HTTP cookies permissions to disk */ -PRIVATE void -permission_Save() { - permission_HostStruct * hostStruct; - permission_TypeStruct * typeStruct; - - if (!cookie_permissionsChanged) { - return; - } - if (cookie_permissionList == nsnull) { - return; - } - nsFileSpec dirSpec; - nsresult rval = cookie_ProfileDirectory(dirSpec); - if (NS_FAILED(rval)) { - return; - } - nsOutputFileStream strm(dirSpec + kCookiesPermFileName); - if (!strm.is_open()) { - return; - } - - strm.write("# HTTP Cookie Permission File\n", 30); - strm.write("# http://www.netscape.com/newsref/std/cookie_spec.html\n", 55); - strm.write("# This is a generated file! Do not edit.\n\n", 43); - - /* format shall be: - * host \t permission \t permission ... \n - */ - - - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 i = 0; i < count; ++i) { - hostStruct = NS_STATIC_CAST(permission_HostStruct*, cookie_permissionList->ElementAt(i)); - if (hostStruct) { - strm.write(hostStruct->host, nsCRT::strlen(hostStruct->host)); - - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - strm.write("\t", 1); - nsCAutoString tmp; tmp.AppendInt(typeStruct->type); - strm.write(tmp.get(), tmp.Length()); - if (typeStruct->permission) { - strm.write("T", 1); - } else { - strm.write("F", 1); - } - } - strm.write("\n", 1); - } - } - - /* save current state of nag boxs' checkmarks */ - strm.write("@@@@", 4); - for (PRInt32 type = 0; type < NUMBER_OF_PERMISSIONS; type++) { - strm.write("\t", 1); - nsCAutoString tmp; tmp.AppendInt(type); - strm.write(tmp.get(), tmp.Length()); - if (permission_GetRememberChecked(type)) { - strm.write("T", 1); - } else { - strm.write("F", 1); - } - } - - strm.write("\n", 1); - - cookie_permissionsChanged = PR_FALSE; - strm.flush(); - strm.close(); -} - -/* reads the HTTP cookies permission from disk */ -PRIVATE void -permission_Load() { - nsAutoString buffer; - nsFileSpec dirSpec; - nsresult rv = cookie_ProfileDirectory(dirSpec); - if (NS_FAILED(rv)) { - return; - } - nsInputFileStream strm(dirSpec + kCookiesPermFileName); - if (!strm.is_open()) { - /* file doesn't exist -- that's not an error */ - for (PRInt32 type=0; type= '0' && c <= '9') { - type = 10*type + (c-'0'); - c = (char)permissionString.CharAt(++index); - } - if (index >= permissionString.Length()) { - continue; /* bad format for this permission entry */ - } - PRBool permission = (permissionString.CharAt(index) == 'T'); - - /* - * a host value of "@@@@" is a special code designating the - * state of the cookie nag-box's checkmark - */ - if (host.EqualsWithConversion("@@@@")) { - if (!permissionString.IsEmpty()) { - permission_SetRememberChecked(type, permission); - } - } else { - if (!permissionString.IsEmpty()) { - rv = permission_Add(host.ToNewCString(), permission, type, PR_FALSE); - if (NS_FAILED(rv)) { - strm.close(); - return; - } - } - } - } - } - - strm.close(); - cookie_permissionsChanged = PR_FALSE; - return; -} - -/* saves out the HTTP cookies to disk */ -PRIVATE void -cookie_Save() { - cookie_CookieStruct * cookie_s; - time_t cur_date = get_current_time(); - char date_string[36]; - if (!cookie_cookiesChanged) { - return; - } - if (cookie_cookieList == nsnull) { - return; - } - nsFileSpec dirSpec; - nsresult rv = cookie_ProfileDirectory(dirSpec); - if (NS_FAILED(rv)) { - return; - } - nsOutputFileStream strm(dirSpec + kCookiesFileName); - if (!strm.is_open()) { - /* file doesn't exist -- that's not an error */ - return; - } - - strm.write("# HTTP Cookie File\n", 19); - strm.write("# http://www.netscape.com/newsref/std/cookie_spec.html\n", 55); - strm.write("# This is a generated file! Do not edit.\n", 42); - strm.write("# To delete cookies, use the Cookie Manager.\n\n", 46); - - /* format shall be: - * - * host \t isDomain \t path \t secure \t expires \t name \t cookie - * - * isDomain is PR_TRUE or PR_FALSE - * secure is PR_TRUE or PR_FALSE - * expires is a time_t integer - * cookie can have tabs - */ - PRInt32 count = cookie_cookieList->Count(); - for (PRInt32 i = 0; i < count; ++i) { - cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_s, "corrupt cookie list"); - if (cookie_s->expires < cur_date) { - /* don't write entry if cookie has expired or has no expiration date */ - continue; - } - - strm.write(cookie_s->host, nsCRT::strlen(cookie_s->host)); - - if (cookie_s->isDomain) { - strm.write("\tTRUE\t", 6); - } else { - strm.write("\tFALSE\t", 7); - } - - strm.write(cookie_s->path, nsCRT::strlen(cookie_s->path)); - - if (cookie_s->secure) { - strm.write("\tTRUE\t", 6); - } else { - strm.write("\tFALSE\t", 7); - } - - PR_snprintf(date_string, sizeof(date_string), "%lu", cookie_s->expires); - - strm.write(date_string, nsCRT::strlen(date_string)); - strm.write("\t", 1); - strm.write(cookie_s->name, nsCRT::strlen(cookie_s->name)); - strm.write("\t", 1); - strm.write(cookie_s->cookie, nsCRT::strlen(cookie_s->cookie)); - strm.write("\n", 1); - } - - cookie_cookiesChanged = PR_FALSE; - strm.flush(); - strm.close(); -} - -/* reads HTTP cookies from disk */ -PRIVATE void -cookie_Load() { - cookie_CookieStruct *new_cookie, *tmp_cookie_ptr; - size_t new_len; - nsAutoString buffer; - PRBool added_to_list; - nsFileSpec dirSpec; - nsresult rv = cookie_ProfileDirectory(dirSpec); - if (NS_FAILED(rv)) { - return; - } - nsInputFileStream strm(dirSpec + kCookiesFileName); - if (!strm.is_open()) { - /* file doesn't exist -- that's not an error */ - return; - } - - /* format is: - * - * host \t isDomain \t path \t secure \t expires \t name \t cookie - * - * if this format isn't respected we move onto the next line in the file. - * isDomain is PR_TRUE or PR_FALSE -- defaulting to PR_FALSE - * secure is PR_TRUE or PR_FALSE -- should default to PR_TRUE - * expires is a time_t integer - * cookie can have tabs - */ - while (cookie_GetLine(strm,buffer) != -1){ - added_to_list = PR_FALSE; - - if ( !buffer.IsEmpty() ) { - PRUnichar firstChar = buffer.CharAt(0); - if (firstChar == '#' || firstChar == CR || - firstChar == LF || firstChar == 0) { - continue; - } - } - int hostIndex, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex; - hostIndex = 0; - if ((isDomainIndex=buffer.FindChar('\t', PR_FALSE,hostIndex)+1) == 0 || - (pathIndex=buffer.FindChar('\t', PR_FALSE,isDomainIndex)+1) == 0 || - (secureIndex=buffer.FindChar('\t', PR_FALSE,pathIndex)+1) == 0 || - (expiresIndex=buffer.FindChar('\t', PR_FALSE,secureIndex)+1) == 0 || - (nameIndex=buffer.FindChar('\t', PR_FALSE,expiresIndex)+1) == 0 || - (cookieIndex=buffer.FindChar('\t', PR_FALSE,nameIndex)+1) == 0 ) { - continue; - } - nsAutoString host, isDomain, path, secure, expires, name, cookie; - buffer.Mid(host, hostIndex, isDomainIndex-hostIndex-1); - buffer.Mid(isDomain, isDomainIndex, pathIndex-isDomainIndex-1); - buffer.Mid(path, pathIndex, secureIndex-pathIndex-1); - buffer.Mid(secure, secureIndex, expiresIndex-secureIndex-1); - buffer.Mid(expires, expiresIndex, nameIndex-expiresIndex-1); - buffer.Mid(name, nameIndex, cookieIndex-nameIndex-1); - buffer.Mid(cookie, cookieIndex, buffer.Length()-cookieIndex); - - /* create a new cookie_struct and fill it in */ - new_cookie = PR_NEW(cookie_CookieStruct); - if (!new_cookie) { - strm.close(); - return; - } - memset(new_cookie, 0, sizeof(cookie_CookieStruct)); - new_cookie->name = name.ToNewCString(); - new_cookie->cookie = cookie.ToNewCString(); - new_cookie->host = host.ToNewCString(); - new_cookie->path = path.ToNewCString(); - if (isDomain.EqualsWithConversion("TRUE")) { - new_cookie->isDomain = PR_TRUE; - } else { - new_cookie->isDomain = PR_FALSE; - } - if (secure.EqualsWithConversion("TRUE")) { - new_cookie->secure = PR_TRUE; - } else { - new_cookie->secure = PR_FALSE; - } - char * expiresCString = expires.ToNewCString(); - new_cookie->expires = strtoul(expiresCString, nsnull, 10); - nsCRT::free(expiresCString); - - /* start new cookie list if one does not already exist */ - if (!cookie_cookieList) { - cookie_cookieList = new nsVoidArray(); - if (!cookie_cookieList) { - strm.close(); - return; - } - } - - /* add new cookie to the list so that it is before any strings of smaller length */ - new_len = PL_strlen(new_cookie->path); - for (PRInt32 i = cookie_cookieList->Count(); i > 0;) { - i--; - tmp_cookie_ptr = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(tmp_cookie_ptr, "corrupt cookie list"); - if (new_len <= PL_strlen(tmp_cookie_ptr->path)) { - cookie_cookieList->InsertElementAt(new_cookie, i); - added_to_list = PR_TRUE; - break; - } - } - - /* no shorter strings found in list so add new cookie at end */ - if (!added_to_list) { - cookie_cookieList->AppendElement(new_cookie); - } - } - - strm.close(); - cookie_cookiesChanged = PR_FALSE; - return; -} - - -PUBLIC int -COOKIE_ReadCookies() -{ - if (cookie_cookieList || cookie_permissionList) - NS_WARNING("We are reading the cookies when we already have some. Probably bad"); - - cookie_Load(); - permission_Load(); - return 0; -} - -PRIVATE PRBool -CookieCompare (cookie_CookieStruct * cookie1, cookie_CookieStruct * cookie2) { - char * host1 = cookie1->host; - char * host2 = cookie2->host; - - /* get rid of leading period on host name, if any */ - if (*host1 == '.') { - host1++; - } - if (*host2 == '.') { - host2++; - } - - /* make decision based on host name if they are unequal */ - if (PL_strcmp (host1, host2) < 0) { - return -1; - } - if (PL_strcmp (host1, host2) > 0) { - return 1; - } - - /* if host names are equal, make decision based on cookie name if they are unequal */ - if (PL_strcmp (cookie1->name, cookie2->name) < 0) { - return -1; - } - if (PL_strcmp (cookie1->name, cookie2->name) > 0) { - return 1; - } - - - /* if host and cookie names are equal, make decision based on path */ - /* It may seem like this should never happen but it does. - * Go to groups.aol.com and you will get two cookies with - * identical host and cookie names but different paths - */ - return (PL_strcmp (cookie1->path, cookie2->path)); -} - -/* - * find the next cookie that is alphabetically after the specified cookie - * ordering is based on hostname and the cookie name - * if specified cookie is NULL, find the first cookie alphabetically - */ -PRIVATE cookie_CookieStruct * -NextCookieAfter(cookie_CookieStruct * cookie, int * cookieNum) { - cookie_CookieStruct *cookie_ptr; - cookie_CookieStruct *lowestCookie = NULL; - - if (!cookie_cookieList) return NULL; - - for (PRInt32 i = cookie_cookieList->Count(); i > 0;) { - i--; - cookie_ptr = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(i)); - NS_ASSERTION(cookie_ptr, "corrupt cookie list"); - if (!cookie || (CookieCompare(cookie_ptr, cookie) > 0)) { - if (!lowestCookie || (CookieCompare(cookie_ptr, lowestCookie) < 0)) { - lowestCookie = cookie_ptr; - *cookieNum = i; - } - } - } - - return lowestCookie; -} - -/* - * return a string that has each " of the argument sting - * replaced with \" so it can be used inside a quoted string - */ -PRIVATE char* -cookie_FixQuoted(char* s) { - char * result; - int count = PL_strlen(s); - char *quote = s; - unsigned int i, j; - while ((quote = PL_strchr(quote, '"'))) { - count++; - quote++; - } - result = (char*)PR_Malloc(count + 1); - for (i=0, j=0; i= 0, "bad data"); - if (start < 0) { - return nsCAutoString().ToNewCString(); - } - start += PL_strlen(name); /* get passed the |name| part */ - length = results.FindChar('|', PR_FALSE,start) - start; - results.Mid(value, start, length); - return value.ToNewCString(); -} - -PUBLIC void -COOKIE_CookieViewerReturn(nsAutoString results) { - cookie_CookieStruct * cookie; - PRInt32 count = 0; - - /* step through all cookies and delete those that are in the sequence */ - char * gone = cookie_FindValueInArgs(results, "|goneC|"); - char * block = cookie_FindValueInArgs(results, "|block|"); - if (cookie_cookieList) { - count = cookie_cookieList->Count(); - while (count>0) { - count--; - cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_cookieList->ElementAt(count)); - NS_ASSERTION(cookie, "corrupt cookie list"); - if (cookie_InSequence(gone, count)) { - if (block[0] == 't' && cookie->host) { - char * hostname = nsnull; - char * hostnameAfterDot = cookie->host; - while (*hostnameAfterDot == '.') { - hostnameAfterDot++; - } - StrAllocCopy(hostname, hostnameAfterDot); - if (hostname) { - permission_Add(hostname, PR_FALSE, COOKIEPERMISSION, PR_TRUE); - } - } - cookie_cookieList->RemoveElementAt(count); - deleteCookie((void*)cookie, nsnull); - cookie_cookiesChanged = PR_TRUE; - } - } - } - cookie_Save(); - nsCRT::free(gone); - nsCRT::free(block); - - /* step through all permissions and delete those that are in the sequence */ - for (PRInt32 type = 0; type < NUMBER_OF_PERMISSIONS; type++) { - switch (type) { - case COOKIEPERMISSION: - gone = cookie_FindValueInArgs(results, "|goneP|"); - break; - case IMAGEPERMISSION: - gone = cookie_FindValueInArgs(results, "|goneI|"); - break; - } - if (cookie_permissionList) { - count = cookie_permissionList->Count(); - while (count>0) { - count--; - if (cookie_InSequence(gone, count)) { - permission_Free(count, type, PR_FALSE); - cookie_permissionsChanged = PR_TRUE; - } - } - } - permission_Save(); - nsCRT::free(gone); - } -} - -#define BREAK '\001' - -PUBLIC void -COOKIE_GetCookieListForViewer(nsString& aCookieList) { - int cookieNum = 0; - cookie_CookieStruct * cookie; - - - /* Get rid of any expired cookies now so user doesn't - * think/see that we're keeping cookies in memory. - */ - cookie_RemoveExpiredCookies(); - - /* generate the list of cookies in alphabetical order */ - cookie = NULL; - while ((cookie = NextCookieAfter(cookie, &cookieNum))) { - char *fixed_name = cookie_FixQuoted(cookie->name); - char *fixed_value = cookie_FixQuoted(cookie->cookie); - char *fixed_domain_or_host = cookie_FixQuoted(cookie->host); - char *fixed_path = cookie_FixQuoted(cookie->path); - PRUnichar * Domain = cookie_Localize("Domain"); - PRUnichar * Host = cookie_Localize("Host"); - PRUnichar * Yes = cookie_Localize("Yes"); - PRUnichar * No = cookie_Localize("No"); - PRUnichar * AtEnd = cookie_Localize("AtEndOfSession"); - - aCookieList.AppendWithConversion(BREAK); - aCookieList.AppendInt(cookieNum); - aCookieList.AppendWithConversion(BREAK); - aCookieList.AppendWithConversion(fixed_name); - aCookieList.AppendWithConversion(BREAK); - aCookieList.AppendWithConversion(fixed_value); - aCookieList.AppendWithConversion(BREAK); - aCookieList.Append(cookie->isDomain ? Domain : Host); - aCookieList.AppendWithConversion(BREAK); - aCookieList.AppendWithConversion(fixed_domain_or_host); - aCookieList.AppendWithConversion(BREAK); - aCookieList.AppendWithConversion(fixed_path); - aCookieList.AppendWithConversion(BREAK); - aCookieList.Append(cookie->secure ? Yes : No); - aCookieList.AppendWithConversion(BREAK); - if (cookie->expires) { - /* - * Cookie expiration times on mac will not be decoded correctly because - * they were based on get_current_time() instead of time(NULL) -- see comments in - * get_current_time. So we need to adjust for that now in order for the - * display of the expiration time to be correct - */ - time_t expires; - expires = cookie->expires + (time(NULL) - get_current_time()); - nsString expireString; expireString.AssignWithConversion(ctime(&(expires))); - aCookieList.Append(expireString); - } else { - aCookieList.Append(AtEnd); - } - - PR_FREEIF(fixed_name); - PR_FREEIF(fixed_value); - PR_FREEIF(fixed_domain_or_host); - PR_FREEIF(fixed_path); - Recycle(Domain); - Recycle(Host); - Recycle(Yes); - Recycle(No); - Recycle(AtEnd); - } -} - -PUBLIC void -COOKIE_GetPermissionListForViewer(nsString& aPermissionList, PRInt32 type) { - - int permissionNum = 0; - permission_HostStruct * hostStruct; - permission_TypeStruct * typeStruct; - - if (cookie_permissionList == nsnull) { - return; - } - - aPermissionList.SetLength(0); - PRInt32 count = cookie_permissionList->Count(); - for (PRInt32 i = 0; i < count; ++i) { - hostStruct = NS_STATIC_CAST(permission_HostStruct*, cookie_permissionList->ElementAt(i)); - if (hostStruct) { - PRInt32 count2 = hostStruct->permissionList->Count(); - for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); - if (typeStruct->type == type) { - aPermissionList.AppendWithConversion(BREAK); - aPermissionList.AppendInt(permissionNum); - aPermissionList.AppendWithConversion(BREAK); - aPermissionList.AppendWithConversion((typeStruct->permission) ? '+' : '-'); - aPermissionList.AppendWithConversion(hostStruct->host); - permissionNum++; - } - } - } - } -} - -PUBLIC void -Image_Block(nsString imageURL) { - if (imageURL.Length() == 0) { - return; - } - char * imageURLCString = imageURL.ToNewCString(); - char *host = cookie_ParseURL(imageURLCString, GET_HOST_PART); - Recycle(imageURLCString); - char * hostname = nsnull; - StrAllocCopy(hostname, host); - Recycle(host); - permission_Add(hostname, PR_FALSE, IMAGEPERMISSION, PR_TRUE); -} - -PUBLIC void -Permission_Add(nsString& objectURL, PRBool permission, PRInt32 type) { - if (objectURL.IsEmpty()) { - return; - } - char * objectURLCString = objectURL.ToNewCString(); - char *host = cookie_ParseURL(objectURLCString, GET_HOST_PART); - Recycle(objectURLCString); - - /* - * if permission is false, it will be added to the permission list - * if permission is true, any false permissions will be removed rather than a - * true permission being added - */ - if (permission) { - char * hostPtr = host; - while (PR_TRUE) { - permission_Unblock(hostPtr, type); - hostPtr = PL_strchr(hostPtr, '.'); - if (!hostPtr) { - break; - } - hostPtr++; /* get passed the period */ - } - Recycle(host); - return; - } - permission_Add(host, permission, type, PR_TRUE); -} - -MODULE_PRIVATE time_t -cookie_ParseDate(char *date_string) { - -#ifndef USE_OLD_TIME_FUNC - - PRTime prdate; - time_t date = 0; - // TRACEMSG(("Parsing date string: %s\n",date_string)); - - /* try using PR_ParseTimeString instead */ - if(PR_ParseTimeString(date_string, PR_TRUE, &prdate) == PR_SUCCESS) { - PRInt64 r, u; - LL_I2L(u, PR_USEC_PER_SEC); - LL_DIV(r, prdate, u); - LL_L2I(date, r); - if (date < 0) { - date = 0; - } - // TRACEMSG(("Parsed date as GMT: %s\n", asctime(gmtime(&date)))); - // TRACEMSG(("Parsed date as local: %s\n", ctime(&date))); - } else { - // TRACEMSG(("Could not parse date")); - } - return (date); - -#else - - struct tm time_info; /* Points to static tm structure */ - char *ip; - char mname[256]; - time_t rv; - // TRACEMSG(("Parsing date string: %s\n",date_string)); - memset(&time_info, 0, sizeof(struct tm)); - - /* Whatever format we're looking at, it will start with weekday. */ - /* Skip to first space. */ - if(!(ip = PL_strchr(date_string,' '))) { - return 0; - } else { - while(COOKIE_IS_SPACE(*ip)) { - ++ip; - } - } - /* make sure that the date is less than 256. That will keep name from ever overflowing */ - if(255 < PL_strlen(ip)) { - return(0); - } - if(isalpha(*ip)) { - /* ctime */ - sscanf(ip, (strstr(ip, "DST") ? "%s %d %d:%d:%d %*s %d" : "%s %d %d:%d:%d %d"), - mname, &time_info.tm_mday, &time_info.tm_hour, &time_info.tm_min, - &time_info.tm_sec, &time_info.tm_year); - time_info.tm_year -= 1900; - } else if(ip[2] == '-') { - /* RFC 850 (normal HTTP) */ - char t[256]; - sscanf(ip,"%s %d:%d:%d", t, &time_info.tm_hour, &time_info.tm_min, &time_info.tm_sec); - t[2] = '\0'; - time_info.tm_mday = atoi(t); - t[6] = '\0'; - PL_strcpy(mname,&t[3]); - time_info.tm_year = atoi(&t[7]); - /* Prevent wraparound from ambiguity */ - if(time_info.tm_year < 70) { - time_info.tm_year += 100; - } else if(time_info.tm_year > 1900) { - time_info.tm_year -= 1900; - } - } else { - /* RFC 822 */ - sscanf(ip,"%d %s %d %d:%d:%d",&time_info.tm_mday, mname, &time_info.tm_year, - &time_info.tm_hour, &time_info.tm_min, &time_info.tm_sec); - /* since tm_year is years since 1900 and the year we parsed - * is absolute, we need to subtract 1900 years from it - */ - time_info.tm_year -= 1900; - } - time_info.tm_mon = NET_MonthNo(mname); - if(time_info.tm_mon == -1) { /* check for error */ - return(0); - } - // TRACEMSG(("Parsed date as: %s\n", asctime(&time_info))); - rv = mktime(&time_info); - if(time_info.tm_isdst) { - rv -= 3600; - } - if(rv == -1) { - // TRACEMSG(("mktime was unable to resolve date/time: %s\n", asctime(&time_info))); - return(0); - } else { - // TRACEMSG(("Parsed date %s\n", asctime(&time_info))); - // TRACEMSG(("\tas %s\n", ctime(&rv))); - return(rv); - } - -#endif -} - -/* Also skip '>' as part of host name */ -MODULE_PRIVATE char * -cookie_ParseURL (const char *url, int parts_requested) { - char *rv=0,*colon, *slash, *ques_mark, *hash_mark; - char *atSign, *host, *passwordColon, *gtThan; - assert(url); - if(!url) { - return(StrAllocCat(rv, "")); - } - colon = PL_strchr(url, ':'); /* returns a const char */ - /* Get the protocol part, not including anything beyond the colon */ - if (parts_requested & GET_PROTOCOL_PART) { - if(colon) { - char val = *(colon+1); - *(colon+1) = '\0'; - StrAllocCopy(rv, url); - *(colon+1) = val; - /* If the user wants more url info, tack on extra slashes. */ - if( (parts_requested & GET_HOST_PART) - || (parts_requested & GET_USERNAME_PART) - || (parts_requested & GET_PASSWORD_PART)) { - if( *(colon+1) == '/' && *(colon+2) == '/') { - StrAllocCat(rv, "//"); - } - /* If there's a third slash consider it file:/// and tack on the last slash. */ - if( *(colon+3) == '/' ) { - StrAllocCat(rv, "/"); - } - } - } - } - - /* Get the username if one exists */ - if (parts_requested & GET_USERNAME_PART) { - if (colon && (*(colon+1) == '/') && (*(colon+2) == '/') && (*(colon+3) != '\0')) { - if ( (slash = PL_strchr(colon+3, '/')) != NULL) { - *slash = '\0'; - } - if ( (atSign = PL_strchr(colon+3, '@')) != NULL) { - *atSign = '\0'; - if ( (passwordColon = PL_strchr(colon+3, ':')) != NULL) { - *passwordColon = '\0'; - } - StrAllocCat(rv, colon+3); - - /* Get the password if one exists */ - if (parts_requested & GET_PASSWORD_PART) { - if (passwordColon) { - StrAllocCat(rv, ":"); - StrAllocCat(rv, passwordColon+1); - } - } - if (parts_requested & GET_HOST_PART) { - StrAllocCat(rv, "@"); - } - if (passwordColon) { - *passwordColon = ':'; - } - *atSign = '@'; - } - if (slash) { - *slash = '/'; - } - } - } - - /* Get the host part */ - if (parts_requested & GET_HOST_PART) { - if(colon) { - if(*(colon+1) == '/' && *(colon+2) == '/') { - slash = PL_strchr(colon+3, '/'); - if(slash) { - *slash = '\0'; - } - if( (atSign = PL_strchr(colon+3, '@')) != NULL) { - host = atSign+1; - } else { - host = colon+3; - } - ques_mark = PL_strchr(host, '?'); - if(ques_mark) { - *ques_mark = '\0'; - } - gtThan = PL_strchr(host, '>'); - if (gtThan) { - *gtThan = '\0'; - } - - /* - * Protect systems whose header files forgot to let the client know when - * gethostbyname would trash their stack. - */ -#ifndef MAX_HOST_NAME_LEN -#ifdef XP_OS2 -#error Managed to get into cookie_ParseURL without defining MAX_HOST_NAME_LEN !!! -#endif -#endif - /* limit hostnames to within MAX_HOST_NAME_LEN characters to keep from crashing */ - if(PL_strlen(host) > MAX_HOST_NAME_LEN) { - char * cp; - char old_char; - cp = host+MAX_HOST_NAME_LEN; - old_char = *cp; - *cp = '\0'; - StrAllocCat(rv, host); - *cp = old_char; - } else { - StrAllocCat(rv, host); - } - if(slash) { - *slash = '/'; - } - if(ques_mark) { - *ques_mark = '?'; - } - if (gtThan) { - *gtThan = '>'; - } - } - } - } - - /* Get the path part */ - if (parts_requested & GET_PATH_PART) { - if(colon) { - if(*(colon+1) == '/' && *(colon+2) == '/') { - /* skip host part */ - slash = PL_strchr(colon+3, '/'); - } else { - /* path is right after the colon */ - slash = colon+1; - } - if(slash) { - ques_mark = PL_strchr(slash, '?'); - hash_mark = PL_strchr(slash, '#'); - if(ques_mark) { - *ques_mark = '\0'; - } - if(hash_mark) { - *hash_mark = '\0'; - } - StrAllocCat(rv, slash); - if(ques_mark) { - *ques_mark = '?'; - } - if(hash_mark) { - *hash_mark = '#'; - } - } - } - } - - if(parts_requested & GET_HASH_PART) { - hash_mark = PL_strchr(url, '#'); /* returns a const char * */ - if(hash_mark) { - ques_mark = PL_strchr(hash_mark, '?'); - if(ques_mark) { - *ques_mark = '\0'; - } - StrAllocCat(rv, hash_mark); - if(ques_mark) { - *ques_mark = '?'; - } - } - } - - if(parts_requested & GET_SEARCH_PART) { - ques_mark = PL_strchr(url, '?'); /* returns a const char * */ - if(ques_mark) { - hash_mark = PL_strchr(ques_mark, '#'); - if(hash_mark) { - *hash_mark = '\0'; - } - StrAllocCat(rv, ques_mark); - if(hash_mark) { - *hash_mark = '#'; - } - } - } - - /* copy in a null string if nothing was copied in */ - if(!rv) { - StrAllocCopy(rv, ""); - } - /* XP_OS2_FIX IBM-MAS: long URLS blowout tracemsg buffer, set max to 1900 chars */ - // TRACEMSG(("mkparse: ParseURL: parsed - %-.1900s",rv)); - return rv; +NS_IMETHODIMP nsCookie::GetExpires(PRUint64 *aExpires) { + *aExpires = cookieExpires; + return NS_OK; } diff --git a/mozilla/extensions/cookie/nsCookie.h b/mozilla/extensions/cookie/nsCookie.h index 672b2c61c8f..a7acfe512ca 100644 --- a/mozilla/extensions/cookie/nsCookie.h +++ b/mozilla/extensions/cookie/nsCookie.h @@ -1,5 +1,5 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -20,42 +20,44 @@ * Contributor(s): */ -#ifndef COOKIES_H -#define COOKIES_H +#ifndef nsCookie_h__ +#define nsCookie_h__ -#include "nscore.h" -#include "nsError.h" -#include "nsString.h" +#include "nsICookie.h" +#include "nsWeakReference.h" -#ifdef _IMPL_NS_COOKIE -#define NS_COOKIE NS_EXPORT -#else -#define NS_COOKIE NS_IMPORT -#endif +//////////////////////////////////////////////////////////////////////////////// +class nsCookie : public nsICookie, + public nsSupportsWeakReference { +public: -typedef enum { - COOKIE_Accept, - COOKIE_DontAcceptForeign, - COOKIE_DontUse -} COOKIE_BehaviorEnum; + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSICOOKIE -class nsIPrompt; + // Note: following constructor takes ownership of the four strings (name, value + // host, and path) passed to it so the caller of the constructor must not + // free them + nsCookie + (char * name, + char * value, + PRBool isDomain, + char * host, + char * path, + PRBool isSecure, + PRUint64 expires); + nsCookie(); + virtual ~nsCookie(void); + +protected: + char * cookieName; + char * cookieValue; + PRBool cookieIsDomain; + char * cookieHost; + char * cookiePath; + PRBool cookieIsSecure; + PRUint64 cookieExpires; +}; -extern char * COOKIE_GetCookie(char * address); -extern char * COOKIE_GetCookieFromHttp(char * address, char * firstAddress); -extern void COOKIE_SetCookieString(char * cur_url, nsIPrompt *aPrompter, char * set_cookie_header); -extern int COOKIE_ReadCookies(); -extern void COOKIE_RegisterCookiePrefCallbacks(void); -extern void COOKIE_RemoveAllCookies(void); -extern void COOKIE_DeletePersistentUserData(void); -extern void COOKIE_SetCookieStringFromHttp(char * cur_url, char * first_url, nsIPrompt *aPRompter, char * set_cookie_header, char * server_date); -extern void COOKIE_GetCookieListForViewer (nsString& aCookieList); -extern void COOKIE_GetPermissionListForViewer (nsString& aPermissionList, PRInt32 type); -extern void COOKIE_CookieViewerReturn(nsAutoString results); -extern COOKIE_BehaviorEnum COOKIE_GetBehaviorPref(); -extern void Image_Block(nsString imageURL); -extern void Permission_Add(nsString& imageURL, PRBool permission, PRInt32 type); -extern nsresult Image_CheckForPermission - (char * hostname, char * firstHostname, PRBool &permission); -#endif /* COOKIES_H */ +#endif /* nsCookie_h__ */ diff --git a/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp b/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp index 493708417b6..815892a0a67 100644 --- a/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp +++ b/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp @@ -24,6 +24,7 @@ #include #endif +#include "nsCookieService.h" /* don't remove -- needed for mac build */ #include "nsCookieHTTPNotify.h" #include "nsIGenericFactory.h" #include "nsIHTTPChannel.h" @@ -64,7 +65,7 @@ NS_METHOD nsCookieHTTPNotify::RegisterProc(nsIComponentManager *aCompMgr, { // Register ourselves into the NS_CATEGORY_HTTP_STARTUP nsresult rv; - nsCOMPtr catman = do_GetService("@mozilla.org/categorymanager;1", &rv); + nsCOMPtr catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsXPIDLCString prevEntry; @@ -81,7 +82,7 @@ NS_METHOD nsCookieHTTPNotify::UnregisterProc(nsIComponentManager *aCompMgr, const nsModuleComponentInfo *info) { nsresult rv; - nsCOMPtr catman = do_GetService("@mozilla.org/categorymanager;1", &rv); + nsCOMPtr catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsXPIDLCString prevEntry; @@ -182,19 +183,14 @@ nsCookieHTTPNotify::ModifyRequest(nsISupports *aContext) rv = SetupCookieService(); if (NS_FAILED(rv)) return rv; - nsAutoString cookie; - rv = mCookieService->GetCookieStringFromHTTP(pURL, pFirstURL, cookie); + char * cookie; + rv = mCookieService->GetCookieStringFromHttp(pURL, pFirstURL, &cookie); if (NS_FAILED(rv)) return rv; // Set the cookie into the request headers - // XXX useless convertion from nsString to char * again - const char *cookieRaw = cookie.ToNewCString(); - if (!cookieRaw) return NS_ERROR_OUT_OF_MEMORY; - - // only set a cookie header if we have a value to send - if (*cookieRaw) - rv = pHTTPConnection->SetRequestHeader(mCookieHeader, cookieRaw); - nsMemory::Free((void *)cookieRaw); + if (cookie && *cookie) + rv = pHTTPConnection->SetRequestHeader(mCookieHeader, cookie); + nsMemory::Free((void *)cookie); return rv; } diff --git a/mozilla/extensions/cookie/nsCookieManager.cpp b/mozilla/extensions/cookie/nsCookieManager.cpp new file mode 100644 index 00000000000..871501aabaf --- /dev/null +++ b/mozilla/extensions/cookie/nsCookieManager.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsIServiceManager.h" +#include "nsCookieManager.h" +#include "nsCRT.h" +#include "nsCookies.h" +#include "nsCookie.h" +#include "nsIGenericFactory.h" +#include "nsXPIDLString.h" +#include "nsIScriptGlobalObject.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsCookieEnumerator : public nsISimpleEnumerator +{ + public: + + NS_DECL_ISUPPORTS + + nsCookieEnumerator() : mCookieCount(0) + { + NS_INIT_REFCNT(); + } + + NS_IMETHOD HasMoreElements(PRBool *result) + { + *result = COOKIE_Count() > mCookieCount; + return NS_OK; + } + + NS_IMETHOD GetNext(nsISupports **result) + { + char *name; + char *value; + PRBool isDomain; + char * host; + char * path; + PRBool isSecure; + PRUint64 expires; + (void) COOKIE_Enumerate + (mCookieCount++, &name, &value, &isDomain, &host, &path, &isSecure, &expires); + nsICookie *cookie = + new nsCookie(name, value, isDomain, host, path, isSecure, expires); + *result = cookie; + NS_ADDREF(*result); + return NS_OK; + } + + virtual ~nsCookieEnumerator() + { + } + + protected: + PRInt32 mCookieCount; +}; + +NS_IMPL_ISUPPORTS1(nsCookieEnumerator, nsISimpleEnumerator); + + +//////////////////////////////////////////////////////////////////////////////// +// nsCookieManager Implementation + +NS_IMPL_ISUPPORTS2(nsCookieManager, nsICookieManager, nsISupportsWeakReference); + +nsCookieManager::nsCookieManager() +{ + NS_INIT_REFCNT(); +} + +nsCookieManager::~nsCookieManager(void) +{ +} + +nsresult nsCookieManager::Init() +{ + COOKIE_Read(); + return NS_OK; +} + +NS_IMETHODIMP nsCookieManager::RemoveAll(void) { + ::COOKIE_RemoveAll(); + return NS_OK; +} + +NS_IMETHODIMP nsCookieManager::GetEnumerator(nsISimpleEnumerator * *entries) +{ + *entries = nsnull; + + nsCookieEnumerator* cookieEnum = new nsCookieEnumerator(); + if (cookieEnum == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(cookieEnum); + *entries = cookieEnum; + return NS_OK; +} + +NS_IMETHODIMP nsCookieManager::Remove + (const char* host, const char* name, const char* path, const PRBool permanent) { + ::COOKIE_Remove(host, name, path, permanent); + return NS_OK; +} diff --git a/mozilla/extensions/cookie/nsCookieManager.h b/mozilla/extensions/cookie/nsCookieManager.h new file mode 100644 index 00000000000..bdd48d86de6 --- /dev/null +++ b/mozilla/extensions/cookie/nsCookieManager.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsCookieManager_h__ +#define nsCookieManager_h__ + +#include "nsICookieManager.h" +#include "nsWeakReference.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsCookieManager : public nsICookieManager, + public nsSupportsWeakReference { +public: + + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSICOOKIEMANAGER + + nsCookieManager(); + virtual ~nsCookieManager(void); + nsresult Init(); + +}; + +#endif /* nsCookieManager_h__ */ diff --git a/mozilla/extensions/cookie/nsCookieService.cpp b/mozilla/extensions/cookie/nsCookieService.cpp index f0c83e18f2d..1fba8896f42 100644 --- a/mozilla/extensions/cookie/nsCookieService.cpp +++ b/mozilla/extensions/cookie/nsCookieService.cpp @@ -24,13 +24,17 @@ #include "nsCookieService.h" #include "nsCookieHTTPNotify.h" #include "nsCRT.h" -#include "nsCookie.h" +#include "nsCookies.h" #include "nsIGenericFactory.h" #include "nsXPIDLString.h" #include "nsIScriptGlobalObject.h" #include "nsIDOMWindowInternal.h" #include "nsIPrompt.h" #include "nsIObserverService.h" +#include "nsIDocumentLoader.h" +#include "nsCURILoader.h" + +static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID); //////////////////////////////////////////////////////////////////////////////// @@ -38,101 +42,114 @@ //////////////////////////////////////////////////////////////////////////////// // nsCookieService Implementation -NS_IMPL_ISUPPORTS3(nsCookieService, nsICookieService, nsIObserver, nsISupportsWeakReference); +NS_IMPL_ISUPPORTS4(nsCookieService, nsICookieService, + nsIObserver, nsIDocumentLoaderObserver, nsISupportsWeakReference); nsCookieService::nsCookieService() -: mInitted(PR_FALSE) { NS_INIT_REFCNT(); } nsCookieService::~nsCookieService(void) { - COOKIE_RemoveAllCookies(); + COOKIE_Write(); /* in case any deleted cookies didn't get removed from file yet */ + COOKIE_RemoveAll(); } nsresult nsCookieService::Init() { - // make sure we're not initted twice, because this has the serious - // consequence of reading the cookies file twice - if (mInitted) - { - NS_ASSERTION(0, "Baking the cookies twice. Doesn't that make them biscuits?"); - return NS_ERROR_ALREADY_INITIALIZED; - } - - COOKIE_RegisterCookiePrefCallbacks(); - COOKIE_ReadCookies(); - + COOKIE_RegisterPrefCallbacks(); + COOKIE_Read(); + nsresult rv; NS_WITH_SERVICE(nsIObserverService, observerService, NS_OBSERVERSERVICE_CONTRACTID, &rv); if (observerService) { observerService->AddObserver(this, NS_LITERAL_STRING("profile-before-change").get()); observerService->AddObserver(this, NS_LITERAL_STRING("profile-do-change").get()); } - - mInitted = PR_TRUE; + + // Register as an observer for the document loader + NS_WITH_SERVICE(nsIDocumentLoader, docLoaderService, kDocLoaderServiceCID, &rv) + if (NS_SUCCEEDED(rv) && docLoaderService) { + docLoaderService->AddObserver((nsIDocumentLoaderObserver*)this); + } else { + NS_ASSERTION(PR_FALSE, "Could not get nsIDocumentLoader"); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::OnStartDocumentLoad(nsIDocumentLoader* aLoader, nsIURI* aURL, const char* aCommand) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::OnEndDocumentLoad(nsIDocumentLoader* aLoader, nsIRequest *request, nsresult aStatus) +{ + COOKIE_Write(); + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::OnStartURLLoad + (nsIDocumentLoader* loader, nsIRequest *request) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::OnProgressURLLoad + (nsIDocumentLoader* loader, nsIRequest *request, PRUint32 aProgress, PRUint32 aProgressMax) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::OnStatusURLLoad + (nsIDocumentLoader* loader, nsIRequest *request, nsString& aMsg) +{ return NS_OK; } NS_IMETHODIMP -nsCookieService::GetCookieString(nsIURI *aURL, nsString& aCookie) { +nsCookieService::OnEndURLLoad + (nsIDocumentLoader* loader, nsIRequest *request, nsresult aStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsCookieService::GetCookieString(nsIURI *aURL, char ** aCookie) { nsXPIDLCString spec; nsresult rv = aURL->GetSpec(getter_Copies(spec)); if (NS_FAILED(rv)) return rv; - char *cookie = COOKIE_GetCookie((char *)(const char *)spec); - if (nsnull != cookie) { - aCookie.AssignWithConversion(cookie); - nsCRT::free(cookie); - } else { - // No Cookie isn't an error condition. - aCookie.Truncate(); - } + *aCookie = COOKIE_GetCookie((char *)(const char *)spec); return NS_OK; } NS_IMETHODIMP -nsCookieService::GetCookieStringFromHTTP(nsIURI *aURL, nsIURI *aFirstURL, nsString& aCookie) { +nsCookieService::GetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, char ** aCookie) { nsXPIDLCString spec; nsresult rv = aURL->GetSpec(getter_Copies(spec)); if (NS_FAILED(rv)) return rv; nsXPIDLCString firstSpec; rv = aFirstURL->GetSpec(getter_Copies(firstSpec)); if (NS_FAILED(rv)) return rv; - char *cookie = COOKIE_GetCookieFromHttp((char *)(const char *)spec, (char *)(const char *)firstSpec); - if (nsnull != cookie) { - aCookie.AssignWithConversion(cookie); - nsCRT::free(cookie); - } else { - // No Cookie isn't an error condition. - aCookie.Truncate(); - } + *aCookie = COOKIE_GetCookieFromHttp((char *)(const char *)spec, (char *)(const char *)firstSpec); return NS_OK; } NS_IMETHODIMP -nsCookieService::SetCookieString(nsIURI *aURL, nsIDocument* aDoc, const nsString& aCookie) { +nsCookieService::SetCookieString(nsIURI *aURL, nsIPrompt* aPrompt, const char * aCookie) { char *spec = NULL; nsresult result = aURL->GetSpec(&spec); NS_ASSERTION(result == NS_OK, "deal with this"); - char *cookie = aCookie.ToNewCString(); - nsCOMPtr globalObj; - nsCOMPtr prompt; - if (aDoc) { - aDoc->GetScriptGlobalObject(getter_AddRefs(globalObj)); - if (globalObj) { - nsCOMPtr window (do_QueryInterface(globalObj)); - if (window) { - window->GetPrompter(getter_AddRefs(prompt)); - } - } - } - - COOKIE_SetCookieString((char *)spec, prompt, cookie); + COOKIE_SetCookieString(spec, aPrompt, aCookie); nsCRT::free(spec); - nsCRT::free(cookie); return NS_OK; } @@ -142,114 +159,38 @@ nsCookieService::SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, nsIPro nsresult rv = aURL->GetSpec(&spec); if (NS_FAILED(rv)) return rv; char *firstSpec = NULL; - rv = aFirstURL->GetSpec(&firstSpec); if (NS_FAILED(rv)) return rv; + rv = aFirstURL->GetSpec(&firstSpec); + if (NS_FAILED(rv)) return rv; COOKIE_SetCookieStringFromHttp(spec, firstSpec, aPrompter, (char *)aCookie, (char *)aExpires); nsCRT::free(spec); nsCRT::free(firstSpec); return NS_OK; } -NS_IMETHODIMP nsCookieService::Cookie_RemoveAllCookies(void) { - ::COOKIE_RemoveAllCookies(); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Cookie_CookieViewerReturn(nsAutoString results) { - ::COOKIE_CookieViewerReturn(results); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Cookie_GetCookieListForViewer(nsString& aCookieList) { - ::COOKIE_GetCookieListForViewer(aCookieList); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Cookie_GetPermissionListForViewer - (nsString& aPermissionList, PRInt32 type) { - ::COOKIE_GetPermissionListForViewer(aPermissionList, type); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Image_Block(nsAutoString imageURL) { - ::Image_Block(imageURL); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Permission_Add - (nsString imageURL, PRBool permission, PRInt32 type) { - ::Permission_Add(imageURL, permission, type); - return NS_OK; -} - -NS_IMETHODIMP nsCookieService::Image_CheckForPermission - (char * hostname, char * firstHostname, PRBool &permission) { - return ::Image_CheckForPermission(hostname, firstHostname, permission); -} - - -NS_IMETHODIMP nsCookieService::CookieEnabled(PRBool* aEnabled) -{ - *aEnabled = (COOKIE_GetBehaviorPref() != COOKIE_DontUse); - return NS_OK; -} - - NS_IMETHODIMP nsCookieService::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData) { nsresult rv = NS_OK; - + if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-before-change").get())) { // The profile is about to change. // Dump current cookies. This will be done by calling - // COOKIE_RemoveAllCookies which clears the memory-resident + // COOKIE_RemoveAll which clears the memory-resident // cookie table. The reason the cookie file does not // need to be updated is because the file was updated every time // the memory-resident table changed (i.e., whenever a new cookie // was accepted). If this condition ever changes, the cookie // file would need to be updated here. - COOKIE_RemoveAllCookies(); + COOKIE_RemoveAll(); if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) COOKIE_DeletePersistentUserData(); } else if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-do-change").get())) { // The profile has aleady changed. // Now just read them from the new profile location. - COOKIE_ReadCookies(); + COOKIE_Read(); } return rv; } - - -//---------------------------------------------------------------------- - -//////////////////////////////////////////////////////////////////////// -// Define the contructor function for the objects - -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieService, Init) -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieHTTPNotify, Init) - -//////////////////////////////////////////////////////////////////////// -// Define a table of CIDs implemented by this module along with other -// information like the function to create an instance, contractid, and -// class name. -// -static nsModuleComponentInfo components[] = { - { "CookieService", NS_COOKIESERVICE_CID, - NS_COOKIESERVICE_CONTRACTID, nsCookieServiceConstructor, }, // XXX Singleton - { NS_COOKIEHTTPNOTIFY_CLASSNAME, - NS_COOKIEHTTPNOTIFY_CID, - NS_COOKIEHTTPNOTIFY_CONTRACTID, - nsCookieHTTPNotifyConstructor, - nsCookieHTTPNotify::RegisterProc, - nsCookieHTTPNotify::UnregisterProc - }, -}; - -//////////////////////////////////////////////////////////////////////// -// Implement the NSGetModule() exported function for your module -// and the entire implementation of the module object. -// -NS_IMPL_NSGETMODULE("nsCookieModule", components) diff --git a/mozilla/extensions/cookie/nsCookieService.h b/mozilla/extensions/cookie/nsCookieService.h index 0767f3973f3..57f9dc31458 100644 --- a/mozilla/extensions/cookie/nsCookieService.h +++ b/mozilla/extensions/cookie/nsCookieService.h @@ -25,39 +25,27 @@ #include "nsICookieService.h" #include "nsIObserver.h" +#include "nsIDocumentLoaderObserver.h" #include "nsWeakReference.h" //////////////////////////////////////////////////////////////////////////////// class nsCookieService : public nsICookieService, public nsIObserver, + public nsIDocumentLoaderObserver, public nsSupportsWeakReference { public: // nsISupports NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER - - NS_IMETHOD GetCookieString(nsIURI *aURL, nsString& aCookie); - NS_IMETHOD GetCookieStringFromHTTP(nsIURI *aURL, nsIURI *aFirstURL, nsString& aCookie); - NS_IMETHOD SetCookieString(nsIURI *aURL, nsIDocument* aDoc, const nsString& aCookie); - NS_IMETHOD SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, nsIPrompt *aPrompter, const char *aCookie, const char *aExpires); - NS_IMETHOD Cookie_RemoveAllCookies(void); - NS_IMETHOD Cookie_CookieViewerReturn(nsAutoString results); - NS_IMETHOD Cookie_GetCookieListForViewer(nsString& aCookieList); - NS_IMETHOD Cookie_GetPermissionListForViewer(nsString& aPermissionList, PRInt32 type); - NS_IMETHOD Image_Block(nsAutoString imageURL); - NS_IMETHOD Permission_Add(nsString imageURL, PRBool permission, PRInt32 type); - NS_IMETHOD Image_CheckForPermission - (char * hostname, char * firstHostname, PRBool &permission); - NS_IMETHOD CookieEnabled(PRBool* aEnabled); + NS_DECL_NSIDOCUMENTLOADEROBSERVER + NS_DECL_NSICOOKIESERVICE nsCookieService(); virtual ~nsCookieService(void); nsresult Init(); -protected: - PRBool mInitted; }; #endif /* nsCookieService_h__ */ diff --git a/mozilla/extensions/cookie/nsCookies.cpp b/mozilla/extensions/cookie/nsCookies.cpp new file mode 100644 index 00000000000..554e1636384 --- /dev/null +++ b/mozilla/extensions/cookie/nsCookies.cpp @@ -0,0 +1,1492 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf + * Henrik Gemal + */ + +#include "nsCookies.h" +#include "nsPermissions.h" +#include "nsUtils.h" +#include "nsIFileSpec.h" +#include "nsVoidArray.h" +#include "prprf.h" +#include "xp_core.h" +#include "prmem.h" +#include "nsXPIDLString.h" +#include "nsIPref.h" +#include "nsTextFormatter.h" +#include "nsAppDirectoryServiceDefs.h" + +#define MAX_NUMBER_OF_COOKIES 300 +#define MAX_COOKIES_PER_SERVER 20 +#define MAX_BYTES_PER_COOKIE 4096 /* must be at least 1 */ + +#define cookie_behaviorPref "network.cookie.cookieBehavior" +#define cookie_warningPref "network.cookie.warnAboutCookies" +#define cookie_strictDomainsPref "network.cookie.strictDomains" +#define cookie_lifetimePref "network.cookie.lifetimeOption" +#define cookie_lifetimeValue "network.cookie.lifetimeLimit" + +static const char *kCookiesFileName = "cookies.txt"; + +MODULE_PRIVATE time_t +cookie_ParseDate(char *date_string); + +typedef struct _cookie_CookieStruct { + char * path; + char * host; + char * name; + char * cookie; + time_t expires; + time_t lastAccessed; + PRBool isSecure; + PRBool isDomain; /* is it a domain instead of an absolute host? */ +} cookie_CookieStruct; + +typedef enum { + COOKIE_Normal, + COOKIE_Discard, + COOKIE_Trim, + COOKIE_Ask +} COOKIE_LifetimeEnum; + +PRIVATE PRBool cookie_changed = PR_FALSE; +PRIVATE PERMISSION_BehaviorEnum cookie_behavior = PERMISSION_Accept; +PRIVATE PRBool cookie_warning = PR_FALSE; +PRIVATE COOKIE_LifetimeEnum cookie_lifetimeOpt = COOKIE_Normal; +PRIVATE time_t cookie_lifetimeLimit = 90*24*60*60; + +PRIVATE nsVoidArray * cookie_list=0; + +static +time_t +get_current_time() + /* + We call this routine instead of |time()| because the latter returns + different values on the Mac than on all other platforms (i.e., based on + the Mac's 1900 epoch, vs all others 1970). We can't call |PR_Now| + directly, since the value is 64bits and too hard to manipulate. + Hence, this cross-platform convenience routine. + */ + { + PRInt64 usecPerSec; + LL_I2L(usecPerSec, 1000000L); + + PRTime now_useconds = PR_Now(); + + PRInt64 now_seconds; + LL_DIV(now_seconds, now_useconds, usecPerSec); + + time_t current_time_in_seconds; + LL_L2I(current_time_in_seconds, now_seconds); + + return current_time_in_seconds; + } + +PRBool PR_CALLBACK deleteCookie(void *aElement, void *aData) { + cookie_CookieStruct *cookie = (cookie_CookieStruct*)aElement; + PR_FREEIF(cookie->path); + PR_FREEIF(cookie->host); + PR_FREEIF(cookie->name); + PR_FREEIF(cookie->cookie); + PR_Free(cookie); + return PR_TRUE; +} + +PUBLIC void +COOKIE_RemoveAll() +{ + if (cookie_list) { + cookie_list->EnumerateBackwards(deleteCookie, nsnull); + cookie_changed = PR_TRUE; + delete cookie_list; + cookie_list = nsnull; + } +} + +PUBLIC void +COOKIE_DeletePersistentUserData(void) +{ + nsresult res; + + nsCOMPtr cookiesFile; + res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(cookiesFile)); + if (NS_SUCCEEDED(res)) { + res = cookiesFile->Append(kCookiesFileName); + if (NS_SUCCEEDED(res)) + (void) cookiesFile->Delete(PR_FALSE); + } +} + +PRIVATE void +cookie_RemoveOldestCookie(void) { + cookie_CookieStruct * cookie_s; + cookie_CookieStruct * oldest_cookie; + + if (cookie_list == nsnull) { + return; + } + + PRInt32 count = cookie_list->Count(); + if (count == 0) { + return; + } + oldest_cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(0)); + PRInt32 oldestLoc = 0; + for (PRInt32 i = 1; i < count; ++i) { + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "cookie list is corrupt"); + if(cookie_s->lastAccessed < oldest_cookie->lastAccessed) { + oldest_cookie = cookie_s; + oldestLoc = i; + } + } + if(oldest_cookie) { + cookie_list->RemoveElementAt(oldestLoc); + deleteCookie((void*)oldest_cookie, nsnull); + cookie_changed = PR_TRUE; + } + +} + +/* Remove any expired cookies from memory */ +PRIVATE void +cookie_RemoveExpiredCookies() { + cookie_CookieStruct * cookie_s; + time_t cur_time = get_current_time(); + + if (cookie_list == nsnull) { + return; + } + + for (PRInt32 i = cookie_list->Count(); i > 0;) { + i--; + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "corrupt cookie list"); + /* Don't get rid of expire time 0 because these need to last for + * the entire session. They'll get cleared on exit. */ + if( cookie_s->expires && (cookie_s->expires < cur_time) ) { + cookie_list->RemoveElementAt(i); + deleteCookie((void*)cookie_s, nsnull); + cookie_changed = PR_TRUE; + } + } +} + +/* checks to see if the maximum number of cookies per host + * is being exceeded and deletes the oldest one in that + * case + */ +PRIVATE void +cookie_CheckForMaxCookiesFromHost(const char * cur_host) { + cookie_CookieStruct * cookie_s; + cookie_CookieStruct * oldest_cookie = 0; + int cookie_count = 0; + + if (cookie_list == nsnull) { + return; + } + + PRInt32 count = cookie_list->Count(); + PRInt32 oldestLoc = -1; + for (PRInt32 i = 0; i < count; ++i) { + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "corrupt cookie list"); + if(!PL_strcasecmp(cookie_s->host, cur_host)) { + cookie_count++; + if(!oldest_cookie || oldest_cookie->lastAccessed > cookie_s->lastAccessed) { + oldest_cookie = cookie_s; + oldestLoc = i; + } + } + } + if(cookie_count >= MAX_COOKIES_PER_SERVER && oldest_cookie) { + NS_ASSERTION(oldestLoc > -1, "oldestLoc got out of sync with oldest_cookie"); + cookie_list->RemoveElementAt(oldestLoc); + deleteCookie((void*)oldest_cookie, nsnull); + cookie_changed = PR_TRUE; + } +} + + +/* search for previous exact match */ +PRIVATE cookie_CookieStruct * +cookie_CheckForPrevCookie(char * path, char * hostname, char * name) { + cookie_CookieStruct * cookie_s; + if (cookie_list == nsnull) { + return NULL; + } + + PRInt32 count = cookie_list->Count(); + for (PRInt32 i = 0; i < count; ++i) { + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "corrupt cookie list"); + if(path && hostname && cookie_s->path && cookie_s->host && cookie_s->name + && !PL_strcmp(name, cookie_s->name) && !PL_strcmp(path, cookie_s->path) + && !PL_strcasecmp(hostname, cookie_s->host)) { + return(cookie_s); + } + } + return(NULL); +} + +/* cookie utility functions */ +PRIVATE void +cookie_SetBehaviorPref(PERMISSION_BehaviorEnum x) { + cookie_behavior = x; +} + +PRIVATE void +cookie_SetWarningPref(PRBool x) { + cookie_warning = x; +} + +PRIVATE void +cookie_SetLifetimePref(COOKIE_LifetimeEnum x) { + cookie_lifetimeOpt = x; +} + +PRIVATE void +cookie_SetLifetimeLimit(PRInt32 x) { + // save limit as seconds instead of days + cookie_lifetimeLimit = x*24*60*60; +} + +PRIVATE PERMISSION_BehaviorEnum +cookie_GetBehaviorPref() { + return cookie_behavior; +} + +PRIVATE PRBool +cookie_GetWarningPref() { + return cookie_warning; +} + +PRIVATE COOKIE_LifetimeEnum +cookie_GetLifetimePref() { + return cookie_lifetimeOpt; +} + +PRIVATE time_t +cookie_GetLifetimeTime() { + // return time after which lifetime is excessive + return get_current_time() + cookie_lifetimeLimit; +} + +#if 0 +PRIVATE PRBool +cookie_GetLifetimeAsk(time_t expireTime) { + // return true if we should ask about this cookie + return (cookie_GetLifetimePref() == COOKIE_Ask) + && (cookie_GetLifetimeTime() < expireTime); +} +#endif + +PRIVATE time_t +cookie_TrimLifetime(time_t expires) { + // return potentially-trimmed lifetime + if (cookie_GetLifetimePref() == COOKIE_Trim) { + // a limit of zero means expire cookies at end of session + if (cookie_lifetimeLimit == 0) { + return 0; + } + time_t limit = cookie_GetLifetimeTime(); + if ((unsigned)expires > (unsigned)limit) { + return limit; + } + } + return expires; +} + +MODULE_PRIVATE int PR_CALLBACK +cookie_BehaviorPrefChanged(const char * newpref, void * data) { + PRInt32 n; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetIntPref(cookie_behaviorPref, &n))) { + n = PERMISSION_Accept; + } + cookie_SetBehaviorPref((PERMISSION_BehaviorEnum)n); + return 0; +} + +MODULE_PRIVATE int PR_CALLBACK +cookie_WarningPrefChanged(const char * newpref, void * data) { + PRBool x; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetBoolPref(cookie_warningPref, &x))) { + x = PR_FALSE; + } + cookie_SetWarningPref(x); + return 0; +} + +MODULE_PRIVATE int PR_CALLBACK +cookie_LifetimeOptPrefChanged(const char * newpref, void * data) { + PRInt32 n; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetIntPref(cookie_lifetimePref, &n))) { + n = COOKIE_Normal; + } + cookie_SetLifetimePref((COOKIE_LifetimeEnum)n); + return 0; +} + +MODULE_PRIVATE int PR_CALLBACK +cookie_LifetimeLimitPrefChanged(const char * newpref, void * data) { + PRInt32 n; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (!NS_FAILED(prefs->GetIntPref(cookie_lifetimeValue, &n))) { + cookie_SetLifetimeLimit(n); + } + return 0; +} + +PRIVATE int +cookie_SameDomain(char * currentHost, char * firstHost); + +PUBLIC void +COOKIE_RegisterPrefCallbacks(void) { + PRInt32 n; + PRBool x; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + + // Initialize for cookie_behaviorPref + if (NS_FAILED(prefs->GetIntPref(cookie_behaviorPref, &n))) { + n = PERMISSION_Accept; + } + cookie_SetBehaviorPref((PERMISSION_BehaviorEnum)n); + prefs->RegisterCallback(cookie_behaviorPref, cookie_BehaviorPrefChanged, NULL); + + // Initialize for cookie_warningPref + if (NS_FAILED(prefs->GetBoolPref(cookie_warningPref, &x))) { + x = PR_FALSE; + } + cookie_SetWarningPref(x); + prefs->RegisterCallback(cookie_warningPref, cookie_WarningPrefChanged, NULL); + + // Initialize for cookie_lifetimePref + if (NS_FAILED(prefs->GetIntPref(cookie_lifetimePref, &n))) { + n = COOKIE_Normal; + } + cookie_SetLifetimePref((COOKIE_LifetimeEnum)n); + prefs->RegisterCallback(cookie_lifetimePref, cookie_LifetimeOptPrefChanged, NULL); + + // Initialize for cookie_lifetimeValue + if (!NS_FAILED(prefs->GetIntPref(cookie_lifetimeValue, &n))) { + cookie_SetLifetimeLimit(n); + } + prefs->RegisterCallback(cookie_lifetimeValue, cookie_LifetimeLimitPrefChanged, NULL); +} + +PRBool +cookie_IsInDomain(char* domain, char* host, int hostLength) { + int domainLength = PL_strlen(domain); + + /* + * special case for domainName = .hostName + * e.g., hostName = netscape.com + * domainName = .netscape.com + */ + if ((domainLength == hostLength+1) && (domain[0] == '.') && + !PL_strncasecmp(&domain[1], host, hostLength)) { + return PR_TRUE; + } + + /* + * normal case for hostName = x + * e.g., hostName = home.netscape.com + * domainName = .netscape.com + */ + if(domainLength <= hostLength && + !PL_strncasecmp(domain, &host[hostLength-domainLength], domainLength)) { + return PR_TRUE; + } + + /* tests failed, not in domain */ + return PR_FALSE; +} + +/* returns PR_TRUE if authorization is required +** +** +** IMPORTANT: Now that this routine is multi-threaded it is up +** to the caller to free any returned string +*/ +PUBLIC char * +COOKIE_GetCookie(char * address) { + char *name=0; + cookie_CookieStruct * cookie_s; + PRBool isSecure = PR_FALSE; + time_t cur_time = get_current_time(); + + int host_length; + + /* return string to build */ + char * rv=0; + + /* disable cookies if the user's prefs say so */ + if(cookie_GetBehaviorPref() == PERMISSION_DontUse) { + return NULL; + } + if (!PL_strncasecmp(address, "https", 5)) { + isSecure = PR_TRUE; + } + + /* search for all cookies */ + if (cookie_list == nsnull) { + return NULL; + } + char *host = CKutil_ParseURL(address, GET_HOST_PART); + char *path = CKutil_ParseURL(address, GET_PATH_PART); + for (PRInt32 i = 0; i Count(); i++) { + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "corrupt cookie list"); + if(!cookie_s->host) continue; + + /* check the host or domain first */ + if(cookie_s->isDomain) { + char *cp; + + /* calculate the host length by looking at all characters up to a + * colon or '\0'. That way we won't include port numbers in domains + */ + for(cp=host; *cp != '\0' && *cp != ':'; cp++) { + ; /* null body */ + } + host_length = cp - host; + if(!cookie_IsInDomain(cookie_s->host, host, host_length)) { + continue; + } + } else if(PL_strcasecmp(host, cookie_s->host)) { + /* hostname matchup failed. FAIL */ + continue; + } + + /* shorter strings always come last so there can be no ambiquity */ + if(cookie_s->path && !PL_strncmp(path, cookie_s->path, PL_strlen(cookie_s->path))) { + + /* if the cookie is secure and the path isn't, dont send it */ + if (cookie_s->isSecure & !isSecure) { + continue; /* back to top of while */ + } + + /* check for expired cookies */ + if( cookie_s->expires && (cookie_s->expires < cur_time) ) { + /* expire and remove the cookie */ + cookie_list->RemoveElementAt(i); + deleteCookie((void*)cookie_s, nsnull); + cookie_changed = PR_TRUE; + continue; + } + + /* if we've already added a cookie to the return list, append a "; " so + * subsequent cookies are delimited in the final list. */ + if (rv) CKutil_StrAllocCat(rv, "; "); + + if(cookie_s->name && *cookie_s->name != '\0') { + cookie_s->lastAccessed = cur_time; + CKutil_StrAllocCopy(name, cookie_s->name); + CKutil_StrAllocCat(name, "="); + +#ifdef PREVENT_DUPLICATE_NAMES + /* make sure we don't have a previous name mapping already in the string */ + if(!rv || !PL_strstr(rv, name)) { + CKutil_StrAllocCat(rv, name); + CKutil_StrAllocCat(rv, cookie_s->cookie); + } +#else + CKutil_StrAllocCat(rv, name); + CKutil_StrAllocCat(rv, cookie_s->cookie); +#endif /* PREVENT_DUPLICATE_NAMES */ + } else { + CKutil_StrAllocCat(rv, cookie_s->cookie); + } + } + } + + PR_FREEIF(name); + PR_FREEIF(path); + PR_FREEIF(host); + + /* may be NULL */ + return(rv); +} + +/* Determines whether the inlineHost is in the same domain as the currentHost. + * For use with rfc 2109 compliance/non-compliance. + */ +PRIVATE int +cookie_SameDomain(char * currentHost, char * firstHost) { + char * dot = 0; + char * currentDomain = 0; + char * firstDomain = 0; + if(!currentHost || !firstHost) { + return 0; + } + + /* case insensitive compare */ + if(PL_strcasecmp(currentHost, firstHost) == 0) { + return 1; + } + currentDomain = PL_strchr(currentHost, '.'); + firstDomain = PL_strchr(firstHost, '.'); + if(!currentDomain || !firstDomain) { + return 0; + } + + /* check for at least two dots before continuing, if there are + * not two dots we don't have enough information to determine + * whether or not the firstDomain is within the currentDomain + */ + dot = PL_strchr(firstDomain, '.'); + if(dot) { + dot = PL_strchr(dot+1, '.'); + } else { + return 0; + } + + /* handle .com. case */ + if(!dot || (*(dot+1) == '\0')) { + return 0; + } + if(!PL_strcasecmp(firstDomain, currentDomain)) { + return 1; + } + return 0; +} + +PRBool +cookie_isForeign (char * curURL, char * firstURL) { + char * curHost = CKutil_ParseURL(curURL, GET_HOST_PART); + char * firstHost = CKutil_ParseURL(firstURL, GET_HOST_PART); + char * curHostColon = 0; + char * firstHostColon = 0; + + /* strip ports */ + curHostColon = PL_strchr(curHost, ':'); + if(curHostColon) { + *curHostColon = '\0'; + } + firstHostColon = PL_strchr(firstHost, ':'); + if(firstHostColon) { + *firstHostColon = '\0'; + } + + /* determine if it's foreign */ + PRBool retval = (!cookie_SameDomain(curHost, firstHost)); + + /* clean up our garbage and return */ + if(curHostColon) { + *curHostColon = ':'; + } + if(firstHostColon) { + *firstHostColon = ':'; + } + PR_FREEIF(curHost); + PR_FREEIF(firstHost); + return retval; +} + +/* returns PR_TRUE if authorization is required +** +** +** IMPORTANT: Now that this routine is multi-threaded it is up +** to the caller to free any returned string +*/ +PUBLIC char * +COOKIE_GetCookieFromHttp(char * address, char * firstAddress) { + + if ((cookie_GetBehaviorPref() == PERMISSION_DontAcceptForeign) && + cookie_isForeign(address, firstAddress)) { + + /* + * WARNING!!! This is a different behavior than 4.x. In 4.x we used this pref to + * control the setting of cookies only. Here we are also blocking the getting of + * cookies if the pref is set. It may be that we need a separate pref to block the + * getting of cookies. But for now we are putting both under one pref since that + * is cleaner. If it turns out that this breaks some important websites, we may + * have to resort to two prefs + */ + + return NULL; + } + return COOKIE_GetCookie(address); +} + +MODULE_PRIVATE PRBool +cookie_IsFromHost(cookie_CookieStruct *cookie_s, char *host) { + if (!cookie_s || !(cookie_s->host)) { + return PR_FALSE; + } + if (cookie_s->isDomain) { + char *cp; + int host_length; + + /* calculate the host length by looking at all characters up to + * a colon or '\0'. That way we won't include port numbers + * in domains + */ + for(cp=host; *cp != '\0' && *cp != ':'; cp++) { + ; /* null body */ + } + host_length = cp - host; + + /* compare the tail end of host to cook_s->host */ + return cookie_IsInDomain(cookie_s->host, host, host_length); + } else { + return PL_strcasecmp(host, cookie_s->host) == 0; + } +} + +/* find out how many cookies this host has already set */ +PRIVATE int +cookie_Count(char * host) { + int count = 0; + cookie_CookieStruct * cookie; + if (!cookie_list || !host) return 0; + + for (PRInt32 i = cookie_list->Count(); i > 0;) { + i--; + cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie, "corrupt cookie list"); + if (cookie_IsFromHost(cookie, host)) count++; + } + return count; +} + +/* Java script is calling COOKIE_SetCookieString, netlib is calling + * this via COOKIE_SetCookieStringFromHttp. + */ +PRIVATE void +cookie_SetCookieString(char * curURL, nsIPrompt *aPrompter, const char * setCookieHeader, time_t timeToExpire) { + cookie_CookieStruct * prev_cookie; + char *path_from_header=NULL, *host_from_header=NULL; + char *name_from_header=NULL, *cookie_from_header=NULL; + char *cur_path = CKutil_ParseURL(curURL, GET_PATH_PART); + char *cur_host = CKutil_ParseURL(curURL, GET_HOST_PART); + char *semi_colon, *ptr, *equal; + char *setCookieHeaderInternal = (char *) setCookieHeader; + PRBool isSecure=PR_FALSE, isDomain=PR_FALSE; + PRBool bCookieAdded; + PRBool pref_scd = PR_FALSE; + + /* Only allow cookies to be set in the listed contexts. + * We don't want cookies being set in html mail. + */ +/* We need to come back and work on this - Neeti + type = context->type; + if(!((type==MWContextBrowser) || (type==MWContextHTMLHelp) || (type==MWContextPane))) { + PR_Free(cur_path); + PR_Free(cur_host); + return; + } +*/ + if(cookie_GetBehaviorPref() == PERMISSION_DontUse) { + PR_Free(cur_path); + PR_Free(cur_host); + return; + } + +//printf("\nSetCookieString(URL '%s', header '%s') time %d == %s\n",curURL,setCookieHeader,timeToExpire,asctime(gmtime(&timeToExpire))); + if(cookie_GetLifetimePref() == COOKIE_Discard) { + if(cookie_GetLifetimeTime() < timeToExpire) { + PR_Free(cur_path); + PR_Free(cur_host); + return; + } + } + +//HG87358 -- @@?? + + /* terminate at any carriage return or linefeed */ + for(ptr=setCookieHeaderInternal; *ptr; ptr++) { + if(*ptr == LF || *ptr == CR) { + *ptr = '\0'; + break; + } + } + + /* parse path and expires attributes from header if present */ + semi_colon = PL_strchr(setCookieHeaderInternal, ';'); + if(semi_colon) { + /* truncate at semi-colon and advance */ + *semi_colon++ = '\0'; + + /* there must be some attributes. (hopefully) */ + if ((ptr=PL_strcasestr(semi_colon, "secure"))) { + char cPre=*(ptr-1), cPost=*(ptr+6); + if (((cPre==' ') || (cPre==';')) && (!cPost || (cPost==' ') || (cPost==';'))) { + isSecure = PR_TRUE; + } + } + + /* look for the path attribute */ + ptr = PL_strcasestr(semi_colon, "path="); + if(ptr) { + nsCAutoString path(ptr+5); + path.CompressWhitespace(); + CKutil_StrAllocCopy(path_from_header, path.get()); + /* terminate at first space or semi-colon */ + for(ptr=path_from_header; *ptr != '\0'; ptr++) { + if(nsString::IsSpace(*ptr) || *ptr == ';' || *ptr == ',') { + *ptr = '\0'; + break; + } + } + } + + /* look for the URI or URL attribute + * + * This might be a security hole so I'm removing + * it for now. + */ + + /* look for a domain */ + ptr = PL_strcasestr(semi_colon, "domain="); + if(ptr) { + char *domain_from_header=NULL; + char *dot, *colon; + int domain_length, cur_host_length; + + /* allocate more than we need */ + nsCAutoString domain(ptr+7); + domain.CompressWhitespace(); + CKutil_StrAllocCopy(domain_from_header, domain.get()); + + /* terminate at first space or semi-colon */ + for(ptr=domain_from_header; *ptr != '\0'; ptr++) { + if(nsString::IsSpace(*ptr) || *ptr == ';' || *ptr == ',') { + *ptr = '\0'; + break; + } + } + + /* verify that this host has the authority to set for this domain. We do + * this by making sure that the host is in the domain. We also require + * that a domain have at least two periods to prevent domains of the form + * ".com" and ".edu" + * + * Also make sure that there is more stuff after + * the second dot to prevent ".com." + */ + dot = PL_strchr(domain_from_header, '.'); + if(dot) { + dot = PL_strchr(dot+1, '.'); + } + if(!dot || *(dot+1) == '\0') { + /* did not pass two dot test. FAIL */ + PR_FREEIF(path_from_header); + PR_Free(domain_from_header); + PR_Free(cur_path); + PR_Free(cur_host); + // TRACEMSG(("DOMAIN failed two dot test")); + return; + } + + /* strip port numbers from the current host for the domain test */ + colon = PL_strchr(cur_host, ':'); + if(colon) { + *colon = '\0'; + } + domain_length = PL_strlen(domain_from_header); + cur_host_length = PL_strlen(cur_host); + + /* check to see if the host is in the domain */ + if (!cookie_IsInDomain(domain_from_header, cur_host, cur_host_length)) { + // TRACEMSG(("DOMAIN failed host within domain test." +// " Domain: %s, Host: %s", domain_from_header, cur_host)); + PR_FREEIF(path_from_header); + PR_Free(domain_from_header); + PR_Free(cur_path); + PR_Free(cur_host); + return; + } + + /* + * check that portion of host not in domain does not contain a dot + * This satisfies the fourth requirement in section 4.3.2 of the cookie + * spec rfc 2109 (see www.cis.ohio-state.edu/htbin/rfc/rfc2109.html). + * It prevents host of the form x.y.co.nz from setting cookies in the + * entire .co.nz domain. Note that this doesn't really solve the problem, + * it justs makes it more unlikely. Sites such as y.co.nz can still set + * cookies for the entire .co.nz domain. + */ + + /* + * Although this is the right thing to do(tm), it breaks too many sites. + * So only do it if the restrictCookieDomains pref is PR_TRUE. + * + */ + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetBoolPref(cookie_strictDomainsPref, &pref_scd))) { + pref_scd = PR_FALSE; + } + if ( pref_scd == PR_TRUE ) { + cur_host[cur_host_length-domain_length] = '\0'; + dot = PL_strchr(cur_host, '.'); + cur_host[cur_host_length-domain_length] = '.'; + if (dot) { + // TRACEMSG(("host minus domain failed no-dot test." + // " Domain: %s, Host: %s", domain_from_header, cur_host)); + PR_FREEIF(path_from_header); + PR_Free(domain_from_header); + PR_Free(cur_path); + PR_Free(cur_host); + return; + } + } + + /* all tests passed, copy in domain to hostname field */ + CKutil_StrAllocCopy(host_from_header, domain_from_header); + isDomain = PR_TRUE; + // TRACEMSG(("Accepted domain: %s", host_from_header)); + PR_Free(domain_from_header); + } + + /* now search for the expires header + * NOTE: that this part of the parsing + * destroys the original part of the string + */ + ptr = PL_strcasestr(semi_colon, "expires="); + if(ptr) { + char *date = ptr+8; + /* terminate the string at the next semi-colon */ + for(ptr=date; *ptr != '\0'; ptr++) { + if(*ptr == ';') { + *ptr = '\0'; + break; + } + } + if(timeToExpire == 0) { + timeToExpire = cookie_ParseDate(date); + } + // TRACEMSG(("Have expires date: %ld", timeToExpire)); + } + } + if(!path_from_header) { + /* strip down everything after the last slash to get the path. */ + char * slash = PL_strrchr(cur_path, '/'); + if(slash) { + *slash = '\0'; + } + path_from_header = cur_path; + } else { + PR_Free(cur_path); + } + if(!host_from_header) { + host_from_header = cur_host; + } else { + PR_Free(cur_host); + } + + /* keep cookies under the max bytes limit */ + if(PL_strlen(setCookieHeaderInternal) > MAX_BYTES_PER_COOKIE) { + setCookieHeaderInternal[MAX_BYTES_PER_COOKIE-1] = '\0'; + } + + /* separate the name from the cookie */ + equal = PL_strchr(setCookieHeaderInternal, '='); + if (equal) + *equal = '\0'; + + nsCAutoString cookieHeader(setCookieHeaderInternal); + cookieHeader.CompressWhitespace(); + if(equal) { + CKutil_StrAllocCopy(name_from_header, cookieHeader.get()); + nsCAutoString value(equal+1); + value.CompressWhitespace(); + CKutil_StrAllocCopy(cookie_from_header, value.get()); + } else { + CKutil_StrAllocCopy(cookie_from_header, cookieHeader.get()); + CKutil_StrAllocCopy(name_from_header, ""); + } + + /* generate the message for the nag box */ + PRUnichar * new_string=0; + int count = cookie_Count(host_from_header); + prev_cookie = cookie_CheckForPrevCookie + (path_from_header, host_from_header, name_from_header); + PRUnichar * message; + if (prev_cookie) { + message = CKutil_Localize(NS_LITERAL_STRING("PermissionToModifyCookie").get()); + new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); + } else if (count>1) { + message = CKutil_Localize(NS_LITERAL_STRING("PermissionToSetAnotherCookie").get()); + new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : "", count); + } else if (count==1){ + message = CKutil_Localize(NS_LITERAL_STRING("PermissionToSetSecondCookie").get()); + new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); + } else { + message = CKutil_Localize(NS_LITERAL_STRING("PermissionToSetACookie").get()); + new_string = nsTextFormatter::smprintf(message, host_from_header ? host_from_header : ""); + } + Recycle(message); + + //TRACEMSG(("mkaccess.c: Setting cookie: %s for host: %s for path: %s", + // cookie_from_header, host_from_header, path_from_header)); + + /* use common code to determine if we can set the cookie */ + PRBool permission = Permission_Check(aPrompter, host_from_header, COOKIEPERMISSION, +// I believe this is the right place to eventually add the logic to ask +// about cookies that have excessive lifetimes, but it shouldn't be done +// until generalized per-site preferences are available. + //cookie_GetLifetimeAsk(timeToExpire) || + cookie_GetWarningPref(), + new_string); + PR_FREEIF(new_string); + if (!permission) { + PR_FREEIF(path_from_header); + PR_FREEIF(host_from_header); + PR_FREEIF(name_from_header); + PR_FREEIF(cookie_from_header); + return; + } + + /* limit the number of cookies from a specific host or domain */ + cookie_CheckForMaxCookiesFromHost(host_from_header); + + if (cookie_list) { + if(cookie_list->Count() > MAX_NUMBER_OF_COOKIES-1) { + cookie_RemoveOldestCookie(); + } + } + prev_cookie = cookie_CheckForPrevCookie (path_from_header, host_from_header, name_from_header); + if(prev_cookie) { + prev_cookie->expires = cookie_TrimLifetime(timeToExpire); + PR_FREEIF(prev_cookie->cookie); + PR_FREEIF(prev_cookie->path); + PR_FREEIF(prev_cookie->host); + PR_FREEIF(prev_cookie->name); + prev_cookie->cookie = cookie_from_header; + prev_cookie->path = path_from_header; + prev_cookie->host = host_from_header; + prev_cookie->name = name_from_header; + prev_cookie->isSecure = isSecure; + prev_cookie->isDomain = isDomain; + prev_cookie->lastAccessed = get_current_time(); + } else { + cookie_CookieStruct * tmp_cookie_ptr; + size_t new_len; + + /* construct a new cookie_struct */ + prev_cookie = PR_NEW(cookie_CookieStruct); + if(!prev_cookie) { + PR_FREEIF(path_from_header); + PR_FREEIF(host_from_header); + PR_FREEIF(name_from_header); + PR_FREEIF(cookie_from_header); + return; + } + + /* copy */ + prev_cookie->cookie = cookie_from_header; + prev_cookie->name = name_from_header; + prev_cookie->path = path_from_header; + prev_cookie->host = host_from_header; + prev_cookie->expires = cookie_TrimLifetime(timeToExpire); + prev_cookie->isSecure = isSecure; + prev_cookie->isDomain = isDomain; + prev_cookie->lastAccessed = get_current_time(); + if(!cookie_list) { + cookie_list = new nsVoidArray(); + if(!cookie_list) { + PR_FREEIF(path_from_header); + PR_FREEIF(name_from_header); + PR_FREEIF(host_from_header); + PR_FREEIF(cookie_from_header); + PR_Free(prev_cookie); + return; + } + } + + /* add it to the list so that it is before any strings of smaller length */ + bCookieAdded = PR_FALSE; + new_len = PL_strlen(prev_cookie->path); + for (PRInt32 i = cookie_list->Count(); i > 0;) { + i--; + tmp_cookie_ptr = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(tmp_cookie_ptr, "corrupt cookie list"); + if(new_len <= PL_strlen(tmp_cookie_ptr->path)) { + cookie_list->InsertElementAt(prev_cookie, i+1); + bCookieAdded = PR_TRUE; + break; + } + } + if ( !bCookieAdded ) { + /* no shorter strings found in list */ + cookie_list->AppendElement(prev_cookie); + } + } + + /* At this point we know a cookie has changed. Make a note to write the cookies to file. */ + cookie_changed = PR_TRUE; + return; +} + +PUBLIC void +COOKIE_SetCookieString(char * curURL, nsIPrompt *aPrompter, const char * setCookieHeader) { + cookie_SetCookieString(curURL, aPrompter, setCookieHeader, 0); +} + +/* This function wrapper wraps COOKIE_SetCookieString for the purposes of + * determining whether or not a cookie is inline (we need the URL struct, + * and outputFormat to do so). this is called from NET_ParseMimeHeaders + * in mkhttp.c + * This routine does not need to worry about the cookie lock since all of + * the work is handled by sub-routines +*/ + +PUBLIC void +COOKIE_SetCookieStringFromHttp(char * curURL, char * firstURL, nsIPrompt *aPrompter, char * setCookieHeader, char * server_date) { + + /* allow for multiple cookies separated by newlines */ + char *newline = PL_strchr(setCookieHeader, '\n'); + if(newline) { + *newline = '\0'; + COOKIE_SetCookieStringFromHttp(curURL, firstURL, aPrompter, setCookieHeader, server_date); + *newline = '\n'; + COOKIE_SetCookieStringFromHttp(curURL, firstURL, aPrompter, newline+1, server_date); + return; + } + + /* If the outputFormat is not PRESENT (the url is not going to the screen), and not + * SAVE AS (shift-click) then + * the cookie being set is defined as inline so we need to do what the user wants us + * to based on his preference to deal with foreign cookies. If it's not inline, just set + * the cookie. + */ + char *ptr=NULL; + time_t gmtCookieExpires=0, expires=0, sDate; + + /* check for foreign cookie if pref says to reject such */ + if ((cookie_GetBehaviorPref() == PERMISSION_DontAcceptForeign) && + cookie_isForeign(curURL, firstURL)) { + /* it's a foreign cookie so don't set the cookie */ + return; + } + + /* Determine when the cookie should expire. This is done by taking the difference between + * the server time and the time the server wants the cookie to expire, and adding that + * difference to the client time. This localizes the client time regardless of whether or + * not the TZ environment variable was set on the client. + */ + + /* Get the time the cookie is supposed to expire according to the attribute*/ + ptr = PL_strcasestr(setCookieHeader, "expires="); + if(ptr) { + char *date = ptr+8; + char origLast = '\0'; + for(ptr=date; *ptr != '\0'; ptr++) { + if(*ptr == ';') { + origLast = ';'; + *ptr = '\0'; + break; + } + } + expires = cookie_ParseDate(date); + *ptr=origLast; + } + if (server_date) { + sDate = cookie_ParseDate(server_date); + } else { + sDate = get_current_time(); + } + if( sDate && expires ) { + if( expires < sDate ) { + gmtCookieExpires=1; + } else { + gmtCookieExpires = expires - sDate + get_current_time(); + // if overflow + if( gmtCookieExpires < get_current_time()) { + gmtCookieExpires = (((unsigned) (~0) << 1) >> 1); // max int + } + } + } + cookie_SetCookieString(curURL, aPrompter, setCookieHeader, gmtCookieExpires); +} + +/* saves out the HTTP cookies to disk */ +PUBLIC nsresult +COOKIE_Write() { + if (!cookie_changed || !cookie_list) { + return NS_OK; + } + cookie_CookieStruct * cookie_s; + time_t cur_date = get_current_time(); + char date_string[36]; + nsFileSpec dirSpec; + nsresult rv = CKutil_ProfileDirectory(dirSpec); + if (NS_FAILED(rv)) { + return rv; + } + nsOutputFileStream strm(dirSpec + kCookiesFileName); + if (!strm.is_open()) { + /* file doesn't exist -- that's not an error */ + return NS_OK; + } + + strm.write("# HTTP Cookie File\n", 19); + strm.write("# http://www.netscape.com/newsref/std/cookie_spec.html\n", 55); + strm.write("# This is a generated file! Do not edit.\n", 42); + strm.write("# To delete cookies, use the Cookie Manager.\n\n", 46); + + /* format shall be: + * + * host \t isDomain \t path \t secure \t expires \t name \t cookie + * + * isDomain is PR_TRUE or PR_FALSE + * secure is PR_TRUE or PR_FALSE + * expires is a time_t integer + * cookie can have tabs + */ + PRInt32 count = cookie_list->Count(); + for (PRInt32 i = 0; i < count; ++i) { + cookie_s = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(cookie_s, "corrupt cookie list"); + if (cookie_s->expires < cur_date) { + /* don't write entry if cookie has expired or has no expiration date */ + continue; + } + + strm.write(cookie_s->host, nsCRT::strlen(cookie_s->host)); + + if (cookie_s->isDomain) { + strm.write("\tTRUE\t", 6); + } else { + strm.write("\tFALSE\t", 7); + } + + strm.write(cookie_s->path, nsCRT::strlen(cookie_s->path)); + + if (cookie_s->isSecure) { + strm.write("\tTRUE\t", 6); + } else { + strm.write("\tFALSE\t", 7); + } + + PR_snprintf(date_string, sizeof(date_string), "%lu", cookie_s->expires); + + strm.write(date_string, nsCRT::strlen(date_string)); + strm.write("\t", 1); + strm.write(cookie_s->name, nsCRT::strlen(cookie_s->name)); + strm.write("\t", 1); + strm.write(cookie_s->cookie, nsCRT::strlen(cookie_s->cookie)); + strm.write("\n", 1); + } + + cookie_changed = PR_FALSE; + strm.flush(); + strm.close(); + return NS_OK; +} + +/* reads HTTP cookies from disk */ +PUBLIC nsresult +COOKIE_Read() { + if (cookie_list) { + return NS_OK; + } + cookie_CookieStruct *new_cookie, *tmp_cookie_ptr; + size_t new_len; + nsAutoString buffer; + PRBool added_to_list; + nsFileSpec dirSpec; + nsresult rv = CKutil_ProfileDirectory(dirSpec); + if (NS_FAILED(rv)) { + return rv; + } + nsInputFileStream strm(dirSpec + kCookiesFileName); + if (!strm.is_open()) { + /* file doesn't exist -- that's not an error */ + return NS_OK; + } + + /* format is: + * + * host \t isDomain \t path \t secure \t expires \t name \t cookie + * + * if this format isn't respected we move onto the next line in the file. + * isDomain is PR_TRUE or PR_FALSE -- defaulting to PR_FALSE + * secure is PR_TRUE or PR_FALSE -- should default to PR_TRUE + * expires is a time_t integer + * cookie can have tabs + */ + while (CKutil_GetLine(strm,buffer) != -1){ + added_to_list = PR_FALSE; + + if ( !buffer.IsEmpty() ) { + PRUnichar firstChar = buffer.CharAt(0); + if (firstChar == '#' || firstChar == CR || + firstChar == LF || firstChar == 0) { + continue; + } + } + int hostIndex, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex; + hostIndex = 0; + if ((isDomainIndex=buffer.FindChar('\t', PR_FALSE,hostIndex)+1) == 0 || + (pathIndex=buffer.FindChar('\t', PR_FALSE,isDomainIndex)+1) == 0 || + (secureIndex=buffer.FindChar('\t', PR_FALSE,pathIndex)+1) == 0 || + (expiresIndex=buffer.FindChar('\t', PR_FALSE,secureIndex)+1) == 0 || + (nameIndex=buffer.FindChar('\t', PR_FALSE,expiresIndex)+1) == 0 || + (cookieIndex=buffer.FindChar('\t', PR_FALSE,nameIndex)+1) == 0 ) { + continue; + } + nsAutoString host, isDomain, path, isSecure, expires, name, cookie; + buffer.Mid(host, hostIndex, isDomainIndex-hostIndex-1); + buffer.Mid(isDomain, isDomainIndex, pathIndex-isDomainIndex-1); + buffer.Mid(path, pathIndex, secureIndex-pathIndex-1); + buffer.Mid(isSecure, secureIndex, expiresIndex-secureIndex-1); + buffer.Mid(expires, expiresIndex, nameIndex-expiresIndex-1); + buffer.Mid(name, nameIndex, cookieIndex-nameIndex-1); + buffer.Mid(cookie, cookieIndex, buffer.Length()-cookieIndex); + + /* create a new cookie_struct and fill it in */ + new_cookie = PR_NEW(cookie_CookieStruct); + if (!new_cookie) { + strm.close(); + return NS_ERROR_OUT_OF_MEMORY; + } + memset(new_cookie, 0, sizeof(cookie_CookieStruct)); + new_cookie->name = name.ToNewCString(); + new_cookie->cookie = cookie.ToNewCString(); + new_cookie->host = host.ToNewCString(); + new_cookie->path = path.ToNewCString(); + if (isDomain.EqualsWithConversion("TRUE")) { + new_cookie->isDomain = PR_TRUE; + } else { + new_cookie->isDomain = PR_FALSE; + } + if (isSecure.EqualsWithConversion("TRUE")) { + new_cookie->isSecure = PR_TRUE; + } else { + new_cookie->isSecure = PR_FALSE; + } + char * expiresCString = expires.ToNewCString(); + new_cookie->expires = strtoul(expiresCString, nsnull, 10); + nsCRT::free(expiresCString); + + /* start new cookie list if one does not already exist */ + if (!cookie_list) { + cookie_list = new nsVoidArray(); + if (!cookie_list) { + strm.close(); + return NS_ERROR_OUT_OF_MEMORY; + } + } + + /* add new cookie to the list so that it is before any strings of smaller length */ + new_len = PL_strlen(new_cookie->path); + for (PRInt32 i = cookie_list->Count(); i > 0;) { + i--; + tmp_cookie_ptr = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(i)); + NS_ASSERTION(tmp_cookie_ptr, "corrupt cookie list"); + if (new_len <= PL_strlen(tmp_cookie_ptr->path)) { + cookie_list->InsertElementAt(new_cookie, i); + added_to_list = PR_TRUE; + break; + } + } + + /* no shorter strings found in list so add new cookie at end */ + if (!added_to_list) { + cookie_list->AppendElement(new_cookie); + } + } + + strm.close(); + cookie_changed = PR_FALSE; + return NS_OK; +} + +PRIVATE PRBool +CookieCompare (cookie_CookieStruct * cookie1, cookie_CookieStruct * cookie2) { + char * host1 = cookie1->host; + char * host2 = cookie2->host; + + /* get rid of leading period on host name, if any */ + if (*host1 == '.') { + host1++; + } + if (*host2 == '.') { + host2++; + } + + /* make decision based on host name if they are unequal */ + if (PL_strcmp (host1, host2) < 0) { + return -1; + } + if (PL_strcmp (host1, host2) > 0) { + return 1; + } + + /* if host names are equal, make decision based on cookie name if they are unequal */ + if (PL_strcmp (cookie1->name, cookie2->name) < 0) { + return -1; + } + if (PL_strcmp (cookie1->name, cookie2->name) > 0) { + return 1; + } + + /* if host and cookie names are equal, make decision based on path */ + /* It may seem like this should never happen but it does. + * Go to groups.aol.com and you will get two cookies with + * identical host and cookie names but different paths + */ + return (PL_strcmp (cookie1->path, cookie2->path)); +} + +/* + * return a string that has each " of the argument sting + * replaced with \" so it can be used inside a quoted string + */ +PRIVATE char* +cookie_FixQuoted(char* s) { + char * result; + int count = PL_strlen(s); + char *quote = s; + unsigned int i, j; + while ((quote = PL_strchr(quote, '"'))) { + count++; + quote++; + } + result = (char*)PR_Malloc(count + 1); + for (i=0, j=0; iCount(); +} + +PUBLIC void +COOKIE_Enumerate + (PRInt32 count, + char **name, + char **value, + PRBool *isDomain, + char ** host, + char ** path, + PRBool * isSecure, + PRUint64 * expires) { + if (count == 0) { + /* Get rid of any expired cookies now so user doesn't + * think/see that we're keeping cookies in memory. + */ + cookie_RemoveExpiredCookies(); + } + cookie_CookieStruct *cookie; + cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(count)); + NS_ASSERTION(cookie, "corrupt cookie list"); + + *name = cookie_FixQuoted(cookie->name); + *value = cookie_FixQuoted(cookie->cookie); + *isDomain = cookie->isDomain; + *host = cookie_FixQuoted(cookie->host); + *path = cookie_FixQuoted(cookie->path); + *isSecure = cookie->isSecure; + time_t expiresTime=0; + if (cookie->expires) { + /* + * Cookie expiration times on mac will not be decoded correctly because + * they were based on get_current_time() instead of time(NULL) -- see comments in + * get_current_time. So we need to adjust for that now in order for the + * display of the expiration time to be correct + */ + expiresTime = cookie->expires + (time(NULL) - get_current_time()); + } + // *expires = expiresTime; -- no good no mac, using next line instead + LL_UI2L(*expires, expiresTime); +} + +PUBLIC void +COOKIE_Remove + (const char* host, const char* name, const char* path, const PRBool permanent) { + cookie_CookieStruct * cookie; + PRInt32 count = 0; + + /* step through all cookies searching for indicated one */ + if (cookie_list) { + count = cookie_list->Count(); + while (count>0) { + count--; + cookie = NS_STATIC_CAST(cookie_CookieStruct*, cookie_list->ElementAt(count)); + NS_ASSERTION(cookie, "corrupt cookie list"); + if ((PL_strcmp(cookie->host, host) == 0) && + (PL_strcmp(cookie->name, name) == 0) && + (PL_strcmp(cookie->path, path) == 0)) { + if (permanent && cookie->host) { + char * hostname = nsnull; + char * hostnameAfterDot = cookie->host; + while (*hostnameAfterDot == '.') { + hostnameAfterDot++; + } + CKutil_StrAllocCopy(hostname, hostnameAfterDot); + if (hostname) { + Permission_AddHost(hostname, PR_FALSE, COOKIEPERMISSION, PR_TRUE); + } + } + cookie_list->RemoveElementAt(count); + deleteCookie((void*)cookie, nsnull); + cookie_changed = PR_TRUE; + COOKIE_Write(); + break; + } + } + } +} + +MODULE_PRIVATE time_t +cookie_ParseDate(char *date_string) { + + PRTime prdate; + time_t date = 0; + // TRACEMSG(("Parsing date string: %s\n",date_string)); + + if(PR_ParseTimeString(date_string, PR_TRUE, &prdate) == PR_SUCCESS) { + PRInt64 r, u; + LL_I2L(u, PR_USEC_PER_SEC); + LL_DIV(r, prdate, u); + LL_L2I(date, r); + if (date < 0) { + date = 0; + } + // TRACEMSG(("Parsed date as GMT: %s\n", asctime(gmtime(&date)))); // TRACEMSG(("Parsed date as local: %s\n", ctime(&date))); + } else { + // TRACEMSG(("Could not parse date")); + } + return (date); +} diff --git a/mozilla/extensions/cookie/nsCookies.h b/mozilla/extensions/cookie/nsCookies.h new file mode 100644 index 00000000000..1f28dc72963 --- /dev/null +++ b/mozilla/extensions/cookie/nsCookies.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef COOKIES_H +#define COOKIES_H + +#include "nsString.h" + +#ifdef _IMPL_NS_COOKIE +#define NS_COOKIE NS_EXPORT +#else +#define NS_COOKIE NS_IMPORT +#endif + + +class nsIPrompt; + +extern nsresult COOKIE_Read(); +extern nsresult COOKIE_Write(); +extern char * COOKIE_GetCookie(char * address); +extern char * COOKIE_GetCookieFromHttp(char * address, char * firstAddress); +extern void COOKIE_SetCookieString(char * cur_url, nsIPrompt *aPrompter, const char * set_cookie_header); +extern void COOKIE_SetCookieStringFromHttp(char * cur_url, char * first_url, nsIPrompt *aPRompter, char * set_cookie_header, char * server_date); +extern void COOKIE_RegisterPrefCallbacks(void); + +extern void COOKIE_RemoveAll(void); +extern void COOKIE_DeletePersistentUserData(void); +extern PRInt32 COOKIE_Count(); +extern void COOKIE_Enumerate + (PRInt32 count, + char **name, + char **value, + PRBool *isDomain, + char ** host, + char ** path, + PRBool * isSecure, + PRUint64 * expires); +extern void COOKIE_Remove + (const char* host, const char* name, const char* path, const PRBool permanent); + +#endif /* COOKIES_H */ diff --git a/mozilla/extensions/cookie/nsICookie.idl b/mozilla/extensions/cookie/nsICookie.idl new file mode 100644 index 00000000000..85d7f56c622 --- /dev/null +++ b/mozilla/extensions/cookie/nsICookie.idl @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + + * The Original Code is mozilla.org code. + + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 2001, Mozilla. All Rights Reserved. + + * Contributor(s): + */ + +#include "nsISupports.idl" + +[scriptable, uuid(E9FCB9A4-D376-458f-B720-E65E7DF593BC)] + +/** + This interface represents a HTTP or Javascript "cookie" object. +*/ + +interface nsICookie : nsISupports { + + /* the name of the cookie */ + readonly attribute string name; + + /* the cookie value */ + readonly attribute string value; + + /* true if the cookie is a domain cookie, false otherwise */ + readonly attribute boolean isDomain; + + /* the host (possibly fully qualified) of the cookie */ + readonly attribute string host; + + /* the path pertaining to the cookie */ + readonly attribute string path; + + /* true if the cookie was transmitted over ssl, false otherwise */ + readonly attribute boolean isSecure; + + /* expiration time (local timezone) expressed as number of seconds since Jan 1, 1970 */ + readonly attribute PRUint64 expires; + +}; + +%{ C++ +// {E9FCB9A4-D376-458f-B720-E65E7DF593BC} +#define NS_COOKIE_CID \ +{ 0xe9fcb9a4, 0xd376, 0x458f, { 0xb7, 0x20, 0xe6, 0x5e, 0x7d, 0xf5, 0x93, 0xbc } } +#define NS_COOKIE_CONTRACTID "@mozilla.org/cookie;1" +%} diff --git a/mozilla/extensions/cookie/nsICookieManager.idl b/mozilla/extensions/cookie/nsICookieManager.idl new file mode 100644 index 00000000000..9eba302fba9 --- /dev/null +++ b/mozilla/extensions/cookie/nsICookieManager.idl @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* + + This file contains an interface to the Cookie Manager. + + */ + +#include "nsISupports.idl" +#include "nsIEnumerator.idl" + +[scriptable, uuid(AAAB6710-0F2C-11d5-A53B-0010A401EB10)] +interface nsICookieManager : nsISupports +{ + void removeAll(); + readonly attribute nsISimpleEnumerator enumerator; + void remove(in string domain, in string name, in string path, in boolean permanent); +}; + +%{ C++ +// {AAAB6710-0F2C-11d5-A53B-0010A401EB10} +#define NS_COOKIEMANAGER_CID \ +{ 0xaaab6710, 0xf2c, 0x11d5, { 0xa5, 0x3b, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } } +#define NS_COOKIEMANAGER_CONTRACTID "@mozilla.org/cookiemanager;1" +%} diff --git a/mozilla/extensions/cookie/nsICookieService.h b/mozilla/extensions/cookie/nsICookieService.idl similarity index 53% rename from mozilla/extensions/cookie/nsICookieService.h rename to mozilla/extensions/cookie/nsICookieService.idl index 08791fa9970..97f8339e39f 100644 --- a/mozilla/extensions/cookie/nsICookieService.h +++ b/mozilla/extensions/cookie/nsICookieService.idl @@ -1,5 +1,5 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -20,32 +20,19 @@ * Contributor(s): */ -#ifndef nsICookieService_h__ -#define nsICookieService_h__ +/* -#include "nsISupports.h" -#include "nsIURL.h" -#include "nsString.h" -#include "nsIDocument.h" + This file contains an interface to the Cookie Service. -// {AB397774-12D3-11d3-8AD1-00105A1B8860} -#define NS_COOKIESERVICE_CID \ -{ 0xab397774, 0x12d3, 0x11d3, { 0x8a, 0xd1, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } } + */ -/* ContractID prefixes for Cookie DLL registration. */ -#define NS_COOKIESERVICE_CONTRACTID "@mozilla.org/cookie;1" - -// {AB397772-12D3-11d3-8AD1-00105A1B8860} -#define NS_ICOOKIESERVICE_IID \ -{ 0xab397772, 0x12d3, 0x11d3, { 0x8a, 0xd1, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } } - -class nsIPrompt; - -class nsICookieService : public nsISupports { -public: - - static const nsIID& GetIID() { static nsIID iid = NS_ICOOKIESERVICE_IID; return iid; } +#include "nsISupports.idl" +#include "nsIURI.idl" +#include "nsIPrompt.idl" +[scriptable, uuid(AB397774-12D3-11d3-8AD1-00105A1B8860)] +interface nsICookieService : nsISupports +{ /* * Get the complete cookie string associated with the URL * @@ -53,7 +40,7 @@ public: * @param aCookie The string object which will hold the result * @return Returns NS_OK if successful, or NS_FALSE if an error occurred. */ - NS_IMETHOD GetCookieString(nsIURI *aURL, nsString& aCookie)=0; + string getCookieString(in nsIURI aURL); /* * Get the complete cookie string associated with the URL @@ -63,7 +50,7 @@ public: * @param aCookie The string object which will hold the result * @return Returns NS_OK if successful, or NS_FALSE if an error occurred. */ - NS_IMETHOD GetCookieStringFromHTTP(nsIURI *aURL, nsIURI *aFirstURL, nsString& aCookie)=0; + string getCookieStringFromHttp(in nsIURI aURL, in nsIURI aFirstURL); /* * Set the cookie string associated with the URL @@ -72,7 +59,7 @@ public: * @param aCookie The string to set * @return Returns NS_OK if successful, or NS_FALSE if an error occurred. */ - NS_IMETHOD SetCookieString(nsIURI *aURL, nsIDocument* aDoc, const nsString& aCookie)=0; + void setCookieString(in nsIURI aURL, in nsIPrompt aPrompt, in string aCookie); /* * Set the cookie string and expires associated with the URL @@ -85,31 +72,13 @@ public: * @param aExpires The expiry information of the cookie * @return Returns NS_OK if successful, or NS_FALSE if an error occurred. */ - NS_IMETHOD SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, nsIPrompt *aPrompter, const char *aCookie, const char *aExpires)=0; + void setCookieStringFromHttp(in nsIURI aURL, in nsIURI aFirstURL, in nsIPrompt aPrompter, in string aCookie, in string aExpires); - /* - * Blows away all permissions currently in the cookie permissions list, - * and then blows away all cookies currently in the cookie list. - */ - NS_IMETHOD Cookie_RemoveAllCookies(void)=0; - - /* - * Interface routines for cookie viewer - */ - NS_IMETHOD Cookie_CookieViewerReturn(nsAutoString results)=0; - NS_IMETHOD Cookie_GetCookieListForViewer(nsString& aCookieList)=0; - NS_IMETHOD Cookie_GetPermissionListForViewer(nsString& aPermissionList, PRInt32 type)=0; - NS_IMETHOD Image_Block(nsAutoString imageURL)=0; - NS_IMETHOD Permission_Add(nsString imageURL, PRBool permission, PRInt32 type)=0; - NS_IMETHOD Image_CheckForPermission - (char * hostname, char * firstHostname, PRBool &permission)=0; - - /* - * Specifies whether cookies will be accepted or not. - * XXX This method can be refined to return more specific information - * (i.e. whether we accept foreign cookies or not, etc.) if necessary. - */ - NS_IMETHOD CookieEnabled(PRBool* aEnabled)=0; }; -#endif /* nsICookieService_h__ */ +%{ C++ +// {AB397774-12D3-11d3-8AD1-00105A1B8860} +#define NS_COOKIESERVICE_CID \ +{ 0xab397774, 0x12d3, 0x11d3, { 0x8a, 0xd1, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } } +#define NS_COOKIESERVICE_CONTRACTID "@mozilla.org/cookieService;1" +%} diff --git a/mozilla/extensions/cookie/nsIImgManager.idl b/mozilla/extensions/cookie/nsIImgManager.idl new file mode 100644 index 00000000000..e8bc70617a0 --- /dev/null +++ b/mozilla/extensions/cookie/nsIImgManager.idl @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* + + This file contains an interface to the Image Manager. + + */ + +#include "nsISupports.idl" + +[scriptable, uuid(D60B3710-166D-11d5-A542-0010A401EB10)] +interface nsIImgManager : nsISupports +{ + void block(in string imageURL); + boolean checkForPermission(in string hostname, in string firstHostname); +}; + +%{ C++ +// {D60B3710-166D-11d5-A542-0010A401EB10} +#define NS_IMGMANAGER_CID \ +{ 0xd60b3710, 0x166d, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } } +#define NS_IMGMANAGER_CONTRACTID "@mozilla.org/imgmanager;1" +%} diff --git a/mozilla/extensions/cookie/nsIPermission.idl b/mozilla/extensions/cookie/nsIPermission.idl new file mode 100644 index 00000000000..74f22d1e212 --- /dev/null +++ b/mozilla/extensions/cookie/nsIPermission.idl @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + + * The Original Code is mozilla.org code. + + * The Initial Developer of the Original Code is Netscape + * Communications, Inc. Portions created by Netscape are + * Copyright (C) 2001, Mozilla. All Rights Reserved. + + * Contributor(s): + */ + +#include "nsISupports.idl" + +[scriptable, uuid(28F16D80-157B-11d5-A542-0010A401EB10)] + +/** + This interface represents a "permission" object. +*/ + +interface nsIPermission : nsISupports { + + /* the name of the host */ + readonly attribute string host; + + /* the type of permission (e.g., cookie, image, etc) */ + readonly attribute PRInt32 type; + + /* the permission */ + readonly attribute boolean capability; +}; + +%{ C++ +// {28F16D80-157B-11d5-A542-0010A401EB10} +#define NS_PERMISSION_CID \ +{ 0x28f16d80, 0x157b, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } } +#define NS_PERMISSION_CONTRACTID "@mozilla.org/permission;1" +%} diff --git a/mozilla/extensions/cookie/nsIPermissionManager.idl b/mozilla/extensions/cookie/nsIPermissionManager.idl new file mode 100644 index 00000000000..6aa4137de89 --- /dev/null +++ b/mozilla/extensions/cookie/nsIPermissionManager.idl @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +/* + + This file contains an interface to the Permission Manager. + + */ + +#include "nsISupports.idl" +#include "nsIEnumerator.idl" + +[scriptable, uuid(4F6B5E00-0C36-11d5-A535-0010A401EB10)] +interface nsIPermissionManager : nsISupports +{ + void add(in string objectURL, in boolean permission, in PRInt32 type); + void removeAll(); + readonly attribute nsISimpleEnumerator enumerator; + void remove(in string host, in PRInt32 type); +}; + +%{ C++ +// {4F6B5E00-0C36-11d5-A535-0010A401EB10} +#define NS_PERMISSIONMANAGER_CID \ +{ 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } } +#define NS_PERMISSIONMANAGER_CONTRACTID "@mozilla.org/permissionmanager;1" +%} diff --git a/mozilla/extensions/cookie/nsImages.cpp b/mozilla/extensions/cookie/nsImages.cpp new file mode 100644 index 00000000000..d1853ea9606 --- /dev/null +++ b/mozilla/extensions/cookie/nsImages.cpp @@ -0,0 +1,186 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsPermissions.h" +#include "nsUtils.h" + +#include "nsVoidArray.h" +#include "xp_core.h" +#include "prmem.h" +#include "nsIPref.h" +#include "nsTextFormatter.h" + +#define image_behaviorPref "network.image.imageBehavior" +#define image_warningPref "network.image.warnAboutImages" + +typedef struct _permission_HostStruct { + char * host; + nsVoidArray * permissionList; +} permission_HostStruct; + +typedef struct _permission_TypeStruct { + PRInt32 type; + PRBool permission; +} permission_TypeStruct; + +PRIVATE PERMISSION_BehaviorEnum image_behavior = PERMISSION_Accept; +PRIVATE PRBool image_warning = PR_FALSE; + +PRIVATE void +image_SetBehaviorPref(PERMISSION_BehaviorEnum x) { + image_behavior = x; +} + +PRIVATE void +image_SetWarningPref(PRBool x) { + image_warning = x; +} + +PRIVATE PERMISSION_BehaviorEnum +image_GetBehaviorPref() { + return image_behavior; +} + +PRIVATE PRBool +image_GetWarningPref() { + return image_warning; +} + +MODULE_PRIVATE int PR_CALLBACK +image_BehaviorPrefChanged(const char * newpref, void * data) { + PRInt32 n; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetIntPref(image_behaviorPref, &n))) { + image_SetBehaviorPref(PERMISSION_Accept); + } else { + image_SetBehaviorPref((PERMISSION_BehaviorEnum)n); + } + return 0; +} + +MODULE_PRIVATE int PR_CALLBACK +image_WarningPrefChanged(const char * newpref, void * data) { + PRBool x; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(prefs->GetBoolPref(image_warningPref, &x))) { + x = PR_FALSE; + } + image_SetWarningPref(x); + return 0; +} + +PUBLIC void +IMAGE_RegisterPrefCallbacks(void) { + PRInt32 n; + PRBool x; + nsresult rv; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + + // Initialize for image_behaviorPref + if (NS_FAILED(prefs->GetIntPref(image_behaviorPref, &n))) { + n = PERMISSION_Accept; + } + image_SetBehaviorPref((PERMISSION_BehaviorEnum)n); + prefs->RegisterCallback(image_behaviorPref, image_BehaviorPrefChanged, NULL); + + // Initialize for image_warningPref + if (NS_FAILED(prefs->GetBoolPref(image_warningPref, &x))) { + x = PR_FALSE; + } + image_SetWarningPref(x); + prefs->RegisterCallback(image_warningPref, image_WarningPrefChanged, NULL); +} + +PUBLIC nsresult +IMAGE_CheckForPermission + (const char * hostname, const char * firstHostname, PRBool *permission) { + + /* exit if imageblocker is not enabled */ + nsresult rv; + PRBool prefvalue = PR_FALSE; + NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_CONTRACTID, &rv); + if (NS_FAILED(rv) || + NS_FAILED(prefs->GetBoolPref("imageblocker.enabled", &prefvalue)) || + !prefvalue) { + *permission = (image_GetBehaviorPref() != PERMISSION_DontUse); + return NS_OK; + } + + /* try to make a decision based on pref settings */ + if ((image_GetBehaviorPref() == PERMISSION_DontUse)) { + *permission = PR_FALSE; + return NS_OK; + } + if (image_GetBehaviorPref() == PERMISSION_DontAcceptForeign) { + /* compare tails of names checking to see if they have a common domain */ + /* we do this by comparing the tails of both names where each tail includes at least one dot */ + PRInt32 dotcount = 0; + const char * tailHostname = hostname + PL_strlen(hostname) - 1; + while (tailHostname > hostname) { + if (*tailHostname == '.') { + dotcount++; + } + if (dotcount == 2) { + tailHostname++; + break; + } + tailHostname--; + } + dotcount = 0; + const char * tailFirstHostname = firstHostname + PL_strlen(firstHostname) - 1; + while (tailFirstHostname > firstHostname) { + if (*tailFirstHostname == '.') { + dotcount++; + } + if (dotcount == 2) { + tailFirstHostname++; + break; + } + tailFirstHostname--; + } + if (PL_strcmp(tailFirstHostname, tailHostname)) { + *permission = PR_FALSE; + return NS_OK; + } + } + + /* use common routine to make decision */ + PRUnichar * message = CKutil_Localize(NS_LITERAL_STRING("PermissionToAcceptImage").get()); + PRUnichar * new_string = nsTextFormatter::smprintf(message, hostname ? hostname : ""); + *permission = Permission_Check(0, hostname, IMAGEPERMISSION, + image_GetWarningPref(), new_string); + PR_FREEIF(new_string); + Recycle(message); + return NS_OK; +} + +PUBLIC nsresult +IMAGE_Block(const char* imageURL) { + if (!imageURL || !(*imageURL)) { + return NS_ERROR_NULL_POINTER; + } + char *host = CKutil_ParseURL(imageURL, GET_HOST_PART); + Permission_AddHost(host, PR_FALSE, IMAGEPERMISSION, PR_TRUE); + return NS_OK; +} diff --git a/mozilla/extensions/cookie/nsImages.h b/mozilla/extensions/cookie/nsImages.h new file mode 100644 index 00000000000..d8d6040bd88 --- /dev/null +++ b/mozilla/extensions/cookie/nsImages.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef IMAGES_H +#define IMAGES_H + +#include "nsString.h" + +extern nsresult IMAGE_CheckForPermission + (const char * hostname, const char * firstHostname, PRBool *permission); +extern nsresult IMAGE_Block(const char * imageURL); +extern void IMAGE_RegisterPrefCallbacks(void); + +#endif /* IMAGES_H */ diff --git a/mozilla/extensions/cookie/nsImgManager.cpp b/mozilla/extensions/cookie/nsImgManager.cpp new file mode 100644 index 00000000000..554c094dcc5 --- /dev/null +++ b/mozilla/extensions/cookie/nsImgManager.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsImgManager.h" +#include "nsImages.h" + +//////////////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////////////// +// nsImgManager Implementation + +NS_IMPL_ISUPPORTS1(nsImgManager, nsIImgManager); + +nsImgManager::nsImgManager() +{ + NS_INIT_REFCNT(); +} + +nsImgManager::~nsImgManager(void) +{ +} + +nsresult nsImgManager::Init() +{ + IMAGE_RegisterPrefCallbacks(); + return NS_OK; +} + + +NS_IMETHODIMP nsImgManager::Block(const char * imageURL) { + ::IMAGE_Block(imageURL); + return NS_OK; +} + +NS_IMETHODIMP nsImgManager::CheckForPermission + (const char * hostname, const char * firstHostname, PRBool *permission) { + return ::IMAGE_CheckForPermission(hostname, firstHostname, permission); +} diff --git a/mozilla/extensions/cookie/nsImgManager.h b/mozilla/extensions/cookie/nsImgManager.h new file mode 100644 index 00000000000..005e8e311d2 --- /dev/null +++ b/mozilla/extensions/cookie/nsImgManager.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsImgManager_h__ +#define nsImgManager_h__ + +#include "nsIImgManager.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsImgManager : public nsIImgManager { +public: + + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSIIMGMANAGER + + nsImgManager(); + virtual ~nsImgManager(void); + nsresult Init(); + +}; + +#endif /* nsImgManager_h__ */ diff --git a/mozilla/extensions/cookie/nsModuleFactory.cpp b/mozilla/extensions/cookie/nsModuleFactory.cpp new file mode 100644 index 00000000000..69d3fa0f8e2 --- /dev/null +++ b/mozilla/extensions/cookie/nsModuleFactory.cpp @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + + +#include "nsIModule.h" +#include "nsIGenericFactory.h" +#include "nsCookie.h" +#include "nsPermission.h" +#include "nsCookieManager.h" +#include "nsCookieService.h" +#include "nsImgManager.h" +#include "nsPermissionManager.h" +#include "nsCookieHTTPNotify.h" + +// Define the constructor function for the objects +NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookie) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsPermission) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieManager, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieService, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsImgManager, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPermissionManager, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieHTTPNotify, Init) + +// The list of components we register +static nsModuleComponentInfo components[] = { + { "Cookie", + NS_COOKIE_CID, + NS_COOKIE_CONTRACTID, + nsCookieConstructor + }, + { "Permission", + NS_PERMISSION_CID, + NS_PERMISSION_CONTRACTID, + nsPermissionConstructor + }, + { "CookieManager", + NS_COOKIEMANAGER_CID, + NS_COOKIEMANAGER_CONTRACTID, + nsCookieManagerConstructor + }, + { "CookieService", + NS_COOKIESERVICE_CID, + NS_COOKIESERVICE_CONTRACTID, + nsCookieServiceConstructor + }, + { "ImgManager", + NS_IMGMANAGER_CID, + NS_IMGMANAGER_CONTRACTID, + nsImgManagerConstructor + }, + { "PermissionManager", + NS_PERMISSIONMANAGER_CID, + NS_PERMISSIONMANAGER_CONTRACTID, + nsPermissionManagerConstructor + }, + { NS_COOKIEHTTPNOTIFY_CLASSNAME, + NS_COOKIEHTTPNOTIFY_CID, + NS_COOKIEHTTPNOTIFY_CONTRACTID, + nsCookieHTTPNotifyConstructor, + nsCookieHTTPNotify::RegisterProc, + nsCookieHTTPNotify::UnregisterProc + }, +}; + +NS_IMPL_NSGETMODULE("nsCookieModule", components) diff --git a/mozilla/extensions/cookie/nsPermission.cpp b/mozilla/extensions/cookie/nsPermission.cpp new file mode 100644 index 00000000000..f1ef040a613 --- /dev/null +++ b/mozilla/extensions/cookie/nsPermission.cpp @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsPermission.h" +#include "nsString.h" +#include "prmem.h" + +// nsPermission Implementation + +NS_IMPL_ISUPPORTS2(nsPermission, nsIPermission, nsISupportsWeakReference); + +nsPermission::nsPermission() { + NS_INIT_REFCNT(); +} + +nsPermission::nsPermission + (char * host, + PRInt32 type, + PRBool capability) { + permissionHost = host; + permissionType = type; + permissionCapability = capability; + NS_INIT_REFCNT(); +} + +nsPermission::~nsPermission(void) { + nsCRT::free(permissionHost); +} + +NS_IMETHODIMP nsPermission::GetHost(char * *aHost) { + if (permissionHost) { + *aHost = (char *) nsMemory::Clone(permissionHost, nsCRT::strlen(permissionHost) + 1); + return NS_OK; + } + return NS_ERROR_NULL_POINTER; +} + +NS_IMETHODIMP nsPermission::GetType(PRInt32 *aType) { + *aType = permissionType; + return NS_OK; +} + +NS_IMETHODIMP nsPermission::GetCapability(PRBool *aCapability) { + *aCapability = permissionCapability; + return NS_OK; +} diff --git a/mozilla/extensions/cookie/nsPermission.h b/mozilla/extensions/cookie/nsPermission.h new file mode 100644 index 00000000000..60d77387811 --- /dev/null +++ b/mozilla/extensions/cookie/nsPermission.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsPermission_h__ +#define nsPermission_h__ + +#include "nsIPermission.h" +#include "nsWeakReference.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsPermission : public nsIPermission, + public nsSupportsWeakReference { +public: + + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSIPERMISSION + + // Note: following constructor takes ownership of the host string so the caller + // of the constructor must not free them + nsPermission(char * host, PRInt32 type, PRBool capability); + nsPermission(); + virtual ~nsPermission(void); + +protected: + char * permissionHost; + PRInt32 permissionType; + PRBool permissionCapability; +}; + +#endif /* nsPermission_h__ */ diff --git a/mozilla/extensions/cookie/nsPermissionManager.cpp b/mozilla/extensions/cookie/nsPermissionManager.cpp new file mode 100644 index 00000000000..10f161292ed --- /dev/null +++ b/mozilla/extensions/cookie/nsPermissionManager.cpp @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsIServiceManager.h" +#include "nsPermissionManager.h" +#include "nsCRT.h" +#include "nsPermissions.h" +#include "nsIGenericFactory.h" +#include "nsXPIDLString.h" +#include "nsIScriptGlobalObject.h" +#include "nsIDOMWindowInternal.h" +#include "nsIPrompt.h" +#include "nsIObserverService.h" +#include "nsPermission.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsPermissionEnumerator : public nsISimpleEnumerator +{ + public: + + NS_DECL_ISUPPORTS + + nsPermissionEnumerator() : mHostCount(0), mTypeCount(0) + { + NS_INIT_REFCNT(); + } + + NS_IMETHOD HasMoreElements(PRBool *result) + { + *result = PERMISSION_HostCount() > mHostCount; + return NS_OK; + } + + NS_IMETHOD GetNext(nsISupports **result) + { + char *host; + PRBool capability; + PRInt32 type; + (void) PERMISSION_Enumerate + (mHostCount, mTypeCount++, &host, &type, &capability); + if (mTypeCount == PERMISSION_TypeCount(mHostCount)) { + mTypeCount = 0; + mHostCount++; + } + nsIPermission *permission = + new nsPermission(host, type, capability); + *result = permission; + NS_ADDREF(*result); + return NS_OK; + } + + virtual ~nsPermissionEnumerator() + { + } + + protected: + PRInt32 mHostCount; + PRInt32 mTypeCount; +}; + +NS_IMPL_ISUPPORTS1(nsPermissionEnumerator, nsISimpleEnumerator); + +//////////////////////////////////////////////////////////////////////////////// +// nsPermissionManager Implementation + +NS_IMPL_ISUPPORTS3(nsPermissionManager, nsIPermissionManager, nsIObserver, nsISupportsWeakReference); + +nsPermissionManager::nsPermissionManager() +{ + NS_INIT_REFCNT(); +} + +nsPermissionManager::~nsPermissionManager(void) +{ + PERMISSION_RemoveAll(); +} + +nsresult nsPermissionManager::Init() +{ + PERMISSION_Read(); + + nsresult rv; + NS_WITH_SERVICE(nsIObserverService, observerService, NS_OBSERVERSERVICE_CONTRACTID, &rv); + if (observerService) { + observerService->AddObserver(this, NS_LITERAL_STRING("profile-before-change").get()); + observerService->AddObserver(this, NS_LITERAL_STRING("profile-do-change").get()); + } + + return NS_OK; +} + +NS_IMETHODIMP nsPermissionManager::Add + (const char * objectURL, PRBool permission, PRInt32 type) { + ::PERMISSION_Add(objectURL, permission, type); + return NS_OK; +} + +NS_IMETHODIMP nsPermissionManager::RemoveAll(void) { + ::PERMISSION_RemoveAll(); + return NS_OK; +} + +NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator * *entries) +{ + *entries = nsnull; + + nsPermissionEnumerator* permissionEnum = new nsPermissionEnumerator(); + if (permissionEnum == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(permissionEnum); + *entries = permissionEnum; + return NS_OK; +} + +NS_IMETHODIMP nsPermissionManager::Remove(const char* host, PRInt32 type) { + ::PERMISSION_Remove(host, type); + return NS_OK; +} + +NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData) +{ + nsresult rv = NS_OK; + + if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-before-change").get())) { + // The profile is about to change. + + // Dump current permission. This will be done by calling + // PERMISSION_RemoveAll which clears the memory-resident + // permission table. The reason the permission file does not + // need to be updated is because the file was updated every time + // the memory-resident table changed (i.e., whenever a new permission + // was accepted). If this condition ever changes, the permission + // file would need to be updated here. + + PERMISSION_RemoveAll(); + if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) + PERMISSION_DeletePersistentUserData(); + } + else if (!nsCRT::strcmp(aTopic, NS_LITERAL_STRING("profile-do-change").get())) { + // The profile has aleady changed. + // Now just read them from the new profile location. + PERMISSION_Read(); + } + + return rv; +} diff --git a/mozilla/extensions/cookie/nsPermissionManager.h b/mozilla/extensions/cookie/nsPermissionManager.h new file mode 100644 index 00000000000..de47267eb43 --- /dev/null +++ b/mozilla/extensions/cookie/nsPermissionManager.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsPermissionManager_h__ +#define nsPermissionManager_h__ + +#include "nsIPermissionManager.h" +#include "nsIObserver.h" +#include "nsWeakReference.h" + +//////////////////////////////////////////////////////////////////////////////// + +class nsPermissionManager : public nsIPermissionManager, + public nsIObserver, + public nsSupportsWeakReference { +public: + + // nsISupports + NS_DECL_ISUPPORTS + NS_DECL_NSIPERMISSIONMANAGER + NS_DECL_NSIOBSERVER + + nsPermissionManager(); + virtual ~nsPermissionManager(void); + nsresult Init(); + +}; + +#endif /* nsPermissionManager_h__ */ diff --git a/mozilla/extensions/cookie/nsPermissions.cpp b/mozilla/extensions/cookie/nsPermissions.cpp new file mode 100644 index 00000000000..11544167073 --- /dev/null +++ b/mozilla/extensions/cookie/nsPermissions.cpp @@ -0,0 +1,697 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf + * Henrik Gemal + */ + +#define alphabetize 1 + +#include "nsPermissions.h" +#include "nsUtils.h" +#include "nsXPIDLString.h" +#include "nsIFileSpec.h" +#include "nsINetSupportDialogService.h" +#include "nsVoidArray.h" +#include "xp_core.h" +#include "prmem.h" +#include "nsAppDirectoryServiceDefs.h" + +static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID); +static const char *kCookiesPermFileName = "cookperm.txt"; + +typedef struct _permission_HostStruct { + char * host; + nsVoidArray * permissionList; +} permission_HostStruct; + +typedef struct _permission_TypeStruct { + PRInt32 type; + PRBool permission; +} permission_TypeStruct; + +PRIVATE PRBool permission_changed = PR_FALSE; + +PRIVATE PRBool cookie_rememberChecked; +PRIVATE PRBool image_rememberChecked; + +PRIVATE nsVoidArray * permission_list=0; + +PRBool +permission_CheckConfirmYN(nsIPrompt *aPrompter, PRUnichar * szMessage, PRUnichar * szCheckMessage, PRBool* checkValue) { + + nsresult res; + nsCOMPtr dialog; + + if (aPrompter) + dialog = aPrompter; + else + dialog = do_GetService(kNetSupportDialogCID); + if (!dialog) { + *checkValue = 0; + return PR_FALSE; + } + + PRInt32 buttonPressed = 1; /* in case user exits dialog by clickin X */ + PRUnichar * yes_string = CKutil_Localize(NS_LITERAL_STRING("Yes").get()); + PRUnichar * no_string = CKutil_Localize(NS_LITERAL_STRING("No").get()); + PRUnichar * confirm_string = CKutil_Localize(NS_LITERAL_STRING("Confirm").get()); + + nsAutoString tempStr; tempStr.AssignWithConversion("chrome://global/skin/question-icon.gif"); + res = dialog->UniversalDialog( + NULL, /* title message */ + confirm_string, /* title text in top line of window */ + szMessage, /* this is the main message */ + szCheckMessage, /* This is the checkbox message */ + yes_string, /* first button text */ + no_string, /* second button text */ + NULL, /* third button text */ + NULL, /* fourth button text */ + NULL, /* first edit field label */ + NULL, /* second edit field label */ + NULL, /* first edit field initial and final value */ + NULL, /* second edit field initial and final value */ + tempStr.GetUnicode() , + checkValue, /* initial and final value of checkbox */ + 2, /* number of buttons */ + 0, /* number of edit fields */ + 0, /* is first edit field a password field */ + &buttonPressed); + + if (NS_FAILED(res)) { + *checkValue = 0; + } + if (*checkValue!=0 && *checkValue!=1) { + *checkValue = 0; /* this should never happen but it is happening!!! */ + } + Recycle(yes_string); + Recycle(no_string); + Recycle(confirm_string); + return (buttonPressed == 0); +} + +/* + * search if permission already exists + */ +nsresult +permission_CheckFromList(const char * hostname, PRBool &permission, PRInt32 type) { + permission_HostStruct * hostStruct; + permission_TypeStruct * typeStruct; + + /* ignore leading period in host name */ + while (hostname && (*hostname == '.')) { + hostname++; + } + + /* return if permission_list does not exist */ + if (permission_list == nsnull) { + return NS_ERROR_FAILURE; + } + + /* find host name within list */ + PRInt32 hostCount = permission_list->Count(); + for (PRInt32 i = 0; i < hostCount; ++i) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); + if (hostStruct) { + if(hostname && hostStruct->host && !PL_strcasecmp(hostname, hostStruct->host)) { + + /* search for type in the permission list for this host */ + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); + if (typeStruct->type == type) { + + /* type found. Obtain the corresponding permission */ + permission = typeStruct->permission; + return NS_OK; + } + } + + /* type not found, return failure */ + return NS_ERROR_FAILURE; + } + } + } + + /* not found, return failure */ + return NS_ERROR_FAILURE; +} + +PRBool +permission_GetRememberChecked(PRInt32 type) { + if (type == COOKIEPERMISSION) { + return cookie_rememberChecked; + } else if (type == IMAGEPERMISSION) { + return image_rememberChecked; + } else { + return PR_FALSE; + } +} + +void +permission_SetRememberChecked(PRInt32 type, PRBool value) { + if (type == COOKIEPERMISSION) { + cookie_rememberChecked = value; + } else if (type == IMAGEPERMISSION) { + image_rememberChecked = value; + } +} + +PUBLIC PRBool +Permission_Check( + nsIPrompt *aPrompter, + const char * hostname, + PRInt32 type, + PRBool warningPref, + PRUnichar * message) +{ + PRBool permission; + + /* try to make decision based on saved permissions */ + if (NS_SUCCEEDED(permission_CheckFromList(hostname, permission, type))) { + return permission; + } + + /* see if we need to prompt */ + if(!warningPref) { + return PR_TRUE; + } + + /* we need to prompt */ + PRBool rememberChecked = permission_GetRememberChecked(type); + PRUnichar * remember_string = CKutil_Localize(NS_LITERAL_STRING("RememberThisDecision").get()); + permission = permission_CheckConfirmYN(aPrompter, message, remember_string, &rememberChecked); + + /* see if we need to remember this decision */ + if (rememberChecked) { + char * hostname2 = NULL; + /* ignore leading periods in host name */ + const char * hostnameAfterDot = hostname; + while (hostnameAfterDot && (*hostnameAfterDot == '.')) { + hostnameAfterDot++; + } + CKutil_StrAllocCopy(hostname2, hostnameAfterDot); + Permission_AddHost(hostname2, permission, type, PR_TRUE); + } + if (rememberChecked != permission_GetRememberChecked(type)) { + permission_SetRememberChecked(type, rememberChecked); + permission_changed = PR_TRUE; + Permission_Save(); + } + return permission; +} + +PUBLIC nsresult +Permission_AddHost(char * host, PRBool permission, PRInt32 type, PRBool save) { + /* create permission list if it does not yet exist */ + if(!permission_list) { + permission_list = new nsVoidArray(); + if(!permission_list) { + Recycle(host); + return NS_ERROR_FAILURE; + } + } + + /* find existing entry for host */ + permission_HostStruct * hostStruct; + PRBool HostFound = PR_FALSE; + PRInt32 hostCount = permission_list->Count(); + PRInt32 i; + for (i = 0; i < hostCount; ++i) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); + if (hostStruct) { + if (PL_strcasecmp(host,hostStruct->host)==0) { + + /* host found in list */ + Recycle(host); + HostFound = PR_TRUE; + break; +#ifdef alphabetize + } else if (PL_strcasecmp(host, hostStruct->host) < 0) { + + /* need to insert new entry here */ + break; +#endif + } + } + } + + if (!HostFound) { + + /* create a host structure for the host */ + hostStruct = PR_NEW(permission_HostStruct); + if (!hostStruct) { + Recycle(host); + return NS_ERROR_FAILURE; + } + hostStruct->host = host; + hostStruct->permissionList = new nsVoidArray(); + if(!hostStruct->permissionList) { + PR_Free(hostStruct); + Recycle(host); + return NS_ERROR_FAILURE; + } + + /* insert host structure into the list */ + if (i == permission_list->Count()) { + permission_list->AppendElement(hostStruct); + } else { + permission_list->InsertElementAt(hostStruct, i); + } + } + + /* see if host already has an entry for this type */ + permission_TypeStruct * typeStruct; + PRBool typeFound = PR_FALSE; + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); + if (typeStruct->type == type) { + + /* type found. Modify the corresponding permission */ + typeStruct->permission = permission; + typeFound = PR_TRUE; + break; + } + } + + /* create a type structure and attach it to the host structure */ + if (!typeFound) { + typeStruct = PR_NEW(permission_TypeStruct); + typeStruct->type = type; + typeStruct->permission = permission; + hostStruct->permissionList->AppendElement(typeStruct); + } + + /* write the changes out to a file */ + if (save) { + permission_changed = PR_TRUE; + Permission_Save(); + } + return NS_OK; +} + +PRIVATE void +permission_Unblock(char * host, PRInt32 type) { + + /* nothing to do if permission list does not exist */ + if(!permission_list) { + return; + } + + /* find existing entry for host */ + permission_HostStruct * hostStruct; + PRInt32 hostCount = permission_list->Count(); + for (PRInt32 hostIndex = 0; hostIndex < hostCount; ++hostIndex) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(hostIndex)); + if (hostStruct && PL_strcasecmp(host, hostStruct->host)==0) { + /* host found in list, see if it has an entry for this type */ + permission_TypeStruct * typeStruct; + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); + if (typeStruct && typeStruct->type == type) { + /* type found. Remove the permission if it is PR_FALSE */ + if (typeStruct->permission == PR_FALSE) { + hostStruct->permissionList->RemoveElementAt(typeIndex); + /* if no more types are present, remove the entry */ + typeCount = hostStruct->permissionList->Count(); + if (typeCount == 0) { + PR_FREEIF(hostStruct->permissionList); + permission_list->RemoveElementAt(hostIndex); + PR_FREEIF(hostStruct->host); + PR_Free(hostStruct); + } + permission_changed = PR_TRUE; + Permission_Save(); + return; + } + break; + } + } + break; + } + } + return; +} + +/* saves the permissions to disk */ +PUBLIC void +Permission_Save() { + permission_HostStruct * hostStruct; + permission_TypeStruct * typeStruct; + + if (!permission_changed) { + return; + } + if (permission_list == nsnull) { + return; + } + nsFileSpec dirSpec; + nsresult rval = CKutil_ProfileDirectory(dirSpec); + if (NS_FAILED(rval)) { + return; + } + nsOutputFileStream strm(dirSpec + kCookiesPermFileName); + if (!strm.is_open()) { + return; + } + + strm.write("# HTTP Permission File\n", 30); + strm.write("# http://www.netscape.com/newsref/std/cookie_spec.html\n", 55); + strm.write("# This is a generated file! Do not edit.\n\n", 43); + + /* format shall be: + * host \t permission \t permission ... \n + */ + + + PRInt32 hostCount = permission_list->Count(); + for (PRInt32 i = 0; i < hostCount; ++i) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); + if (hostStruct) { + strm.write(hostStruct->host, nsCRT::strlen(hostStruct->host)); + + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 typeIndex=0; typeIndexpermissionList->ElementAt(typeIndex)); + strm.write("\t", 1); + nsCAutoString tmp; tmp.AppendInt(typeStruct->type); + strm.write(tmp.get(), tmp.Length()); + if (typeStruct->permission) { + strm.write("T", 1); + } else { + strm.write("F", 1); + } + } + strm.write("\n", 1); + } + } + + /* save current state of nag boxs' checkmarks */ + strm.write("@@@@", 4); + for (PRInt32 type = 0; type < NUMBER_OF_PERMISSIONS; type++) { + strm.write("\t", 1); + nsCAutoString tmp; tmp.AppendInt(type); + strm.write(tmp.get(), tmp.Length()); + if (permission_GetRememberChecked(type)) { + strm.write("T", 1); + } else { + strm.write("F", 1); + } + } + + strm.write("\n", 1); + + permission_changed = PR_FALSE; + strm.flush(); + strm.close(); +} + +/* reads the permissions from disk */ +PUBLIC nsresult +PERMISSION_Read() { + if (permission_list) { + return NS_OK; + } + nsAutoString buffer; + nsFileSpec dirSpec; + nsresult rv = CKutil_ProfileDirectory(dirSpec); + if (NS_FAILED(rv)) { + return rv; + } + nsInputFileStream strm(dirSpec + kCookiesPermFileName); + if (!strm.is_open()) { + /* file doesn't exist -- that's not an error */ + for (PRInt32 type=0; type= '0' && c <= '9') { + type = 10*type + (c-'0'); + c = (char)permissionString.CharAt(++index); + } + if (index >= permissionString.Length()) { + continue; /* bad format for this permission entry */ + } + PRBool permission = (permissionString.CharAt(index) == 'T'); + + /* + * a host value of "@@@@" is a special code designating the + * state of the nag-box's checkmark + */ + if (host.EqualsWithConversion("@@@@")) { + if (!permissionString.IsEmpty()) { + permission_SetRememberChecked(type, permission); + } + } else { + if (!permissionString.IsEmpty()) { + rv = Permission_AddHost(host.ToNewCString(), permission, type, PR_FALSE); + if (NS_FAILED(rv)) { + strm.close(); + return rv; + } + } + } + } + } + + strm.close(); + permission_changed = PR_FALSE; + return NS_OK; +} + +PUBLIC PRInt32 +PERMISSION_HostCount() { + if (!permission_list) { + return 0; + } + return permission_list->Count(); +} + +PUBLIC PRInt32 +PERMISSION_TypeCount(PRInt32 host) { + if (!permission_list) { + return 0; + } + + permission_HostStruct *hostStruct; + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(host)); + NS_ASSERTION(hostStruct, "corrupt permission list"); + return hostStruct->permissionList->Count(); +} + +PUBLIC void +PERMISSION_Enumerate + (PRInt32 hostNumber, PRInt32 typeNumber, char **host, PRInt32 *type, PRBool *capability) { + permission_HostStruct *hostStruct; + permission_TypeStruct * typeStruct; + + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(hostNumber)); + NS_ASSERTION(hostStruct, "corrupt permission list"); + char * copyOfHost = NULL; + CKutil_StrAllocCopy(copyOfHost, hostStruct->host); + *host = copyOfHost; + + typeStruct = NS_STATIC_CAST + (permission_TypeStruct*, hostStruct->permissionList->ElementAt(typeNumber)); + *capability = typeStruct->permission; + *type = typeStruct->type; +} + +PRIVATE void +permission_remove (PRInt32 hostNumber, PRInt32 type) { + if (!permission_list) { + return; + } + permission_HostStruct * hostStruct; + hostStruct = + NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(hostNumber)); + if (!hostStruct) { + return; + } + permission_TypeStruct * typeStruct; + typeStruct = + NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList->ElementAt(type)); + if (!typeStruct) { + return; + } + hostStruct->permissionList->RemoveElementAt(type); + permission_changed = PR_TRUE; + + /* if no types are present, remove the entry */ + PRInt32 typeCount = hostStruct->permissionList->Count(); + if (typeCount == 0) { + PR_FREEIF(hostStruct->permissionList); + permission_list->RemoveElementAt(hostNumber); + PR_FREEIF(hostStruct->host); + PR_Free(hostStruct); + } +} + +PUBLIC void +PERMISSION_Remove(const char* host, PRInt32 type) { + + /* get to the indicated host in the list */ + if (permission_list) { + PRInt32 hostCount = permission_list->Count(); + permission_HostStruct * hostStruct; + while (hostCount>0) { + hostCount--; + hostStruct = + NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(hostCount)); + NS_ASSERTION(hostStruct, "corrupt permission list"); + if ((PL_strcmp(hostStruct->host, host) == 0)) { + + /* get to the indicated permission in the list */ + PRInt32 typeCount = hostStruct->permissionList->Count(); + permission_TypeStruct * typeStruct; + while (typeCount>0) { + typeCount--; + typeStruct = + NS_STATIC_CAST + (permission_TypeStruct*, hostStruct->permissionList->ElementAt(typeCount)); + NS_ASSERTION(typeStruct, "corrupt permission list"); + if (typeStruct->type == type) { + permission_remove(hostCount, typeCount); + permission_changed = PR_TRUE; + Permission_Save(); + break; + } + } + break; + } + } + } +} + +/* blows away all permissions currently in the list */ +PUBLIC void +PERMISSION_RemoveAll() { + + if (permission_list) { + permission_HostStruct * hostStruct; + PRInt32 hostCount = permission_list->Count(); + for (PRInt32 i = hostCount-1; i >=0; i--) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 typeIndex = typeCount-1; typeIndex >=0; typeIndex--) { + permission_remove(hostCount, typeCount); + } + } + delete permission_list; + permission_list = NULL; + } +} + +PUBLIC void +PERMISSION_DeletePersistentUserData(void) +{ + nsresult res; + + nsCOMPtr cookiesPermFile; + res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(cookiesPermFile)); + if (NS_SUCCEEDED(res)) { + res = cookiesPermFile->Append(kCookiesPermFileName); + if (NS_SUCCEEDED(res)) + (void) cookiesPermFile->Delete(PR_FALSE); + } +} + +PUBLIC void +PERMISSION_Add(const char * objectURL, PRBool permission, PRInt32 type) { + if (!objectURL) { + return; + } + char *host = CKutil_ParseURL(objectURL, GET_HOST_PART); + + /* + * if permission is false, it will be added to the permission list + * if permission is true, any false permissions will be removed rather than a + * true permission being added + */ + if (permission) { + char * hostPtr = host; + while (PR_TRUE) { + permission_Unblock(hostPtr, type); + hostPtr = PL_strchr(hostPtr, '.'); + if (!hostPtr) { + break; + } + hostPtr++; /* get passed the period */ + } + Recycle(host); + return; + } + Permission_AddHost(host, permission, type, PR_TRUE); +} diff --git a/mozilla/extensions/cookie/nsPermissions.h b/mozilla/extensions/cookie/nsPermissions.h new file mode 100644 index 00000000000..d041e7313d2 --- /dev/null +++ b/mozilla/extensions/cookie/nsPermissions.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef PERMISSIONS_H +#define PERMISSIONS_H + +#include "nsString.h" + +#define COOKIEPERMISSION 0 +#define IMAGEPERMISSION 1 +#define NUMBER_OF_PERMISSIONS 2 + +typedef enum { + PERMISSION_Accept, + PERMISSION_DontAcceptForeign, + PERMISSION_DontUse +} PERMISSION_BehaviorEnum; + +class nsIPrompt; + +extern nsresult PERMISSION_Read(); +extern void PERMISSION_Add(const char * objectURL, PRBool permission, PRInt32 type); +extern void PERMISSION_RemoveAll(); +extern void PERMISSION_DeletePersistentUserData(void); + +extern PRInt32 PERMISSION_HostCount(); +extern PRInt32 PERMISSION_TypeCount(PRInt32 host); +extern void PERMISSION_Enumerate + (PRInt32 hostNumber, PRInt32 typeNumber, char **host, PRInt32 *type, PRBool *capability); +extern void PERMISSION_Remove(const char* host, PRInt32 type); + +extern PRBool Permission_Check + (nsIPrompt *aPrompter, const char * hostname, PRInt32 type, + PRBool warningPref, PRUnichar * message); +extern nsresult Permission_AddHost + (char * host, PRBool permission, PRInt32 type, PRBool save); +//extern void Permission_Free(PRInt32 hostNumber, PRInt32 type, PRBool save); +extern void Permission_Save(); + +#endif /* PERMISSIONS_H */ diff --git a/mozilla/extensions/cookie/nsUtils.cpp b/mozilla/extensions/cookie/nsUtils.cpp new file mode 100644 index 00000000000..c6cc137004e --- /dev/null +++ b/mozilla/extensions/cookie/nsUtils.cpp @@ -0,0 +1,331 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsUtils.h" +#include "xp_core.h" +#include "nsXPIDLString.h" +#include "nsIStringBundle.h" +#include "nsIPref.h" +#include "nsIFileSpec.h" +#include "nsAppDirectoryServiceDefs.h" +#include "prmem.h" + +static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); + +#define MAX_HOST_NAME_LEN 64 +#define BUFSIZE 128 +#define LOCALIZATION "chrome://communicator/locale/wallet/cookie.properties" + +nsresult +ckutil_getChar(nsInputFileStream& strm, char& c) { + static char buffer[BUFSIZE]; + static PRInt32 next = BUFSIZE, count = BUFSIZE; + + if (next == count) { + if (BUFSIZE > count) { // never say "count < ..." vc6.0 thinks this is a template beginning and crashes + next = BUFSIZE; + count = BUFSIZE; + return NS_ERROR_FAILURE; + } + count = strm.read(buffer, BUFSIZE); + next = 0; + if (count == 0) { + next = BUFSIZE; + count = BUFSIZE; + return NS_ERROR_FAILURE; + } + } + c = buffer[next++]; + return NS_OK; +} + +/* + * get a line from a file + * return -1 if end of file reached + * strip carriage returns and line feeds from end of line + */ +PUBLIC PRInt32 +CKutil_GetLine(nsInputFileStream& strm, nsString& aLine) { + + /* read the line */ + aLine.Truncate(); + char c; + for (;;) { + if NS_FAILED(ckutil_getChar(strm, c)) { + return -1; + } + if (c == '\n') { + break; + } + + if (c != '\r') { + aLine.AppendWithConversion(c); + } + } + return 0; +} + +PUBLIC char * +CKutil_ParseURL (const char *url, int parts_requested) { + char *rv=0,*colon, *slash, *ques_mark, *hash_mark; + char *atSign, *host, *passwordColon, *gtThan; + assert(url); + if(!url) { + return(CKutil_StrAllocCat(rv, "")); + } + colon = PL_strchr(url, ':'); /* returns a const char */ + /* Get the protocol part, not including anything beyond the colon */ + if (parts_requested & GET_PROTOCOL_PART) { + if(colon) { + char val = *(colon+1); + *(colon+1) = '\0'; + CKutil_StrAllocCopy(rv, url); + *(colon+1) = val; + /* If the user wants more url info, tack on extra slashes. */ + if( (parts_requested & GET_HOST_PART) + || (parts_requested & GET_USERNAME_PART) + || (parts_requested & GET_PASSWORD_PART)) { + if( *(colon+1) == '/' && *(colon+2) == '/') { + CKutil_StrAllocCat(rv, "//"); + } + /* If there's a third slash consider it file:/// and tack on the last slash. */ + if( *(colon+3) == '/' ) { + CKutil_StrAllocCat(rv, "/"); + } + } + } + } + + /* Get the username if one exists */ + if (parts_requested & GET_USERNAME_PART) { + if (colon && (*(colon+1) == '/') && (*(colon+2) == '/') && (*(colon+3) != '\0')) { + if ( (slash = PL_strchr(colon+3, '/')) != NULL) { + *slash = '\0'; + } + if ( (atSign = PL_strchr(colon+3, '@')) != NULL) { + *atSign = '\0'; + if ( (passwordColon = PL_strchr(colon+3, ':')) != NULL) { + *passwordColon = '\0'; + } + CKutil_StrAllocCat(rv, colon+3); + + /* Get the password if one exists */ + if (parts_requested & GET_PASSWORD_PART) { + if (passwordColon) { + CKutil_StrAllocCat(rv, ":"); + CKutil_StrAllocCat(rv, passwordColon+1); + } + } + if (parts_requested & GET_HOST_PART) { + CKutil_StrAllocCat(rv, "@"); + } + if (passwordColon) { + *passwordColon = ':'; + } + *atSign = '@'; + } + if (slash) { + *slash = '/'; + } + } + } + + /* Get the host part */ + if (parts_requested & GET_HOST_PART) { + if(colon) { + if(*(colon+1) == '/' && *(colon+2) == '/') { + slash = PL_strchr(colon+3, '/'); + if(slash) { + *slash = '\0'; + } + if( (atSign = PL_strchr(colon+3, '@')) != NULL) { + host = atSign+1; + } else { + host = colon+3; + } + ques_mark = PL_strchr(host, '?'); + if(ques_mark) { + *ques_mark = '\0'; + } + gtThan = PL_strchr(host, '>'); + if (gtThan) { + *gtThan = '\0'; + } + + /* limit hostnames to within MAX_HOST_NAME_LEN characters to keep from crashing */ + if(PL_strlen(host) > MAX_HOST_NAME_LEN) { + char * cp; + char old_char; + cp = host+MAX_HOST_NAME_LEN; + old_char = *cp; + *cp = '\0'; + CKutil_StrAllocCat(rv, host); + *cp = old_char; + } else { + CKutil_StrAllocCat(rv, host); + } + if(slash) { + *slash = '/'; + } + if(ques_mark) { + *ques_mark = '?'; + } + if (gtThan) { + *gtThan = '>'; + } + } + } + } + + /* Get the path part */ + if (parts_requested & GET_PATH_PART) { + if(colon) { + if(*(colon+1) == '/' && *(colon+2) == '/') { + /* skip host part */ + slash = PL_strchr(colon+3, '/'); + } else { + /* path is right after the colon */ + slash = colon+1; + } + if(slash) { + ques_mark = PL_strchr(slash, '?'); + hash_mark = PL_strchr(slash, '#'); + if(ques_mark) { + *ques_mark = '\0'; + } + if(hash_mark) { + *hash_mark = '\0'; + } + CKutil_StrAllocCat(rv, slash); + if(ques_mark) { + *ques_mark = '?'; + } + if(hash_mark) { + *hash_mark = '#'; + } + } + } + } + + if(parts_requested & GET_HASH_PART) { + hash_mark = PL_strchr(url, '#'); /* returns a const char * */ + if(hash_mark) { + ques_mark = PL_strchr(hash_mark, '?'); + if(ques_mark) { + *ques_mark = '\0'; + } + CKutil_StrAllocCat(rv, hash_mark); + if(ques_mark) { + *ques_mark = '?'; + } + } + } + + if(parts_requested & GET_SEARCH_PART) { + ques_mark = PL_strchr(url, '?'); /* returns a const char * */ + if(ques_mark) { + hash_mark = PL_strchr(ques_mark, '#'); + if(hash_mark) { + *hash_mark = '\0'; + } + CKutil_StrAllocCat(rv, ques_mark); + if(hash_mark) { + *hash_mark = '#'; + } + } + } + + /* copy in a null string if nothing was copied in */ + if(!rv) { + CKutil_StrAllocCopy(rv, ""); + } + + return rv; +} + +PRUnichar * +CKutil_Localize(const PRUnichar *genericString) { + nsresult ret; + PRUnichar *ptrv = nsnull; + NS_WITH_SERVICE(nsIStringBundleService, pStringService, kStringBundleServiceCID, &ret); + if (NS_SUCCEEDED(ret) && (nsnull != pStringService)) { + nsCOMPtr locale; + nsCOMPtr bundle; + ret = pStringService->CreateBundle(LOCALIZATION, locale, getter_AddRefs(bundle)); + if (NS_SUCCEEDED(ret) && bundle) { + ret = bundle->GetStringFromName(genericString, &ptrv); + if ( NS_SUCCEEDED(ret) && (ptrv) ) { + return ptrv; + } + } + } + return nsCRT::strdup(genericString); +} + +PUBLIC nsresult +CKutil_ProfileDirectory(nsFileSpec& dirSpec) { + nsresult res; + nsCOMPtr aFile; + nsCOMPtr tempSpec; + + res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(aFile)); + if (NS_FAILED(res)) return res; + + // TODO: When the calling code can take an nsIFile, + // this conversion to nsFileSpec can be avoided. + nsXPIDLCString pathBuf; + aFile->GetPath(getter_Copies(pathBuf)); + res = NS_NewFileSpec(getter_AddRefs(tempSpec)); + if (NS_FAILED(res)) return res; + res = tempSpec->SetNativePath(pathBuf); + if (NS_FAILED(res)) return res; + res = tempSpec->GetFileSpec(&dirSpec); + + return res; +} + +PUBLIC char * +CKutil_StrAllocCopy(char *&destination, const char *source) { + if(destination) { + PL_strfree(destination); + destination = 0; + } + destination = PL_strdup(source); + return destination; +} + +PUBLIC char * +CKutil_StrAllocCat(char *&destination, const char *source) { + if (source && *source) { + if (destination) { + int length = PL_strlen (destination); + destination = (char *) PR_Realloc(destination, length + PL_strlen(source) + 1); + if (destination == NULL) { + return(NULL); + } + PL_strcpy (destination + length, source); + } else { + destination = PL_strdup(source); + } + } + return destination; +} diff --git a/mozilla/extensions/cookie/nsUtils.h b/mozilla/extensions/cookie/nsUtils.h new file mode 100644 index 00000000000..20d473e8ec5 --- /dev/null +++ b/mozilla/extensions/cookie/nsUtils.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef UTILS_H +#define UTILS_H + +#include "nsString.h" +#include "nsFileStream.h" + +//#define GET_ALL_PARTS 127 +#define GET_PASSWORD_PART 64 +#define GET_USERNAME_PART 32 +#define GET_PROTOCOL_PART 16 +#define GET_HOST_PART 8 +#define GET_PATH_PART 4 +#define GET_HASH_PART 2 +#define GET_SEARCH_PART 1 + +extern PRInt32 CKutil_GetLine(nsInputFileStream& strm, nsString& aLine); +extern char * CKutil_ParseURL (const char *url, int parts_requested); +extern PRUnichar* CKutil_Localize(const PRUnichar *genericString); +extern nsresult CKutil_ProfileDirectory(nsFileSpec& dirSpec); +extern char * CKutil_StrAllocCopy(char *&destination, const char *source); +extern char * CKutil_StrAllocCat(char *&destination, const char *source); + +#endif /* UTILS_H */ diff --git a/mozilla/extensions/cookie/resources/content/cookieContextOverlay.xul b/mozilla/extensions/cookie/resources/content/cookieContextOverlay.xul index c58d91bffc4..f12b6e19081 100644 --- a/mozilla/extensions/cookie/resources/content/cookieContextOverlay.xul +++ b/mozilla/extensions/cookie/resources/content/cookieContextOverlay.xul @@ -54,33 +54,39 @@ } /* determine if image is already being blocked */ - var cookieViewer = contextMenu.createInstance - ("@mozilla.org/cookieviewer/cookieviewer-world;1", "nsICookieViewer"); - var list = cookieViewer.GetPermissionValue(1); - var permissionList = list.split(list[0]); - for(var i = 1; i < permissionList.length; i+=2) { - var permStr = permissionList[i+1]; - var type = permStr.substring(0,1); - if (type == "-") { - /* some host is being blocked, need to find out if it's our image's host */ - var host = permStr.substring(1,permStr.length); + var permissionmanager = + Components.classes["@mozilla.org/permissionmanager;1"] + .getService().QueryInterface(Components.interfaces.nsIPermissionManager); + + + var enumerator = permissionmanager.enumerator; + while (enumerator.hasMoreElements()) { + var nextPermission = enumerator.getNext(); + nextPermission = nextPermission.QueryInterface(Components.interfaces.nsIPermission); + var imageType = 1; + if (nextPermission.type == imageType && + !nextPermission.capability) { + /* some image host is being blocked, need to find out if it's our image's host */ + var host = nextPermission.host; + if(host.charAt(0) == ".") { // get rid of the ugly dot on the start of some domains + host = host.substring(1,host.length); + } if (host && contextMenu.imageURL.search(host) != -1) { /* it's our image's host that's being blocked */ - return false; } } - } + } /* image is not already being blocked, so "Block Image" can appear on the menu */ return true; }, // Block image from loading in the future. blockImage : function () { - var cookieViewer = - contextMenu.createInstance("@mozilla.org/cookieviewer/cookieviewer-world;1", - "nsICookieViewer" ); - cookieViewer.BlockImage(contextMenu.imageURL); + var imgmanager = + Components.classes["@mozilla.org/imgmanager;1"] + .getService().QueryInterface(Components.interfaces.nsIImgManager); + imgmanager.block(contextMenu.imageURL); }, initImageBlocking : function () { diff --git a/mozilla/extensions/cookie/resources/content/cookieTasksOverlay.xul b/mozilla/extensions/cookie/resources/content/cookieTasksOverlay.xul index a06c60723aa..51acdf2700e 100644 --- a/mozilla/extensions/cookie/resources/content/cookieTasksOverlay.xul +++ b/mozilla/extensions/cookie/resources/content/cookieTasksOverlay.xul @@ -40,16 +40,26 @@ element.setAttribute("disabled","true" ); } + // for some unexplainable reason, CheckForImage() keeps getting called repeatedly + // as we mouse over the task menu. IMO, that shouldn't be happening. To avoid + // taking a performance hit due to this, we will set the following flag to avoid + // reexecuting the routine + var alreadyCheckedForImage = false; + // determine if we need to remove the image entries from the task menu function CheckForImage() { + if (alreadyCheckedForImage) { + return; + } + alreadyCheckedForImage = true; // remove image functions (unless overruled by the "imageblocker.enabled" pref) try { if (!this.pref.GetBoolPref("imageblocker.enabled")) { HideImage(); } } catch(e) { - HideImage(); + HideImage(); dump("imageblocker.enabled pref is missing from all.js\n"); } } @@ -57,31 +67,33 @@ // perform a Cookie or Image action function CookieImageAction(action) { - var cookieViewer = - Components.classes["@mozilla.org/cookieviewer/cookieviewer-world;1"] - .createInstance(Components.interfaces["nsICookieViewer"]); - + var permissionmanager = + Components.classes["@mozilla.org/permissionmanager;1"] + .getService().QueryInterface(Components.interfaces.nsIPermissionManager); + if (!permissionmanager) { + return; + } var COOKIEPERMISSION = 0; var IMAGEPERMISSION = 1; - + var element; switch (action) { case "cookieAllow": - cookieViewer.AddPermission(window._content, true, COOKIEPERMISSION); + permissionmanager.add(window._content.location, true, COOKIEPERMISSION); element = document.getElementById("AllowCookies"); alert(element.getAttribute("msg")); break; case "cookieBlock": - cookieViewer.AddPermission(window._content, false, COOKIEPERMISSION); + permissionmanager.add(window._content.location, false, COOKIEPERMISSION); element = document.getElementById("BlockCookies"); alert(element.getAttribute("msg")); break; case "imageAllow": - cookieViewer.AddPermission(window._content, true, IMAGEPERMISSION); + permissionmanager.add(window._content.location, true, IMAGEPERMISSION); element = document.getElementById("AllowImages"); alert(element.getAttribute("msg")); break; case "imageBlock": - cookieViewer.AddPermission(window._content, false, IMAGEPERMISSION); + permissionmanager.add(window._content.location, false, IMAGEPERMISSION); element = document.getElementById("BlockImages"); alert(element.getAttribute("msg")); break; @@ -93,7 +105,9 @@ - + + + @@ -112,9 +126,10 @@ - + diff --git a/mozilla/extensions/cookie/tests/TestCookie.cpp b/mozilla/extensions/cookie/tests/TestCookie.cpp index c53f6c4e9e9..82a62f17513 100644 --- a/mozilla/extensions/cookie/tests/TestCookie.cpp +++ b/mozilla/extensions/cookie/tests/TestCookie.cpp @@ -40,10 +40,8 @@ void SetACookie(nsICookieService *cookieService, const char* aSpec, const char* (void)NS_NewURI(getter_AddRefs(uri), aSpec); NS_ASSERTION(uri, "malformed uri"); - nsString cookie; - cookie.AssignWithConversion(aCookieString); printf("setting cookie for \"%s\" : ", aSpec); - nsresult rv = cookieService->SetCookieString(uri, nsnull, cookie); + nsresult rv = cookieService->SetCookieString(uri, nsnull, (char *)aCookieString); if (NS_FAILED(rv)) { printf("NOT-SET\n"); } else { @@ -57,16 +55,15 @@ void GetACookie(nsICookieService *cookieService, const char* aSpec, char* *aCook (void)NS_NewURI(getter_AddRefs(uri), aSpec); NS_ASSERTION(uri, "malformed uri"); - nsString cookie; + char * cookieString; printf("retrieving cookie(s) for \"%s\" : ", aSpec); - nsresult rv = cookieService->GetCookieString(uri, cookie); + nsresult rv = cookieService->GetCookieString(uri, &cookieString); if (NS_FAILED(rv)) printf("XXX GetCookieString() failed!\n"); - if (cookie.IsEmpty()) { + if (!cookieString) { printf("NOT-FOUND\n"); } else { printf("FOUND: "); - char *cookieString = cookie.ToNewCString(); printf("%s\n", cookieString); nsCRT::free(cookieString); } diff --git a/mozilla/extensions/wallet/Makefile.in b/mozilla/extensions/wallet/Makefile.in index 538fef21924..3d044367a5a 100644 --- a/mozilla/extensions/wallet/Makefile.in +++ b/mozilla/extensions/wallet/Makefile.in @@ -26,7 +26,7 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -DIRS = public src editor signonviewer cookieviewer walletpreview build +DIRS = public src editor signonviewer walletpreview build include $(topsrcdir)/config/rules.mk diff --git a/mozilla/extensions/wallet/build/Makefile.in b/mozilla/extensions/wallet/build/Makefile.in index 78853be2844..a03db93cd3f 100644 --- a/mozilla/extensions/wallet/build/Makefile.in +++ b/mozilla/extensions/wallet/build/Makefile.in @@ -35,14 +35,12 @@ REQUIRES = xpcom string dom js CPPSRCS = nsWalletViewerFactory.cpp LOCAL_INCLUDES = \ - -I$(srcdir)/../cookieviewer \ -I$(srcdir)/../editor \ -I$(srcdir)/../signonviewer \ -I$(srcdir)/../walletpreview \ $(NULL) SHARED_LIBRARY_LIBS = \ - $(DIST)/lib/libcookieviewer_s.$(LIB_SUFFIX) \ $(DIST)/lib/libsignonviewer_s.$(LIB_SUFFIX) \ $(DIST)/lib/libwalletpreview_s.$(LIB_SUFFIX) \ $(DIST)/lib/libwalleteditor_s.$(LIB_SUFFIX) \ diff --git a/mozilla/extensions/wallet/build/makefile.win b/mozilla/extensions/wallet/build/makefile.win index f530c77728d..ba7b45fe106 100644 --- a/mozilla/extensions/wallet/build/makefile.win +++ b/mozilla/extensions/wallet/build/makefile.win @@ -27,7 +27,7 @@ MODULE = walletviewers LIBNAME = .\$(OBJDIR)\wlltvwrs DLL = $(LIBNAME).dll -LINCS = -I..\cookieviewer \ +LINCS = \ -I..\editor \ -I..\signonviewer \ -I..\walletpreview \ @@ -38,7 +38,6 @@ CPP_OBJS = \ $(NULL) LLIBS = \ - $(DIST)\lib\cookieviewer_s.lib \ $(DIST)\lib\signonviewer_s.lib \ $(DIST)\lib\walletpreview_s.lib \ $(DIST)\lib\walleteditor_s.lib \ diff --git a/mozilla/extensions/wallet/build/nsWalletViewerFactory.cpp b/mozilla/extensions/wallet/build/nsWalletViewerFactory.cpp index 1bf5c81a962..f7e6e5438a6 100644 --- a/mozilla/extensions/wallet/build/nsWalletViewerFactory.cpp +++ b/mozilla/extensions/wallet/build/nsWalletViewerFactory.cpp @@ -26,12 +26,10 @@ #include "nsWalletPreview.h" #include "nsSignonViewer.h" -#include "nsCookieViewer.h" #include "nsWalletEditor.h" NS_GENERIC_FACTORY_CONSTRUCTOR(WalletPreviewImpl) NS_GENERIC_FACTORY_CONSTRUCTOR(SignonViewerImpl) -NS_GENERIC_FACTORY_CONSTRUCTOR(CookieViewerImpl) NS_GENERIC_FACTORY_CONSTRUCTOR(WalletEditorImpl) // The list of components we register @@ -40,8 +38,6 @@ static nsModuleComponentInfo components[] = { "@mozilla.org/walletpreview/walletpreview-world;1", WalletPreviewImplConstructor }, { "SignonViewer World Component", NS_SIGNONVIEWER_CID, "@mozilla.org/signonviewer/signonviewer-world;1", SignonViewerImplConstructor }, - { "CookieViewer World Component", NS_COOKIEVIEWER_CID, - "@mozilla.org/cookieviewer/cookieviewer-world;1", CookieViewerImplConstructor }, { "WalletEditor World Component", NS_WALLETEDITOR_CID, "@mozilla.org/walleteditor/walleteditor-world;1", WalletEditorImplConstructor }, }; diff --git a/mozilla/extensions/wallet/cookieviewer/CookieViewer.js b/mozilla/extensions/wallet/cookieviewer/CookieViewer.js index 5661dc31652..03b52abd1ae 100644 --- a/mozilla/extensions/wallet/cookieviewer/CookieViewer.js +++ b/mozilla/extensions/wallet/cookieviewer/CookieViewer.js @@ -18,39 +18,27 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): * Ben Goodger */ -/* - * The cookieList is a sequence of items separated by the BREAK character. These - * items are: - * empty - * number for first cookie - * name for first cookie - * value for first cookie - * domain indicator ("Domain" or "Host") for first cookie - * domain or host name for first cookie - * path for first cookie - * secure indicator ("Yes" or "No") for first cookie - * expiration for first cookie - * with the eight items above repeated for each successive cookie - */ - // global variables -var cookieviewer = null; // cookieviewer interface -var cookieList = []; // array of cookies (OLD STREAM) -var cookies = []; // array of cookeis (NEW OBJECT) -var permissionList = []; // array of permissions (OLD STREAM) -var permissions = []; // array of permissions (NEW OBJECT) -var imageList = []; // array of images (OLD STREAM) +var cookiemanager = null; // cookiemanager interface +var permissionmanager = null; // permissionmanager interface +var cookies = []; // array of cookies +var permissions = []; // array of permissions var images = []; // array of images (NEW OBJECT) var deleted_cookies = []; var deleted_permissions = []; var deleted_images = []; -var deleted_cookies_count = 0; -var deleted_permissions_count = 0; -var deleted_images_count = 0; +var deleted_cookies_count = 0; +var deleted_cookie_permissions_count = 0; +var deleted_image_permissions_count = 0; +var cookie_permissions_count = 0; +var image_permissions_count = 0; +var cookieType = 0; +var imageType = 1; + // for dealing with the interface: var gone_c = ""; var gone_p = ""; @@ -58,16 +46,19 @@ var gone_i = ""; // string bundle var bundle = null; // CHANGE THIS WHEN MOVING FILES - strings localization file! -var JS_STRINGS_FILE = "chrome://communicator/locale/wallet/CookieViewer.properties"; - +var JS_STRINGS_FILE = "chrome://communicator/locale/wallet/CookieViewer.properties"; + // function : ::Startup(); // purpose : initialises the cookie viewer dialog function Startup() { - // xpconnect to cookieviewer interface - cookieviewer = Components.classes["@mozilla.org/cookieviewer/cookieviewer-world;1"].createInstance(); - cookieviewer = cookieviewer.QueryInterface(Components.interfaces.nsICookieViewer); - // intialise string bundle for + // xpconnect to cookiemanager interface + cookiemanager = Components.classes["@mozilla.org/cookiemanager;1"].getService(); + cookiemanager = cookiemanager.QueryInterface(Components.interfaces.nsICookieManager); + // xpconnect to permissionmanager interface + permissionmanager = Components.classes["@mozilla.org/permissionmanager;1"].getService(); + permissionmanager = permissionmanager.QueryInterface(Components.interfaces.nsIPermissionManager); + // intialise string bundle bundle = srGetStrBundle(JS_STRINGS_FILE); // install imageblocker tab if instructed to do so by the "imageblocker.enabled" pref @@ -80,9 +71,9 @@ function Startup() if (pref.GetBoolPref("imageblocker.enabled")) { var element; element = document.getElementById("imagesTab"); - element.setAttribute("style","display: inline;" ); + element.setAttribute("hidden","false" ); element = document.getElementById("images"); - element.setAttribute("style","display: inline;" ); + element.setAttribute("hidden","false" ); } } catch(e) { } @@ -94,6 +85,8 @@ function Startup() element2.selectedTab = element; element = document.getElementById("panel"); element.setAttribute("index","0" ); + element = document.getElementById("imagesTab"); + element.setAttribute("hidden","true" ); } else { element = document.getElementById("cookieviewer"); element.setAttribute("title", bundle.GetStringFromName("imageTitle")); @@ -101,6 +94,10 @@ function Startup() element2.selectedTab = element; element = document.getElementById("panel"); element.setAttribute("index","2" ); + element = document.getElementById("serversTab"); + element.setAttribute("hidden","true" ); + element = document.getElementById("cookiesTab"); + element.setAttribute("hidden","true" ); } } catch(e) { } @@ -109,48 +106,41 @@ function Startup() pref = null; } - + loadCookies(); loadPermissions(); - loadImages(); doSetOKCancel(onOK, null); window.sizeToContent(); } /*** =================== COOKIES CODE =================== ***/ -// function : ::CreateCookieList(); -// purpose : creates an array of cookie objects from the cookie stream -function CreateCookieList() -{ - var count = 0; - for(var i = 1; i < cookieList.length; i+=8) - { - cookies[count] = new Cookie(); - cookies[count].number = cookieList[i+0]; - cookies[count].name = cookieList[i+1]; - cookies[count].value = cookieList[i+2]; - cookies[count].domaintype = cookieList[i+3]; - cookies[count].domain = cookieList[i+4]; - cookies[count].path = cookieList[i+5]; - cookies[count].secure = cookieList[i+6]; - cookies[count].expire = cookieList[i+7]; - count++; - } +// function : ::AddCookieToList(); +// purpose : creates an array of cookie objects +function AddCookieToList(count, name, value, isDomain, host, path, isSecure, expires) { + cookies[count] = new Cookie(); + cookies[count].number = count; + cookies[count].name = name; + cookies[count].value = value; + cookies[count].isDomain = isDomain; + cookies[count].host = host; + cookies[count].path = path; + cookies[count].isSecure = isSecure; + cookies[count].expires = expires; } // function : ::Cookie(); // purpose : an home-brewed object that represents a individual cookie in the stream -function Cookie(number,name,value,domaintype,domain,path,secure,expire) +function Cookie(number,name,value,isDomain,host,path,isSecure,expires) { this.number = ( number ) ? number : null; this.name = ( name ) ? name : null; this.value = ( value ) ? value : null; - this.domaintype = ( domaintype ) ? domaintype : null; - this.domain = ( domain ) ? domain : null; + this.isDomain = ( isDomain ) ? isDomain : null; + this.host = ( host ) ? host : null; this.path = ( path ) ? path : null; - this.secure = ( secure ) ? secure : null; - this.expire = ( expire ) ? expire : null; + this.isSecure = ( isSecure ) ? isSecure : null; + this.expires = ( expires ) ? expires : null; } @@ -158,26 +148,39 @@ function Cookie(number,name,value,domaintype,domain,path,secure,expire) // purpose : loads the list of cookies into the cookie list treeview function loadCookies() { - // get cookies into an array - var list = cookieviewer.GetCookieValue(); - var BREAK = list.substring(0,1); - cookieList = list.split(BREAK); - CreateCookieList(); // builds an object array from cookiestream - for(var i = 0; i < cookies.length; i++) - { - var domain = cookies[i].domain; - if(domain.charAt(0) == ".") // get rid of the ugly dot on the start of some domains - domain = domain.substring(1,domain.length); - AddItem("cookielist", [domain,cookies[i].name], "tree_", cookies[i].number); + var cookieString; + var cookieArray = []; + + var enumerator = cookiemanager.enumerator; + var count = 0; + while (enumerator.hasMoreElements()) { + var nextCookie = enumerator.getNext(); + nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie); + + var name = nextCookie.name; + var value = nextCookie.value; + var isDomain = nextCookie.isDomain; + var host = nextCookie.host; + var path = nextCookie.path; + var isSecure = nextCookie.isSecure; + var expires = nextCookie.expires; + + AddCookieToList + (count, name, value, isDomain, host, path, isSecure, expires); + if(host.charAt(0) == ".") { // get rid of the ugly dot on the start of some domains + host = host.substring(1,host.length); + } + AddItem("cookieList", [host, name], "cookietree_", count++); } - if (cookies.length == 0) { + Wallet_ColumnSort('0', 'cookieList'); + if (count == 0) { document.getElementById("removeAllCookies").setAttribute("disabled","true"); } } // function : ::ViewSelectedCookie(); // purpose : displays information about the selected cookie in the info fieldset -function ViewCookieSelected( e ) +function ViewCookieSelected( e ) { var cookie = null; var cookietree = document.getElementById("cookietree"); @@ -188,37 +191,50 @@ function ViewCookieSelected( e ) selItemsMax = true; if( cookietree.selectedItems.length ) document.getElementById("removeCookies").removeAttribute("disabled","true"); - + if( ( e.type == "keypress" || e.type == "select" ) && e.target.selectedItems.length ) cookie = cookietree.selectedItems[0]; - if( e.type == "click" ) + if( e.type == "click" ) cookie = e.target.parentNode.parentNode; - if( !cookie || cookie.getAttribute("id").indexOf("tree_") == -1) + if( !cookie || cookie.getAttribute("id").indexOf("cookietree_") == -1) return false; - var idx = parseInt(cookie.getAttribute("id").substring(5,cookie.getAttribute("id").length)); + var idx = parseInt(cookie.getAttribute("id").substring("cookietree_".length,cookie.getAttribute("id").length)); for (var x=0; x::CreatePermissionList(); -// purpose : creates an array of permission objects from the permission stream -function CreatePermissionList() -{ - var count = 0; - for(var i = 1; i < permissionList.length; i+=2) - { - permissions[count] = new Permission(); - permissions[count].number = permissionList[i]; - var permStr = permissionList[i+1]; - permissions[count].type = permStr.substring(0,1); - permissions[count].domain = permStr.substring(1,permStr.length); - count++; - } +// function : ::AddPermissionToList(); +// purpose : creates an array of permission objects +function AddPermissionToList(count, host, type, capability) { + permissions[count] = new Permission(); + permissions[count].number = count; + permissions[count].host = host; + permissions[count].type = type; + permissions[count].capability = capability; } // function : ::Permission(); // purpose : an home-brewed object that represents a individual permission in the stream -function Permission(number,type,domain) +function Permission(number, host, type, capability) { this.number = (number) ? number : null; + this.host = (host) ? host : null; this.type = (type) ? type : null; - this.domain = (domain) ? domain : null; + this.capability = (capability) ? capability : null; } // function : ::loadPermissions(); // purpose : loads the list of permissions into the permission list treeview function loadPermissions() { - // get permissions into an array - var list = cookieviewer.GetPermissionValue(0); - var BREAK = list.substring(0,1); - permissionList = list.split(BREAK); - CreatePermissionList(); // builds an object array from permissionstream - for(var i = 0; i < permissions.length; i++) - { - var contentStr; - var domain = permissions[i].domain; - if(domain.charAt(0) == ".") // get rid of the ugly dot on the start of some domains - domain = domain.substring(1,domain.length); - if(permissions[i].type == "+") + var permissionString; + var permissionArray = []; + + var enumerator = permissionmanager.enumerator; + var contentStr; + while (enumerator.hasMoreElements()) { + var nextPermission = enumerator.getNext(); + nextPermission = nextPermission.QueryInterface(Components.interfaces.nsIPermission); + + var host = nextPermission.host; + var type = nextPermission.type; + var capability = nextPermission.capability; + if(host.charAt(0) == ".") { // get rid of the ugly dot on the start of some domains + host = host.substring(1,host.length); + } + if(capability) { contentStr = bundle.GetStringFromName("can"); - else if(permissions[i].type == "-") - contentStr = bundle.GetStringFromName("cannot"); - AddItem("permissionslist",[domain,contentStr],"permtree_",permissions[i].number) + } else { + contentStr = bundle.GetStringFromName("cannot"); + } + if (type == cookieType) { + AddPermissionToList(cookie_permissions_count, host, type, capability); + AddItem("cookiePermList", [host, contentStr], "cookiepermtree_", cookie_permissions_count++); + } else if (type == imageType) { + AddPermissionToList(image_permissions_count, host, type, capability); + AddItem("imagePermList", [host, contentStr], "imagepermtree_", image_permissions_count++); + } } - if (permissions.length == 0) { + if (cookie_permissions_count == 0) { document.getElementById("removeAllPermissions").setAttribute("disabled","true"); } + if (image_permissions_count == 0) { + document.getElementById("removeAllImages").setAttribute("disabled","true"); + } } -function ViewPermissionSelected() +function ViewCookiePermissionSelected() { - var permissiontree = document.getElementById("permissionstree"); - if( permissiontree.selectedItems.length ) + var cookiepermtree = document.getElementById("cookiepermissionstree"); + if( cookiepermtree.selectedItems.length ) document.getElementById("removePermissions").removeAttribute("disabled","true"); } -function DeletePermissionSelected() +function DeleteCookiePermissionSelected() { - deleted_permissions_count += document.getElementById("permissionstree").selectedItems.length; - gone_p += DeleteItemSelected('permissionstree', 'permtree_', 'permissionslist'); - if( !document.getElementById("permissionstree").selectedItems.length ) { + deleted_cookie_permissions_count += + document.getElementById("cookiepermissionstree").selectedItems.length; + gone_p += DeleteItemSelected('cookiepermissionstree', 'cookiepermtree_', 'cookiePermList'); + if( !document.getElementById("cookiepermissionstree").selectedItems.length ) { if( !document.getElementById("removePermissions").disabled ) { document.getElementById("removePermissions").setAttribute("disabled", "true") } } - if (deleted_permissions_count >= permissions.length) { + if (deleted_cookie_permissions_count >= cookie_permissions_count) { document.getElementById("removeAllPermissions").setAttribute("disabled","true"); } } -function DeleteAllPermissions() { +function DeleteAllCookiePermissions() { // delete selected item - gone_p += DeleteAllItems(permissions.length, "permtree_", "permissionslist"); + gone_p += DeleteAllItems(cookie_permissions_count, "cookiepermtree_", "cookiePermList"); if( !document.getElementById("removePermissions").disabled ) { document.getElementById("removePermissions").setAttribute("disabled", "true") } @@ -374,79 +400,31 @@ function DeleteAllPermissions() { /*** =================== IMAGES CODE =================== ***/ -// function : ::CreateImageList(); -// purpose : creates an array of image objects from the image stream -function CreateImageList() +function ViewImagePermissionSelected() { - var count = 0; - for(var i = 1; i < imageList.length; i+=2) - { - images[count] = new Image(); - images[count].number = imageList[i]; - var imgStr = imageList[i+1]; - images[count].type = imgStr.substring(0,1); - images[count].domain = imgStr.substring(1,imgStr.length); - count++; - } -} - -// function : ::Image(); -// purpose : an home-brewed object that represents a individual image in the stream -function Image(number,type,domain) -{ - this.number = (number) ? number : null; - this.type = (type) ? type : null; - this.domain = (domain) ? domain : null; -} - -// function : ::loadImages(); -// purpose : loads the list of images into the image list treeview -function loadImages() -{ - // get images into an array - var list = cookieviewer.GetPermissionValue(1); - var BREAK = list.substring(0,1); - imageList = list.split(BREAK); - CreateImageList(); // builds an object array from imagestream - for(var i = 0; i < images.length; i++) - { - var contentStr; - var domain = images[i].domain; - if(images[i].type == "+") - contentStr = bundle.GetStringFromName("canImages"); - else if(images[i].type == "-") - contentStr = bundle.GetStringFromName("cannotImages"); - AddItem("imageslist",[domain,contentStr],"imgtree_",images[i].number) - } - if (images.length == 0) { - document.getElementById("removeAllImages").setAttribute("disabled","true"); - } -} - -function ViewImageSelected() -{ - var imagetree = document.getElementById("imagestree"); - if( imagetree.selectedItems.length ) + var imagepermtree = document.getElementById("imagepermissionstree"); + if( imagepermtree.selectedItems.length ) document.getElementById("removeImages").removeAttribute("disabled","true"); } -function DeleteImageSelected() +function DeleteImagePermissionSelected() { - deleted_images_count += document.getElementById("imagestree").selectedItems.length; - gone_i += DeleteItemSelected('imagestree', 'imgtree_', 'imageslist'); - if( !document.getElementById("imagestree").selectedItems.length ) { + deleted_image_permissions_count + += document.getElementById("imagepermissionstree").selectedItems.length; + gone_i += DeleteItemSelected('imagepermissionstree', 'imagepermtree_', 'imagePermList'); + if( !document.getElementById("imagepermissionstree").selectedItems.length ) { if( !document.getElementById("removeImages").disabled ) { document.getElementById("removeImages").setAttribute("disabled", "true") } } - if (deleted_images_count >= images.length) { + if (deleted_image_permissions_count >= image_permissions_count) { document.getElementById("removeAllImages").setAttribute("disabled","true"); } } -function DeleteAllImages() { +function DeleteAllImagePermissions() { // delete selected item - gone_i += DeleteAllItems(images.length, "imgtree_", "imageslist"); + gone_i += DeleteAllItems(image_permissions_count, "imagepermtree_", "imagePermList"); if( !document.getElementById("removeImages").disabled ) { document.getElementById("removeImages").setAttribute("disabled", "true") } @@ -458,9 +436,36 @@ function DeleteAllImages() { // function : ::doOKButton(); // purpose : saves the changed settings and closes the dialog. function onOK(){ - var result = "|goneC|" + gone_c + "|goneP|" + gone_p + "|goneI|" + gone_i + - "|block|" + document.getElementById("checkbox").checked +"|"; - cookieviewer.SetValue(result, window); + + var deletedCookies = []; + deletedCookies = gone_c.split(","); + var cookieCount; + for (cookieCount=0; cookieCount - - @@ -67,14 +67,14 @@ + onclick="return Wallet_ColumnSort('0', 'cookieList');"/> + onclick="return Wallet_ColumnSort('1', 'cookieList');"/> - +