From 5999f10ccbc93937ba70e2b893e8dcafe376a835 Mon Sep 17 00:00:00 2001 From: "morse%netscape.com" Date: Sat, 18 Dec 1999 05:48:26 +0000 Subject: [PATCH] implement foreign-cookie pref, bug 13655, r=neeti, a=chofmann git-svn-id: svn://10.0.0.236/trunk@56188 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/extensions/cookie/nsCookie.cpp | 204 ++++++++++-------- mozilla/extensions/cookie/nsCookie.h | 3 +- .../extensions/cookie/nsCookieHTTPNotify.cpp | 40 +++- mozilla/extensions/cookie/nsCookieService.cpp | 29 ++- mozilla/extensions/cookie/nsICookieService.h | 13 +- 5 files changed, 188 insertions(+), 101 deletions(-) diff --git a/mozilla/extensions/cookie/nsCookie.cpp b/mozilla/extensions/cookie/nsCookie.cpp index f6838793af2..09bf869b33c 100644 --- a/mozilla/extensions/cookie/nsCookie.cpp +++ b/mozilla/extensions/cookie/nsCookie.cpp @@ -820,7 +820,7 @@ COOKIE_RegisterCookiePrefCallbacks(void) { /* returns PR_TRUE if authorization is required ** ** -** IMPORTANT: Now that this routine is mutli-threaded it is up +** IMPORTANT: Now that this routine is multi-threaded it is up ** to the caller to free any returned string */ PUBLIC char * @@ -940,6 +940,107 @@ COOKIE_GetCookie(char * address) { 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); +} + void cookie_AddPermission(cookie_PermissionStruct * cookie_permission, PRBool save ) { /* @@ -1535,51 +1636,6 @@ COOKIE_SetCookieString(char * curURL, char * setCookieHeader) { cookie_SetCookieString(curURL, setCookieHeader, 0); } -#ifdef later // We need to come back and fix this. - Neeti -/* 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 * inlineHost) { - char * dot = 0; - char * currentDomain = 0; - char * inlineDomain = 0; - if(!currentHost || !inlineHost) { - return 0; - } - - /* case insensitive compare */ - if(PL_strcasecmp(currentHost, inlineHost) == 0) { - return 1; - } - currentDomain = PL_strchr(currentHost, '.'); - inlineDomain = PL_strchr(inlineHost, '.'); - if(!currentDomain || !inlineDomain) { - 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 inlineDomain is within the currentDomain - */ - dot = PL_strchr(inlineDomain, '.'); - if(dot) { - dot = PL_strchr(dot+1, '.'); - } else { - return 0; - } - - /* handle .com. case */ - if(!dot || (*(dot+1) == '\0')) { - return 0; - } - if(!PL_strcasecmp(inlineDomain, currentDomain)) { - return 1; - } - return 0; -} -#endif - /* 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 @@ -1589,15 +1645,15 @@ cookie_SameDomain(char * currentHost, char * inlineHost) { */ PUBLIC void -COOKIE_SetCookieStringFromHttp(char * curURL, char * setCookieHeader, char * server_date) { +COOKIE_SetCookieStringFromHttp(char * curURL, char * firstURL, 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, setCookieHeader, server_date); + COOKIE_SetCookieStringFromHttp(curURL, firstURL, setCookieHeader, server_date); *newline = '\n'; - COOKIE_SetCookieStringFromHttp(curURL, newline+1, server_date); + COOKIE_SetCookieStringFromHttp(curURL, firstURL, newline+1, server_date); return; } @@ -1610,44 +1666,12 @@ COOKIE_SetCookieStringFromHttp(char * curURL, char * setCookieHeader, char * ser char *ptr=NULL; time_t gmtCookieExpires=0, expires=0, sDate; -#ifdef later // We need to come back and fix this. - Neeti - if(CLEAR_CACHE_BIT(outputFormat) != FO_PRESENT && - CLEAR_CACHE_BIT(outputFormat) != FO_SAVE_AS) { - if (cookie_GetBehaviorPref() == COOKIE_DontAcceptForeign) { - // the user doesn't want foreign cookies, check to see if its foreign - char * curSessionHistHost = 0; - char * theColon = 0; - char * curHost = cookie_ParseURL(curURL, GET_HOST_PART); - History_entry * shistEntry = SHIST_GetCurrent(&context->hist); - if (shistEntry) { - curSessionHistHost = cookie_ParseURL(shistEntry->address, GET_HOST_PART); - } - if(!curHost || !curSessionHistHost) { - PR_FREEIF(curHost); - PR_FREEIF(curSessionHistHost); - return; - } - - /* strip ports */ - theColon = PL_strchr(curHost, ':'); - if(theColon) { - *theColon = '\0'; - } - theColon = PL_strchr(curSessionHistHost, ':'); - if(theColon) { - *theColon = '\0'; - } - /* if it's foreign, get out of here after a little clean up */ - if(!cookie_SameDomain(curHost, curSessionHistHost)) { - PR_FREEIF(curHost); - PR_FREEIF(curSessionHistHost); - return; - } - PR_FREEIF(curHost); - PR_FREEIF(curSessionHistHost); - } + /* 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; } -#endif /* later */ /* 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 @@ -2348,14 +2372,6 @@ XP_StripLine (char *string) { return string; } -#ifdef later -PUBLIC History_entry * -SHIST_GetCurrent(History * hist) { - /* MOZ_FUNCTION_STUB; */ - return NULL; -} -#endif - /* Very similar to strdup except it free's too */ PUBLIC char * diff --git a/mozilla/extensions/cookie/nsCookie.h b/mozilla/extensions/cookie/nsCookie.h index a3edc88ad55..6c1c7ff86a5 100644 --- a/mozilla/extensions/cookie/nsCookie.h +++ b/mozilla/extensions/cookie/nsCookie.h @@ -34,11 +34,12 @@ #endif extern char * COOKIE_GetCookie(char * address); +extern char * COOKIE_GetCookieFromHttp(char * address, char * firstAddress); extern void COOKIE_SetCookieString(char * cur_url, char * set_cookie_header); extern int COOKIE_ReadCookies(); extern void COOKIE_RegisterCookiePrefCallbacks(void); extern void COOKIE_RemoveAllCookies(void); -extern void COOKIE_SetCookieStringFromHttp(char * cur_url, char * set_cookie_header, char * server_date); +extern void COOKIE_SetCookieStringFromHttp(char * cur_url, char * first_url, char * set_cookie_header, char * server_date); extern void COOKIE_GetCookieListForViewer (nsString& aCookieList); extern void COOKIE_GetPermissionListForViewer (nsString& aPermissionList); extern void COOKIE_CookieViewerReturn(nsAutoString results); diff --git a/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp b/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp index adbbb17a187..1187960d1fa 100644 --- a/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp +++ b/mozilla/extensions/cookie/nsCookieHTTPNotify.cpp @@ -31,6 +31,7 @@ #include "nsIServiceManager.h" #include "nsIAllocator.h" #include "nsINetModuleMgr.h" +#include "nsILoadGroup.h" static NS_DEFINE_CID(kINetModuleMgrCID, NS_NETMODULEMGR_CID); @@ -110,16 +111,34 @@ nsCookieHTTPNotify::ModifyRequest(nsISupports *aContext) nsCOMPtr pHTTPConnection = do_QueryInterface(aContext, &rv); if (NS_FAILED(rv)) return rv; + // Get the url nsCOMPtr pURL; rv = pHTTPConnection->GetURI(getter_AddRefs(pURL)); if (NS_FAILED(rv)) return rv; + // Get the original url that the user either typed in or clicked on + nsCOMPtr pLoadGroup; + rv = pHTTPConnection->GetLoadGroup(getter_AddRefs(pLoadGroup)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr pChannel; + rv = pLoadGroup->GetDefaultLoadChannel(getter_AddRefs(pChannel)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr pFirstURL; + if (pChannel) { + rv = pChannel->GetURI(getter_AddRefs(pFirstURL)); + } else { + rv = pHTTPConnection->GetURI(getter_AddRefs(pFirstURL)); + } + if (NS_FAILED(rv)) return rv; + // Ensure that the cookie service exists rv = SetupCookieService(); if (NS_FAILED(rv)) return rv; nsString cookie; - rv = mCookieService->GetCookieString(pURL, cookie); + rv = mCookieService->GetCookieStringFromHTTP(pURL, pFirstURL, cookie); if (NS_FAILED(rv)) return rv; // Set the cookie into the request headers @@ -156,6 +175,23 @@ nsCookieHTTPNotify::AsyncExamineResponse(nsISupports *aContext) rv = pHTTPConnection->GetURI(getter_AddRefs(pURL)); if (NS_FAILED(rv)) return rv; + // Get the original url that the user either typed in or clicked on + nsCOMPtr pLoadGroup; + rv = pHTTPConnection->GetLoadGroup(getter_AddRefs(pLoadGroup)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr pChannel; + rv = pLoadGroup->GetDefaultLoadChannel(getter_AddRefs(pChannel)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr pFirstURL; + if (pChannel) { + rv = pChannel->GetURI(getter_AddRefs(pFirstURL)); + } else { + rv = pHTTPConnection->GetURI(getter_AddRefs(pFirstURL)); + } + if (NS_FAILED(rv)) return rv; + // Get the expires nsXPIDLCString expiresHeader; rv = pHTTPConnection->GetResponseHeader(mExpiresHeader, getter_Copies(expiresHeader)); @@ -166,7 +202,7 @@ nsCookieHTTPNotify::AsyncExamineResponse(nsISupports *aContext) if (NS_FAILED(rv)) return rv; // Save the cookie - rv = mCookieService->SetCookieStringFromHttp(pURL, cookieHeader, expiresHeader); + rv = mCookieService->SetCookieStringFromHttp(pURL, pFirstURL, cookieHeader, expiresHeader); return rv; } diff --git a/mozilla/extensions/cookie/nsCookieService.cpp b/mozilla/extensions/cookie/nsCookieService.cpp index 992afbe5c25..7528bbac101 100644 --- a/mozilla/extensions/cookie/nsCookieService.cpp +++ b/mozilla/extensions/cookie/nsCookieService.cpp @@ -45,8 +45,9 @@ public: NS_DECL_ISUPPORTS NS_IMETHOD GetCookieString(nsIURI *aURL, nsString& aCookie); + NS_IMETHOD GetCookieStringFromHTTP(nsIURI *aURL, nsIURI *aFirstURL, nsString& aCookie); NS_IMETHOD SetCookieString(nsIURI *aURL, const nsString& aCookie); - NS_IMETHOD SetCookieStringFromHttp(nsIURI *aURL, const char *aCookie, const char *aExpires); + NS_IMETHOD SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, const char *aCookie, const char *aExpires); NS_IMETHOD Cookie_RemoveAllCookies(void); NS_IMETHOD Cookie_CookieViewerReturn(nsAutoString results); NS_IMETHOD Cookie_GetCookieListForViewer(nsString& aCookieList); @@ -121,6 +122,25 @@ nsCookieService::GetCookieString(nsIURI *aURL, nsString& aCookie) { return NS_OK; } +NS_IMETHODIMP +nsCookieService::GetCookieStringFromHTTP(nsIURI *aURL, nsIURI *aFirstURL, nsString& 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.SetString(cookie); + nsCRT::free(cookie); + } else { + // No Cookie isn't an error condition. + aCookie.SetString(""); + } + return NS_OK; +} + NS_IMETHODIMP nsCookieService::SetCookieString(nsIURI *aURL, const nsString& aCookie) { char *spec = NULL; @@ -134,12 +154,15 @@ nsCookieService::SetCookieString(nsIURI *aURL, const nsString& aCookie) { } NS_IMETHODIMP -nsCookieService::SetCookieStringFromHttp(nsIURI *aURL, const char *aCookie, const char *aExpires) { +nsCookieService::SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, const char *aCookie, const char *aExpires) { char *spec = NULL; nsresult rv = aURL->GetSpec(&spec); if (NS_FAILED(rv)) return rv; - COOKIE_SetCookieStringFromHttp(spec, (char *)aCookie, (char *)aExpires); + char *firstSpec = NULL; + rv = aFirstURL->GetSpec(&firstSpec); if (NS_FAILED(rv)) return rv; + COOKIE_SetCookieStringFromHttp(spec, firstSpec, (char *)aCookie, (char *)aExpires); nsCRT::free(spec); + nsCRT::free(firstSpec); return NS_OK; } diff --git a/mozilla/extensions/cookie/nsICookieService.h b/mozilla/extensions/cookie/nsICookieService.h index 4769b5df2fc..815552297d3 100644 --- a/mozilla/extensions/cookie/nsICookieService.h +++ b/mozilla/extensions/cookie/nsICookieService.h @@ -49,6 +49,16 @@ public: */ NS_IMETHOD GetCookieString(nsIURI *aURL, nsString& aCookie)=0; + /* + * Get the complete cookie string associated with the URL + * + * @param aURL The URL for which to get the cookie string + * @param aFirstURL The URL which the user typed in or clicked on + * @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; + /* * Set the cookie string associated with the URL * @@ -62,11 +72,12 @@ public: * Set the cookie string and expires associated with the URL * * @param aURL The URL for which to set the cookie string + * @param aFirstURL The URL which the user typed in or clicked on * @param aCookie The char * string to set * @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, const char *aCookie, const char *aExpires)=0; + NS_IMETHOD SetCookieStringFromHttp(nsIURI *aURL, nsIURI *aFirstURL, const char *aCookie, const char *aExpires)=0; /* * Blows away all permissions currently in the cookie permissions list,