From fc219b0ab37da8b80d023fa1aaa957ec01b61b2a Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Mon, 1 Oct 2012 14:22:57 +0200 Subject: [PATCH] wininet: Added basic cookie domain validation in set_cookie function. --- dlls/wininet/cookie.c | 83 ++++++++++++++++++++++++----------- dlls/wininet/tests/internet.c | 20 +++++++++ 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/dlls/wininet/cookie.c b/dlls/wininet/cookie.c index 46adf68bb26..5253b2b9586 100644 --- a/dlls/wininet/cookie.c +++ b/dlls/wininet/cookie.c @@ -678,6 +678,43 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, return r; } + +/*********************************************************************** + * IsDomainLegalCookieDomainW (WININET.@) + */ +BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 ) +{ + DWORD s1_len, s2_len; + + FIXME("(%s, %s) semi-stub\n", debugstr_w(s1), debugstr_w(s2)); + + if (!s1 || !s2) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0]) + { + SetLastError(ERROR_INVALID_NAME); + return FALSE; + } + if(!strchrW(s1, '.') || !strchrW(s2, '.')) + return FALSE; + + s1_len = strlenW(s1); + s2_len = strlenW(s2); + if (s1_len > s2_len) + return FALSE; + + if (strncmpiW(s1, s2+s2_len-s1_len, s1_len) || (s2_len>s1_len && s2[s2_len-s1_len-1]!='.')) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return TRUE; +} + BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cookie_data) { cookie_domain *thisCookieDomain = NULL; @@ -727,7 +764,26 @@ BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cooki if (strncmpiW(ptr, szDomain, 7) == 0) { - ptr+=strlenW(szDomain); + WCHAR *end_ptr; + + ptr += sizeof(szDomain)/sizeof(szDomain[0])-1; + if(*ptr == '.') + ptr++; + end_ptr = strchrW(ptr, ';'); + if(end_ptr) + *end_ptr = 0; + + if(!IsDomainLegalCookieDomainW(ptr, domain)) + { + if(value != data) + heap_free(value); + heap_free(data); + return FALSE; + } + + if(end_ptr) + *end_ptr = ';'; + domain = ptr; TRACE("Parsing new domain %s\n",debugstr_w(domain)); } @@ -1059,28 +1115,3 @@ BOOL WINAPI InternetSetPerSiteCookieDecisionW( LPCWSTR pchHostName, DWORD dwDeci FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision); return FALSE; } - -/*********************************************************************** - * IsDomainLegalCookieDomainW (WININET.@) - */ -BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 ) -{ - const WCHAR *p; - - FIXME("(%s, %s)\n", debugstr_w(s1), debugstr_w(s2)); - - if (!s1 || !s2) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0]) - { - SetLastError(ERROR_INVALID_NAME); - return FALSE; - } - if (!(p = strchrW(s2, '.'))) return FALSE; - if (strchrW(p + 1, '.') && !strcmpW(p + 1, s1)) return TRUE; - else if (!strcmpW(s1, s2)) return TRUE; - return FALSE; -} diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c index 5a8ba99153b..cf1fc4ed88e 100644 --- a/dlls/wininet/tests/internet.c +++ b/dlls/wininet/tests/internet.c @@ -496,6 +496,15 @@ static void test_complicated_cookie(void) ret = GetUrlCacheEntryInfo(buffer, NULL, &len); ok(!ret, "GetUrlCacheEntryInfo succeeded\n"); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() = %d\n", GetLastError()); + + /* try setting cookie for different domain */ + ret = InternetSetCookie("http://www.aaa.example.com/bar",NULL,"E=F; domain=different.com"); + ok(!ret, "InternetSetCookie succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n", GetLastError()); + ret = InternetSetCookie("http://www.aaa.example.com.pl/bar",NULL,"E=F; domain=example.com.pl"); + ok(ret, "InternetSetCookie failed with error: %d\n", GetLastError()); + ret = InternetSetCookie("http://www.aaa.example.com.pl/bar",NULL,"E=F; domain=com.pl"); + todo_wine ok(!ret, "InternetSetCookie succeeded\n"); } static void test_cookie_url(void) @@ -828,6 +837,8 @@ static void test_IsDomainLegalCookieDomainW(void) static const WCHAR dot_com[] = {'.','c','o','m',0}; static const WCHAR gmail_com[] = {'g','m','a','i','l','.','c','o','m',0}; static const WCHAR dot_gmail_com[] = {'.','g','m','a','i','l','.','c','o','m',0}; + static const WCHAR www_gmail_com[] = {'w','w','w','.','g','m','a','i','l','.','c','o','m',0}; + static const WCHAR www_mail_gmail_com[] = {'w','w','w','.','m','a','i','l','.','g','m','a','i','l','.','c','o','m',0}; static const WCHAR mail_gmail_com[] = {'m','a','i','l','.','g','m','a','i','l','.','c','o','m',0}; static const WCHAR gmail_co_uk[] = {'g','m','a','i','l','.','c','o','.','u','k',0}; static const WCHAR co_uk[] = {'c','o','.','u','k',0}; @@ -924,6 +935,12 @@ static void test_IsDomainLegalCookieDomainW(void) ret = pIsDomainLegalCookieDomainW(gmail_com, gmail_com); ok(ret, "IsDomainLegalCookieDomainW failed\n"); + ret = pIsDomainLegalCookieDomainW(gmail_com, www_gmail_com); + ok(ret, "IsDomainLegalCookieDomainW failed\n"); + + ret = pIsDomainLegalCookieDomainW(gmail_com, www_mail_gmail_com); + ok(ret, "IsDomainLegalCookieDomainW failed\n"); + SetLastError(0xdeadbeef); ret = pIsDomainLegalCookieDomainW(gmail_co_uk, co_uk); error = GetLastError(); @@ -940,6 +957,9 @@ static void test_IsDomainLegalCookieDomainW(void) ret = pIsDomainLegalCookieDomainW(gmail_co_uk, dot_co_uk); ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); + ret = pIsDomainLegalCookieDomainW(co_uk, gmail_co_uk); + todo_wine ok(!ret, "IsDomainLegalCookieDomainW succeeded\n"); + ret = pIsDomainLegalCookieDomainW(gmail_co_uk, gmail_co_uk); ok(ret, "IsDomainLegalCookieDomainW failed\n");