aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dpi/cookies.c35
-rw-r--r--src/cache.c5
-rw-r--r--src/cookies.c14
-rw-r--r--src/cookies.h3
4 files changed, 47 insertions, 10 deletions
diff --git a/dpi/cookies.c b/dpi/cookies.c
index 50c50c2e..521717c2 100644
--- a/dpi/cookies.c
+++ b/dpi/cookies.c
@@ -632,7 +632,7 @@ static void Cookies_eat_value(char **cookie_str)
* Parse cookie. A cookie might look something like:
* "Name=Val; Domain=example.com; Max-Age=3600; HttpOnly"
*/
-static CookieData_t *Cookies_parse(char *cookie_str)
+static CookieData_t *Cookies_parse(char *cookie_str, const char *server_date)
{
CookieData_t *cookie = NULL;
char *str = cookie_str;
@@ -687,6 +687,29 @@ static CookieData_t *Cookies_parse(char *cookie_str)
if (!max_age) {
value = Cookies_parse_value(&str);
cookie->expires_at = Cookies_create_timestamp(value);
+ if (cookie->expires_at && server_date) {
+ time_t server_time = Cookies_create_timestamp(server_date);
+
+ if (server_time) {
+ time_t now = time(NULL);
+ time_t client_time = cookie->expires_at + now - server_time;
+
+ if (server_time == cookie->expires_at) {
+ cookie->expires_at = now;
+ } else if ((cookie->expires_at > now) ==
+ (client_time > now)) {
+ cookie->expires_at = client_time;
+ } else {
+ /* It seems not at all unlikely that bad server code will
+ * fail to take normal clock skew into account when
+ * setting max/min cookie values.
+ */
+ MSG("At %ld, %ld was trying to turn into %ld\n",
+ (long)now, (long)cookie->expires_at,
+ (long)client_time);
+ }
+ }
+ }
expires = TRUE;
dFree(value);
MSG("Expires in %ld seconds, at %s",
@@ -918,7 +941,7 @@ static bool_t Cookies_validate_domain(CookieData_t *cookie, char *host)
* Set the value corresponding to the cookie string
*/
static void Cookies_set(char *cookie_string, char *url_host,
- char *url_path)
+ char *url_path, char *server_date)
{
CookieControlAction action;
CookieData_t *cookie;
@@ -934,7 +957,7 @@ static void Cookies_set(char *cookie_string, char *url_host,
_MSG("%s setting: %s\n", url_host, cookie_string);
- if ((cookie = Cookies_parse(cookie_string))) {
+ if ((cookie = Cookies_parse(cookie_string, server_date))) {
if (Cookies_validate_domain(cookie, url_host)) {
Cookies_validate_path(cookie, url_path);
if (action == COOKIE_ACCEPT_SESSION)
@@ -1211,13 +1234,17 @@ static int srv_parse_tok(Dsh *sh, ClientInfo *client, char *Buf)
exit(0);
} else if (cmd && strcmp(cmd, "set_cookie") == 0) {
+ char *date;
+
dFree(cmd);
cookie = a_Dpip_get_attr_l(Buf, BufSize, "cookie");
host = a_Dpip_get_attr_l(Buf, BufSize, "host");
path = a_Dpip_get_attr_l(Buf, BufSize, "path");
+ date = a_Dpip_get_attr_l(Buf, BufSize, "date");
- Cookies_set(cookie, host, path);
+ Cookies_set(cookie, host, path, date);
+ dFree(date);
dFree(path);
dFree(host);
dFree(cookie);
diff --git a/src/cache.c b/src/cache.c
index 3341388c..8700502e 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -733,10 +733,13 @@ static void Cache_parse_header(CacheEntry_t *entry)
* know if that is a real issue though. */
if ((Cookies = Cache_parse_multiple_fields(header, "Set-Cookie2")) ||
(Cookies = Cache_parse_multiple_fields(header, "Set-Cookie"))) {
- a_Cookies_set(Cookies, entry->Url);
+ char *server_date = Cache_parse_field(header, "Date");
+
+ a_Cookies_set(Cookies, entry->Url, server_date);
for (i = 0; (data = dList_nth_data(Cookies, i)); ++i)
dFree(data);
dList_free(Cookies);
+ dFree(server_date);
}
#endif /* !DISABLE_COOKIES */
diff --git a/src/cookies.c b/src/cookies.c
index 0793a670..ceb5b238 100644
--- a/src/cookies.c
+++ b/src/cookies.c
@@ -138,7 +138,8 @@ void a_Cookies_freeall()
/*
* Set the value corresponding to the cookie string
*/
-void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url)
+void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url,
+ const char *date)
{
CookieControlAction action;
char *cmd, *cookie_string, *dpip_tag;
@@ -156,9 +157,14 @@ void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url)
for (i = 0; (cookie_string = dList_nth_data(cookie_strings, i)); ++i) {
path = URL_PATH_(set_url);
- cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s",
- "set_cookie", cookie_string, URL_HOST_(set_url),
- path ? path : "/");
+ if (date)
+ cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s date=%s",
+ "set_cookie", cookie_string,
+ URL_HOST_(set_url), path ? path : "/", date);
+ else
+ cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s",
+ "set_cookie", cookie_string,
+ URL_HOST_(set_url), path ? path : "/");
_MSG("Cookies.c: a_Cookies_set \n\t \"%s\" \n",cmd );
/* This call is commented because it doesn't guarantee the order
diff --git a/src/cookies.h b/src/cookies.h
index 6f9f77e0..482aa5ae 100644
--- a/src/cookies.h
+++ b/src/cookies.h
@@ -12,7 +12,8 @@ extern "C" {
# define a_Cookies_freeall() ;
#else
char *a_Cookies_get_query(const DilloUrl *request_url);
- void a_Cookies_set(Dlist *cookie_string, const DilloUrl *set_url);
+ void a_Cookies_set(Dlist *cookie_string, const DilloUrl *set_url,
+ const char *server_date);
void a_Cookies_init( void );
void a_Cookies_freeall( void );
#endif