]> sjero.net Git - wget/blob - src/cookies.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / cookies.c
1 /* Support for cookies.
2    Copyright (C) 2001-2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or (at
9 your option) any later version.
10
11 GNU Wget is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
18
19 In addition, as a special exception, the Free Software Foundation
20 gives permission to link the code of its release of Wget with the
21 OpenSSL project's "OpenSSL" library (or with modified versions of it
22 that use the same license as the "OpenSSL" library), and distribute
23 the linked executables.  You must obey the GNU General Public License
24 in all respects for all of the code used other than "OpenSSL".  If you
25 modify this file, you may extend this exception to your version of the
26 file, but you are not obligated to do so.  If you do not wish to do
27 so, delete this exception statement from your version.  */
28
29 /* Written by Hrvoje Niksic.  Parts are loosely inspired by the
30    cookie patch submitted by Tomasz Wegrzanowski.
31
32    This implements the client-side cookie support, as specified
33    (loosely) by Netscape's "preliminary specification", currently
34    available at:
35
36        http://wp.netscape.com/newsref/std/cookie_spec.html
37
38    rfc2109 is not supported because of its incompatibilities with the
39    above widely-used specification.  rfc2965 is entirely ignored,
40    since popular client software doesn't implement it, and even the
41    sites that do send Set-Cookie2 also emit Set-Cookie for
42    compatibility.  */
43
44 #include <config.h>
45
46 #include <stdio.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <assert.h>
50 #include <errno.h>
51 #include <time.h>
52
53 #include "wget.h"
54 #include "utils.h"
55 #include "hash.h"
56 #include "cookies.h"
57 #include "http.h"               /* for http_atotm */
58 \f
59 /* Declarations of `struct cookie' and the most basic functions. */
60
61 /* Cookie jar serves as cookie storage and a means of retrieving
62    cookies efficiently.  All cookies with the same domain are stored
63    in a linked list called "chain".  A cookie chain can be reached by
64    looking up the domain in the cookie jar's chains_by_domain table.
65
66    For example, to reach all the cookies under google.com, one must
67    execute hash_table_get(jar->chains_by_domain, "google.com").  Of
68    course, when sending a cookie to `www.google.com', one must search
69    for cookies that belong to either `www.google.com' or `google.com'
70    -- but the point is that the code doesn't need to go through *all*
71    the cookies.  */
72
73 struct cookie_jar {
74   /* Cookie chains indexed by domain.  */
75   struct hash_table *chains;
76
77   int cookie_count;             /* number of cookies in the jar. */
78 };
79
80 /* Value set by entry point functions, so that the low-level
81    routines don't need to call time() all the time.  */
82 static time_t cookies_now;
83
84 struct cookie_jar *
85 cookie_jar_new (void)
86 {
87   struct cookie_jar *jar = xnew (struct cookie_jar);
88   jar->chains = make_nocase_string_hash_table (0);
89   jar->cookie_count = 0;
90   return jar;
91 }
92
93 struct cookie {
94   char *domain;                 /* domain of the cookie */
95   int port;                     /* port number */
96   char *path;                   /* path prefix of the cookie */
97
98   unsigned discard_requested :1; /* whether cookie was created to
99                                    request discarding another
100                                    cookie. */
101
102   unsigned secure :1;           /* whether cookie should be
103                                    transmitted over non-https
104                                    connections. */
105   unsigned domain_exact :1;     /* whether DOMAIN must match as a
106                                    whole. */
107
108   unsigned permanent :1;        /* whether the cookie should outlive
109                                    the session. */
110   time_t expiry_time;           /* time when the cookie expires, 0
111                                    means undetermined. */
112
113   char *attr;                   /* cookie attribute name */
114   char *value;                  /* cookie attribute value */
115
116   struct cookie *next;          /* used for chaining of cookies in the
117                                    same domain. */
118 };
119
120 #define PORT_ANY (-1)
121
122 /* Allocate and return a new, empty cookie structure. */
123
124 static struct cookie *
125 cookie_new (void)
126 {
127   struct cookie *cookie = xnew0 (struct cookie);
128
129   /* Both cookie->permanent and cookie->expiry_time are now 0.  This
130      means that the cookie doesn't expire, but is only valid for this
131      session (i.e. not written out to disk).  */
132
133   cookie->port = PORT_ANY;
134   return cookie;
135 }
136
137 /* Non-zero if the cookie has expired.  Assumes cookies_now has been
138    set by one of the entry point functions.  */
139
140 static bool
141 cookie_expired_p (const struct cookie *c)
142 {
143   return c->expiry_time != 0 && c->expiry_time < cookies_now;
144 }
145
146 /* Deallocate COOKIE and its components. */
147
148 static void
149 delete_cookie (struct cookie *cookie)
150 {
151   xfree_null (cookie->domain);
152   xfree_null (cookie->path);
153   xfree_null (cookie->attr);
154   xfree_null (cookie->value);
155   xfree (cookie);
156 }
157 \f
158 /* Functions for storing cookies.
159
160    All cookies can be reached beginning with jar->chains.  The key in
161    that table is the domain name, and the value is a linked list of
162    all cookies from that domain.  Every new cookie is placed on the
163    head of the list.  */
164
165 /* Find and return a cookie in JAR whose domain, path, and attribute
166    name correspond to COOKIE.  If found, PREVPTR will point to the
167    location of the cookie previous in chain, or NULL if the found
168    cookie is the head of a chain.
169
170    If no matching cookie is found, return NULL. */
171
172 static struct cookie *
173 find_matching_cookie (struct cookie_jar *jar, struct cookie *cookie,
174                       struct cookie **prevptr)
175 {
176   struct cookie *chain, *prev;
177
178   chain = hash_table_get (jar->chains, cookie->domain);
179   if (!chain)
180     goto nomatch;
181
182   prev = NULL;
183   for (; chain; prev = chain, chain = chain->next)
184     if (0 == strcmp (cookie->path, chain->path)
185         && 0 == strcmp (cookie->attr, chain->attr)
186         && cookie->port == chain->port)
187       {
188         *prevptr = prev;
189         return chain;
190       }
191
192  nomatch:
193   *prevptr = NULL;
194   return NULL;
195 }
196
197 /* Store COOKIE to the jar.
198
199    This is done by placing COOKIE at the head of its chain.  However,
200    if COOKIE matches a cookie already in memory, as determined by
201    find_matching_cookie, the old cookie is unlinked and destroyed.
202
203    The key of each chain's hash table entry is allocated only the
204    first time; next hash_table_put's reuse the same key.  */
205
206 static void
207 store_cookie (struct cookie_jar *jar, struct cookie *cookie)
208 {
209   struct cookie *chain_head;
210   char *chain_key;
211
212   if (hash_table_get_pair (jar->chains, cookie->domain,
213                            &chain_key, &chain_head))
214     {
215       /* A chain of cookies in this domain already exists.  Check for
216          duplicates -- if an extant cookie exactly matches our domain,
217          port, path, and name, replace it.  */
218       struct cookie *prev;
219       struct cookie *victim = find_matching_cookie (jar, cookie, &prev);
220
221       if (victim)
222         {
223           /* Remove VICTIM from the chain.  COOKIE will be placed at
224              the head. */
225           if (prev)
226             {
227               prev->next = victim->next;
228               cookie->next = chain_head;
229             }
230           else
231             {
232               /* prev is NULL; apparently VICTIM was at the head of
233                  the chain.  This place will be taken by COOKIE, so
234                  all we need to do is:  */
235               cookie->next = victim->next;
236             }
237           delete_cookie (victim);
238           --jar->cookie_count;
239           DEBUGP (("Deleted old cookie (to be replaced.)\n"));
240         }
241       else
242         cookie->next = chain_head;
243     }
244   else
245     {
246       /* We are now creating the chain.  Use a copy of cookie->domain
247          as the key for the life-time of the chain.  Using
248          cookie->domain would be unsafe because the life-time of the
249          chain may exceed the life-time of the cookie.  (Cookies may
250          be deleted from the chain by this very function.)  */
251       cookie->next = NULL;
252       chain_key = xstrdup (cookie->domain);
253     }
254
255   hash_table_put (jar->chains, chain_key, cookie);
256   ++jar->cookie_count;
257
258   IF_DEBUG
259     {
260       time_t exptime = cookie->expiry_time;
261       DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n",
262                cookie->domain, cookie->port,
263                cookie->port == PORT_ANY ? " (ANY)" : "",
264                cookie->path,
265                cookie->permanent ? "permanent" : "session",
266                cookie->secure ? "secure" : "insecure",
267                cookie->expiry_time ? datetime_str (exptime) : "none",
268                cookie->attr, cookie->value));
269     }
270 }
271
272 /* Discard a cookie matching COOKIE's domain, port, path, and
273    attribute name.  This gets called when we encounter a cookie whose
274    expiry date is in the past, or whose max-age is set to 0.  The
275    former corresponds to netscape cookie spec, while the latter is
276    specified by rfc2109.  */
277
278 static void
279 discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie)
280 {
281   struct cookie *prev, *victim;
282
283   if (!hash_table_count (jar->chains))
284     /* No elements == nothing to discard. */
285     return;
286
287   victim = find_matching_cookie (jar, cookie, &prev);
288   if (victim)
289     {
290       if (prev)
291         /* Simply unchain the victim. */
292         prev->next = victim->next;
293       else
294         {
295           /* VICTIM was head of its chain.  We need to place a new
296              cookie at the head.  */
297           char *chain_key = NULL;
298           int res;
299
300           res = hash_table_get_pair (jar->chains, victim->domain,
301                                      &chain_key, NULL);
302           assert (res != 0);
303           if (!victim->next)
304             {
305               /* VICTIM was the only cookie in the chain.  Destroy the
306                  chain and deallocate the chain key.  */
307               hash_table_remove (jar->chains, victim->domain);
308               xfree (chain_key);
309             }
310           else
311             hash_table_put (jar->chains, chain_key, victim->next);
312         }
313       delete_cookie (victim);
314       DEBUGP (("Discarded old cookie.\n"));
315     }
316 }
317 \f
318 /* Functions for parsing the `Set-Cookie' header, and creating new
319    cookies from the wire.  */
320
321 #define TOKEN_IS(token, string_literal)                         \
322   BOUNDED_EQUAL_NO_CASE (token.b, token.e, string_literal)
323
324 #define TOKEN_NON_EMPTY(token) (token.b != NULL && token.b != token.e)
325
326 /* Parse the contents of the `Set-Cookie' header.  The header looks
327    like this:
328
329    name1=value1; name2=value2; ...
330
331    Trailing semicolon is optional; spaces are allowed between all
332    tokens.  Additionally, values may be quoted.
333
334    A new cookie is returned upon success, NULL otherwise.
335
336    The first name-value pair will be used to set the cookie's
337    attribute name and value.  Subsequent parameters will be checked
338    against field names such as `domain', `path', etc.  Recognized
339    fields will be parsed and the corresponding members of COOKIE
340    filled.  */
341
342 static struct cookie *
343 parse_set_cookie (const char *set_cookie, bool silent)
344 {
345   const char *ptr = set_cookie;
346   struct cookie *cookie = cookie_new ();
347   param_token name, value;
348
349   if (!extract_param (&ptr, &name, &value, ';'))
350     goto error;
351   if (!value.b)
352     goto error;
353   cookie->attr = strdupdelim (name.b, name.e);
354   cookie->value = strdupdelim (value.b, value.e);
355
356   while (extract_param (&ptr, &name, &value, ';'))
357     {
358       if (TOKEN_IS (name, "domain"))
359         {
360           if (!TOKEN_NON_EMPTY (value))
361             goto error;
362           xfree_null (cookie->domain);
363           /* Strictly speaking, we should set cookie->domain_exact if the
364              domain doesn't begin with a dot.  But many sites set the
365              domain to "foo.com" and expect "subhost.foo.com" to get the
366              cookie, and it apparently works in browsers.  */
367           if (*value.b == '.')
368             ++value.b;
369           cookie->domain = strdupdelim (value.b, value.e);
370         }
371       else if (TOKEN_IS (name, "path"))
372         {
373           if (!TOKEN_NON_EMPTY (value))
374             goto error;
375           xfree_null (cookie->path);
376           cookie->path = strdupdelim (value.b, value.e);
377         }
378       else if (TOKEN_IS (name, "expires"))
379         {
380           char *value_copy;
381           time_t expires;
382
383           if (!TOKEN_NON_EMPTY (value))
384             goto error;
385           BOUNDED_TO_ALLOCA (value.b, value.e, value_copy);
386
387           expires = http_atotm (value_copy);
388           if (expires != (time_t) -1)
389             {
390               cookie->permanent = 1;
391               cookie->expiry_time = expires;
392               /* According to netscape's specification, expiry time in
393                  the past means that discarding of a matching cookie
394                  is requested.  */
395               if (cookie->expiry_time < cookies_now)
396                 cookie->discard_requested = 1;
397             }
398           else
399             /* Error in expiration spec.  Assume default (cookie doesn't
400                expire, but valid only for this session.)  */
401             ;
402         }
403       else if (TOKEN_IS (name, "max-age"))
404         {
405           double maxage = -1;
406           char *value_copy;
407
408           if (!TOKEN_NON_EMPTY (value))
409             goto error;
410           BOUNDED_TO_ALLOCA (value.b, value.e, value_copy);
411
412           sscanf (value_copy, "%lf", &maxage);
413           if (maxage == -1)
414             /* something went wrong. */
415             goto error;
416           cookie->permanent = 1;
417           cookie->expiry_time = cookies_now + maxage;
418
419           /* According to rfc2109, a cookie with max-age of 0 means that
420              discarding of a matching cookie is requested.  */
421           if (maxage == 0)
422             cookie->discard_requested = 1;
423         }
424       else if (TOKEN_IS (name, "secure"))
425         {
426           /* ignore value completely */
427           cookie->secure = 1;
428         }
429       else
430         /* Ignore unrecognized attribute. */
431         ;
432     }
433   if (*ptr)
434     /* extract_param has encountered a syntax error */
435     goto error;
436
437   /* The cookie has been successfully constructed; return it. */
438   return cookie;
439
440  error:
441   if (!silent)
442     logprintf (LOG_NOTQUIET,
443                _("Syntax error in Set-Cookie: %s at position %d.\n"),
444                escnonprint (set_cookie), (int) (ptr - set_cookie));
445   delete_cookie (cookie);
446   return NULL;
447 }
448
449 #undef TOKEN_IS
450 #undef TOKEN_NON_EMPTY
451 \f
452 /* Sanity checks.  These are important, otherwise it is possible for
453    mailcious attackers to destroy important cookie information and/or
454    violate your privacy.  */
455
456
457 #define REQUIRE_DIGITS(p) do {                  \
458   if (!ISDIGIT (*p))                            \
459     return false;                               \
460   for (++p; ISDIGIT (*p); p++)                  \
461     ;                                           \
462 } while (0)
463
464 #define REQUIRE_DOT(p) do {                     \
465   if (*p++ != '.')                              \
466     return false;                               \
467 } while (0)
468
469 /* Check whether ADDR matches <digits>.<digits>.<digits>.<digits>.
470
471    We don't want to call network functions like inet_addr() because
472    all we need is a check, preferrably one that is small, fast, and
473    well-defined.  */
474
475 static bool
476 numeric_address_p (const char *addr)
477 {
478   const char *p = addr;
479
480   REQUIRE_DIGITS (p);           /* A */
481   REQUIRE_DOT (p);              /* . */
482   REQUIRE_DIGITS (p);           /* B */
483   REQUIRE_DOT (p);              /* . */
484   REQUIRE_DIGITS (p);           /* C */
485   REQUIRE_DOT (p);              /* . */
486   REQUIRE_DIGITS (p);           /* D */
487
488   if (*p != '\0')
489     return false;
490   return true;
491 }
492
493 /* Check whether COOKIE_DOMAIN is an appropriate domain for HOST.
494    Originally I tried to make the check compliant with rfc2109, but
495    the sites deviated too often, so I had to fall back to "tail
496    matching", as defined by the original Netscape's cookie spec.  */
497
498 static bool
499 check_domain_match (const char *cookie_domain, const char *host)
500 {
501   DEBUGP (("cdm: 1"));
502
503   /* Numeric address requires exact match.  It also requires HOST to
504      be an IP address.  */
505   if (numeric_address_p (cookie_domain))
506     return 0 == strcmp (cookie_domain, host);
507
508   DEBUGP ((" 2"));
509
510   /* For the sake of efficiency, check for exact match first. */
511   if (0 == strcasecmp (cookie_domain, host))
512     return true;
513
514   DEBUGP ((" 3"));
515
516   /* HOST must match the tail of cookie_domain. */
517   if (!match_tail (host, cookie_domain, true))
518     return false;
519
520   /* We know that COOKIE_DOMAIN is a subset of HOST; however, we must
521      make sure that somebody is not trying to set the cookie for a
522      subdomain shared by many entities.  For example, "company.co.uk"
523      must not be allowed to set a cookie for ".co.uk".  On the other
524      hand, "sso.redhat.de" should be able to set a cookie for
525      ".redhat.de".
526
527      The only marginally sane way to handle this I can think of is to
528      reject on the basis of the length of the second-level domain name
529      (but when the top-level domain is unknown), with the assumption
530      that those of three or less characters could be reserved.  For
531      example:
532
533           .co.org -> works because the TLD is known
534            .co.uk -> doesn't work because "co" is only two chars long
535           .com.au -> doesn't work because "com" is only 3 chars long
536           .cnn.uk -> doesn't work because "cnn" is also only 3 chars long (ugh)
537           .cnn.de -> doesn't work for the same reason (ugh!!)
538          .abcd.de -> works because "abcd" is 4 chars long
539       .img.cnn.de -> works because it's not trying to set the 2nd level domain
540        .cnn.co.uk -> works for the same reason
541
542     That should prevent misuse, while allowing reasonable usage.  If
543     someone knows of a better way to handle this, please let me
544     know.  */
545   {
546     const char *p = cookie_domain;
547     int dccount = 1;            /* number of domain components */
548     int ldcl  = 0;              /* last domain component length */
549     int nldcl = 0;              /* next to last domain component length */
550     int out;
551     if (*p == '.')
552       /* Ignore leading period in this calculation. */
553       ++p;
554     DEBUGP ((" 4"));
555     for (out = 0; !out; p++)
556       switch (*p)
557         {
558         case '\0':
559           out = 1;
560           break;
561         case '.':
562           if (ldcl == 0)
563             /* Empty domain component found -- the domain is invalid. */
564             return false;
565           if (*(p + 1) == '\0')
566             {
567               /* Tolerate trailing '.' by not treating the domain as
568                  one ending with an empty domain component.  */
569               out = 1;
570               break;
571             }
572           nldcl = ldcl;
573           ldcl  = 0;
574           ++dccount;
575           break;
576         default:
577           ++ldcl;
578         }
579
580     DEBUGP ((" 5"));
581
582     if (dccount < 2)
583       return false;
584
585     DEBUGP ((" 6"));
586
587     if (dccount == 2)
588       {
589         int i;
590         int known_toplevel = false;
591         static const char *known_toplevel_domains[] = {
592           ".com", ".edu", ".net", ".org", ".gov", ".mil", ".int"
593         };
594         for (i = 0; i < countof (known_toplevel_domains); i++)
595           if (match_tail (cookie_domain, known_toplevel_domains[i], true))
596             {
597               known_toplevel = true;
598               break;
599             }
600         if (!known_toplevel && nldcl <= 3)
601           return false;
602       }
603   }
604
605   DEBUGP ((" 7"));
606
607   /* Don't allow the host "foobar.com" to set a cookie for domain
608      "bar.com".  */
609   if (*cookie_domain != '.')
610     {
611       int dlen = strlen (cookie_domain);
612       int hlen = strlen (host);
613       /* cookie host:    hostname.foobar.com */
614       /* desired domain:             bar.com */
615       /* '.' must be here in host-> ^        */
616       if (hlen > dlen && host[hlen - dlen - 1] != '.')
617         return false;
618     }
619
620   DEBUGP ((" 8"));
621
622   return true;
623 }
624
625 static int path_matches (const char *, const char *);
626
627 /* Check whether PATH begins with COOKIE_PATH. */
628
629 static bool
630 check_path_match (const char *cookie_path, const char *path)
631 {
632   return path_matches (path, cookie_path) != 0;
633 }
634
635 /* Prepend '/' to string S.  S is copied to fresh stack-allocated
636    space and its value is modified to point to the new location.  */
637
638 #define PREPEND_SLASH(s) do {                                   \
639   char *PS_newstr = (char *) alloca (1 + strlen (s) + 1);       \
640   *PS_newstr = '/';                                             \
641   strcpy (PS_newstr + 1, s);                                    \
642   s = PS_newstr;                                                \
643 } while (0)
644
645 \f
646 /* Process the HTTP `Set-Cookie' header.  This results in storing the
647    cookie or discarding a matching one, or ignoring it completely, all
648    depending on the contents.  */
649
650 void
651 cookie_handle_set_cookie (struct cookie_jar *jar,
652                           const char *host, int port,
653                           const char *path, const char *set_cookie)
654 {
655   struct cookie *cookie;
656   cookies_now = time (NULL);
657
658   /* Wget's paths don't begin with '/' (blame rfc1808), but cookie
659      usage assumes /-prefixed paths.  Until the rest of Wget is fixed,
660      simply prepend slash to PATH.  */
661   PREPEND_SLASH (path);
662
663   cookie = parse_set_cookie (set_cookie, false);
664   if (!cookie)
665     goto out;
666
667   /* Sanitize parts of cookie. */
668
669   if (!cookie->domain)
670     {
671     copy_domain:
672       /* If the domain was not provided, we use the one we're talking
673          to, and set exact match.  */
674       cookie->domain = xstrdup (host);
675       cookie->domain_exact = 1;
676       /* Set the port, but only if it's non-default. */
677       if (port != 80 && port != 443)
678         cookie->port = port;
679     }
680   else
681     {
682       if (!check_domain_match (cookie->domain, host))
683         {
684           logprintf (LOG_NOTQUIET,
685                      _("Cookie coming from %s attempted to set domain to %s\n"),
686                      escnonprint (host), escnonprint (cookie->domain));
687           xfree (cookie->domain);
688           goto copy_domain;
689         }
690     }
691
692   if (!cookie->path)
693     {
694       /* The cookie doesn't set path: set it to the URL path, sans the
695          file part ("/dir/file" truncated to "/dir/").  */
696       char *trailing_slash = strrchr (path, '/');
697       if (trailing_slash)
698         cookie->path = strdupdelim (path, trailing_slash + 1);
699       else
700         /* no slash in the string -- can this even happen? */
701         cookie->path = xstrdup (path);
702     }
703   else
704     {
705       /* The cookie sets its own path; verify that it is legal. */
706       if (!check_path_match (cookie->path, path))
707         {
708           DEBUGP (("Attempt to fake the path: %s, %s\n",
709                    cookie->path, path));
710           goto out;
711         }
712     }
713
714   /* Now store the cookie, or discard an existing cookie, if
715      discarding was requested.  */
716
717   if (cookie->discard_requested)
718     {
719       discard_matching_cookie (jar, cookie);
720       goto out;
721     }
722
723   store_cookie (jar, cookie);
724   return;
725
726  out:
727   if (cookie)
728     delete_cookie (cookie);
729 }
730 \f
731 /* Support for sending out cookies in HTTP requests, based on
732    previously stored cookies.  Entry point is
733    `build_cookies_request'.  */
734    
735 /* Return a count of how many times CHR occurs in STRING. */
736
737 static int
738 count_char (const char *string, char chr)
739 {
740   const char *p;
741   int count = 0;
742   for (p = string; *p; p++)
743     if (*p == chr)
744       ++count;
745   return count;
746 }
747
748 /* Find the cookie chains whose domains match HOST and store them to
749    DEST.
750
751    A cookie chain is the head of a list of cookies that belong to a
752    host/domain.  Given HOST "img.search.xemacs.org", this function
753    will return the chains for "img.search.xemacs.org",
754    "search.xemacs.org", and "xemacs.org" -- those of them that exist
755    (if any), that is.
756
757    DEST should be large enough to accept (in the worst case) as many
758    elements as there are domain components of HOST.  */
759
760 static int
761 find_chains_of_host (struct cookie_jar *jar, const char *host,
762                      struct cookie *dest[])
763 {
764   int dest_count = 0;
765   int passes, passcnt;
766
767   /* Bail out quickly if there are no cookies in the jar.  */
768   if (!hash_table_count (jar->chains))
769     return 0;
770
771   if (numeric_address_p (host))
772     /* If host is an IP address, only check for the exact match. */
773     passes = 1;
774   else
775     /* Otherwise, check all the subdomains except the top-level (last)
776        one.  As a domain with N components has N-1 dots, the number of
777        passes equals the number of dots.  */
778     passes = count_char (host, '.');
779
780   passcnt = 0;
781
782   /* Find chains that match HOST, starting with exact match and
783      progressing to less specific domains.  For instance, given HOST
784      fly.srk.fer.hr, first look for fly.srk.fer.hr's chain, then
785      srk.fer.hr's, then fer.hr's.  */
786   while (1)
787     {
788       struct cookie *chain = hash_table_get (jar->chains, host);
789       if (chain)
790         dest[dest_count++] = chain;
791       if (++passcnt >= passes)
792         break;
793       host = strchr (host, '.') + 1;
794     }
795
796   return dest_count;
797 }
798
799 /* If FULL_PATH begins with PREFIX, return the length of PREFIX, zero
800    otherwise.  */
801
802 static int
803 path_matches (const char *full_path, const char *prefix)
804 {
805   int len = strlen (prefix);
806
807   if (0 != strncmp (full_path, prefix, len))
808     /* FULL_PATH doesn't begin with PREFIX. */
809     return 0;
810
811   /* Length of PREFIX determines the quality of the match. */
812   return len + 1;
813 }
814
815 /* Return true iff COOKIE matches the provided parameters of the URL
816    being downloaded: HOST, PORT, PATH, and SECFLAG.
817
818    If PATH_GOODNESS is non-NULL, store the "path goodness" value
819    there.  That value is a measure of how closely COOKIE matches PATH,
820    used for ordering cookies.  */
821
822 static bool
823 cookie_matches_url (const struct cookie *cookie,
824                     const char *host, int port, const char *path,
825                     bool secflag, int *path_goodness)
826 {
827   int pg;
828
829   if (cookie_expired_p (cookie))
830     /* Ignore stale cookies.  Don't bother unchaining the cookie at
831        this point -- Wget is a relatively short-lived application, and
832        stale cookies will not be saved by `save_cookies'.  On the
833        other hand, this function should be as efficient as
834        possible.  */
835     return false;
836
837   if (cookie->secure && !secflag)
838     /* Don't transmit secure cookies over insecure connections.  */
839     return false;
840   if (cookie->port != PORT_ANY && cookie->port != port)
841     return false;
842
843   /* If exact domain match is required, verify that cookie's domain is
844      equal to HOST.  If not, assume success on the grounds of the
845      cookie's chain having been found by find_chains_of_host.  */
846   if (cookie->domain_exact
847       && 0 != strcasecmp (host, cookie->domain))
848     return false;
849
850   pg = path_matches (path, cookie->path);
851   if (pg == 0)
852     return false;
853
854   if (path_goodness)
855     /* If the caller requested path_goodness, we return it.  This is
856        an optimization, so that the caller doesn't need to call
857        path_matches() again.  */
858     *path_goodness = pg;
859   return true;
860 }
861
862 /* A structure that points to a cookie, along with the additional
863    information about the cookie's "goodness".  This allows us to sort
864    the cookies when returning them to the server, as required by the
865    spec.  */
866
867 struct weighed_cookie {
868   struct cookie *cookie;
869   int domain_goodness;
870   int path_goodness;
871 };
872
873 /* Comparator used for uniquifying the list. */
874
875 static int
876 equality_comparator (const void *p1, const void *p2)
877 {
878   struct weighed_cookie *wc1 = (struct weighed_cookie *)p1;
879   struct weighed_cookie *wc2 = (struct weighed_cookie *)p2;
880
881   int namecmp  = strcmp (wc1->cookie->attr, wc2->cookie->attr);
882   int valuecmp = strcmp (wc1->cookie->value, wc2->cookie->value);
883
884   /* We only really care whether both name and value are equal.  We
885      return them in this order only for consistency...  */
886   return namecmp ? namecmp : valuecmp;
887 }
888
889 /* Eliminate duplicate cookies.  "Duplicate cookies" are any two
890    cookies with the same attr name and value.  Whenever a duplicate
891    pair is found, one of the cookies is removed.  */
892
893 static int
894 eliminate_dups (struct weighed_cookie *outgoing, int count)
895 {
896   struct weighed_cookie *h;     /* hare */
897   struct weighed_cookie *t;     /* tortoise */
898   struct weighed_cookie *end = outgoing + count;
899
900   /* We deploy a simple uniquify algorithm: first sort the array
901      according to our sort criteria, then copy it to itself, comparing
902      each cookie to its neighbor and ignoring the duplicates.  */
903
904   qsort (outgoing, count, sizeof (struct weighed_cookie), equality_comparator);
905
906   /* "Hare" runs through all the entries in the array, followed by
907      "tortoise".  If a duplicate is found, the hare skips it.
908      Non-duplicate entries are copied to the tortoise ptr.  */
909
910   for (h = t = outgoing; h < end; h++)
911     {
912       if (h != end - 1)
913         {
914           struct cookie *c0 = h[0].cookie;
915           struct cookie *c1 = h[1].cookie;
916           if (!strcmp (c0->attr, c1->attr) && !strcmp (c0->value, c1->value))
917             continue;           /* ignore the duplicate */
918         }
919
920       /* If the hare has advanced past the tortoise (because of
921          previous dups), make sure the values get copied.  Otherwise,
922          no copying is necessary.  */
923       if (h != t)
924         *t++ = *h;
925       else
926         t++;
927     }
928   return t - outgoing;
929 }
930
931 /* Comparator used for sorting by quality. */
932
933 static int
934 goodness_comparator (const void *p1, const void *p2)
935 {
936   struct weighed_cookie *wc1 = (struct weighed_cookie *)p1;
937   struct weighed_cookie *wc2 = (struct weighed_cookie *)p2;
938
939   /* Subtractions take `wc2' as the first argument becauase we want a
940      sort in *decreasing* order of goodness.  */
941   int dgdiff = wc2->domain_goodness - wc1->domain_goodness;
942   int pgdiff = wc2->path_goodness - wc1->path_goodness;
943
944   /* Sort by domain goodness; if these are the same, sort by path
945      goodness.  (The sorting order isn't really specified; maybe it
946      should be the other way around.)  */
947   return dgdiff ? dgdiff : pgdiff;
948 }
949
950 /* Generate a `Cookie' header for a request that goes to HOST:PORT and
951    requests PATH from the server.  The resulting string is allocated
952    with `malloc', and the caller is responsible for freeing it.  If no
953    cookies pertain to this request, i.e. no cookie header should be
954    generated, NULL is returned.  */
955
956 char *
957 cookie_header (struct cookie_jar *jar, const char *host,
958                int port, const char *path, bool secflag)
959 {
960   struct cookie **chains;
961   int chain_count;
962
963   struct cookie *cookie;
964   struct weighed_cookie *outgoing;
965   int count, i, ocnt;
966   char *result;
967   int result_size, pos;
968   PREPEND_SLASH (path);         /* see cookie_handle_set_cookie */
969
970   /* First, find the cookie chains whose domains match HOST. */
971
972   /* Allocate room for find_chains_of_host to write to.  The number of
973      chains can at most equal the number of subdomains, hence
974      1+<number of dots>.  */
975   chains = alloca_array (struct cookie *, 1 + count_char (host, '.'));
976   chain_count = find_chains_of_host (jar, host, chains);
977
978   /* No cookies for this host. */
979   if (!chain_count)
980     return NULL;
981
982   cookies_now = time (NULL);
983
984   /* Now extract from the chains those cookies that match our host
985      (for domain_exact cookies), port (for cookies with port other
986      than PORT_ANY), etc.  See matching_cookie for details.  */
987
988   /* Count the number of matching cookies. */
989   count = 0;
990   for (i = 0; i < chain_count; i++)
991     for (cookie = chains[i]; cookie; cookie = cookie->next)
992       if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
993         ++count;
994   if (!count)
995     return NULL;                /* no cookies matched */
996
997   /* Allocate the array. */
998   outgoing = alloca_array (struct weighed_cookie, count);
999
1000   /* Fill the array with all the matching cookies from the chains that
1001      match HOST. */
1002   ocnt = 0;
1003   for (i = 0; i < chain_count; i++)
1004     for (cookie = chains[i]; cookie; cookie = cookie->next)
1005       {
1006         int pg;
1007         if (!cookie_matches_url (cookie, host, port, path, secflag, &pg))
1008           continue;
1009         outgoing[ocnt].cookie = cookie;
1010         outgoing[ocnt].domain_goodness = strlen (cookie->domain);
1011         outgoing[ocnt].path_goodness   = pg;
1012         ++ocnt;
1013       }
1014   assert (ocnt == count);
1015
1016   /* Eliminate duplicate cookies; that is, those whose name and value
1017      are the same.  */
1018   count = eliminate_dups (outgoing, count);
1019
1020   /* Sort the array so that best-matching domains come first, and
1021      that, within one domain, best-matching paths come first. */
1022   qsort (outgoing, count, sizeof (struct weighed_cookie), goodness_comparator);
1023
1024   /* Count the space the name=value pairs will take. */
1025   result_size = 0;
1026   for (i = 0; i < count; i++)
1027     {
1028       struct cookie *c = outgoing[i].cookie;
1029       /* name=value */
1030       result_size += strlen (c->attr) + 1 + strlen (c->value);
1031     }
1032
1033   /* Allocate output buffer:
1034      name=value pairs -- result_size
1035      "; " separators  -- (count - 1) * 2
1036      \0 terminator    -- 1 */
1037   result_size = result_size + (count - 1) * 2 + 1;
1038   result = xmalloc (result_size);
1039   pos = 0;
1040   for (i = 0; i < count; i++)
1041     {
1042       struct cookie *c = outgoing[i].cookie;
1043       int namlen = strlen (c->attr);
1044       int vallen = strlen (c->value);
1045
1046       memcpy (result + pos, c->attr, namlen);
1047       pos += namlen;
1048       result[pos++] = '=';
1049       memcpy (result + pos, c->value, vallen);
1050       pos += vallen;
1051       if (i < count - 1)
1052         {
1053           result[pos++] = ';';
1054           result[pos++] = ' ';
1055         }
1056     }
1057   result[pos++] = '\0';
1058   assert (pos == result_size);
1059   return result;
1060 }
1061 \f
1062 /* Support for loading and saving cookies.  The format used for
1063    loading and saving should be the format of the `cookies.txt' file
1064    used by Netscape and Mozilla, at least the Unix versions.
1065    (Apparently IE can export cookies in that format as well.)  The
1066    format goes like this:
1067
1068        DOMAIN DOMAIN-FLAG PATH SECURE-FLAG TIMESTAMP ATTR-NAME ATTR-VALUE
1069
1070      DOMAIN      -- cookie domain, optionally followed by :PORT
1071      DOMAIN-FLAG -- whether all hosts in the domain match
1072      PATH        -- cookie path
1073      SECURE-FLAG -- whether cookie requires secure connection
1074      TIMESTAMP   -- expiry timestamp, number of seconds since epoch
1075      ATTR-NAME   -- name of the cookie attribute
1076      ATTR-VALUE  -- value of the cookie attribute (empty if absent)
1077
1078    The fields are separated by TABs.  All fields are mandatory, except
1079    for ATTR-VALUE.  The `-FLAG' fields are boolean, their legal values
1080    being "TRUE" and "FALSE'.  Empty lines, lines consisting of
1081    whitespace only, and comment lines (beginning with # optionally
1082    preceded by whitespace) are ignored.
1083
1084    Example line from cookies.txt (split in two lines for readability):
1085
1086        .google.com      TRUE    /       FALSE   2147368447      \
1087        PREF     ID=34bb47565bbcd47b:LD=en:NR=20:TM=985172580:LM=985739012
1088
1089 */
1090
1091 /* If the region [B, E) ends with :<digits>, parse the number, return
1092    it, and store new boundary (location of the `:') to DOMAIN_E_PTR.
1093    If port is not specified, return 0.  */
1094
1095 static int
1096 domain_port (const char *domain_b, const char *domain_e,
1097              const char **domain_e_ptr)
1098 {
1099   int port = 0;
1100   const char *p;
1101   const char *colon = memchr (domain_b, ':', domain_e - domain_b);
1102   if (!colon)
1103     return 0;
1104   for (p = colon + 1; p < domain_e && ISDIGIT (*p); p++)
1105     port = 10 * port + (*p - '0');
1106   if (p < domain_e)
1107     /* Garbage following port number. */
1108     return 0;
1109   *domain_e_ptr = colon;
1110   return port;
1111 }
1112
1113 #define GET_WORD(p, b, e) do {                  \
1114   b = p;                                        \
1115   while (*p && *p != '\t')                      \
1116     ++p;                                        \
1117   e = p;                                        \
1118   if (b == e || !*p)                            \
1119     goto next;                                  \
1120   ++p;                                          \
1121 } while (0)
1122
1123 /* Load cookies from FILE.  */
1124
1125 void
1126 cookie_jar_load (struct cookie_jar *jar, const char *file)
1127 {
1128   char *line;
1129   FILE *fp = fopen (file, "r");
1130   if (!fp)
1131     {
1132       logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
1133                  file, strerror (errno));
1134       return;
1135     }
1136   cookies_now = time (NULL);
1137
1138   for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
1139     {
1140       struct cookie *cookie;
1141       char *p = line;
1142
1143       double expiry;
1144       int port;
1145
1146       char *domain_b  = NULL, *domain_e  = NULL;
1147       char *domflag_b = NULL, *domflag_e = NULL;
1148       char *path_b    = NULL, *path_e    = NULL;
1149       char *secure_b  = NULL, *secure_e  = NULL;
1150       char *expires_b = NULL, *expires_e = NULL;
1151       char *name_b    = NULL, *name_e    = NULL;
1152       char *value_b   = NULL, *value_e   = NULL;
1153
1154       /* Skip leading white-space. */
1155       while (*p && ISSPACE (*p))
1156         ++p;
1157       /* Ignore empty lines.  */
1158       if (!*p || *p == '#')
1159         continue;
1160
1161       GET_WORD (p, domain_b,  domain_e);
1162       GET_WORD (p, domflag_b, domflag_e);
1163       GET_WORD (p, path_b,    path_e);
1164       GET_WORD (p, secure_b,  secure_e);
1165       GET_WORD (p, expires_b, expires_e);
1166       GET_WORD (p, name_b,    name_e);
1167
1168       /* Don't use GET_WORD for value because it ends with newline,
1169          not TAB.  */
1170       value_b = p;
1171       value_e = p + strlen (p);
1172       if (value_e > value_b && value_e[-1] == '\n')
1173         --value_e;
1174       if (value_e > value_b && value_e[-1] == '\r')
1175         --value_e;
1176       /* Empty values are legal (I think), so don't bother checking. */
1177
1178       cookie = cookie_new ();
1179
1180       cookie->attr    = strdupdelim (name_b, name_e);
1181       cookie->value   = strdupdelim (value_b, value_e);
1182       cookie->path    = strdupdelim (path_b, path_e);
1183       cookie->secure  = BOUNDED_EQUAL (secure_b, secure_e, "TRUE");
1184
1185       /* Curl source says, quoting Andre Garcia: "flag: A TRUE/FALSE
1186          value indicating if all machines within a given domain can
1187          access the variable.  This value is set automatically by the
1188          browser, depending on the value set for the domain."  */
1189       cookie->domain_exact = !BOUNDED_EQUAL (domflag_b, domflag_e, "TRUE");
1190
1191       /* DOMAIN needs special treatment because we might need to
1192          extract the port.  */
1193       port = domain_port (domain_b, domain_e, (const char **)&domain_e);
1194       if (port)
1195         cookie->port = port;
1196
1197       if (*domain_b == '.')
1198         ++domain_b;             /* remove leading dot internally */
1199       cookie->domain  = strdupdelim (domain_b, domain_e);
1200
1201       /* safe default in case EXPIRES field is garbled. */
1202       expiry = (double)cookies_now - 1;
1203
1204       /* I don't like changing the line, but it's safe here.  (line is
1205          malloced.)  */
1206       *expires_e = '\0';
1207       sscanf (expires_b, "%lf", &expiry);
1208
1209       if (expiry == 0)
1210         {
1211           /* EXPIRY can be 0 for session cookies saved because the
1212              user specified `--keep-session-cookies' in the past.
1213              They remain session cookies, and will be saved only if
1214              the user has specified `keep-session-cookies' again.  */
1215         }
1216       else
1217         {
1218           if (expiry < cookies_now)
1219             goto abort_cookie;  /* ignore stale cookie. */
1220           cookie->expiry_time = expiry;
1221           cookie->permanent = 1;
1222         }
1223
1224       store_cookie (jar, cookie);
1225
1226     next:
1227       continue;
1228
1229     abort_cookie:
1230       delete_cookie (cookie);
1231     }
1232   fclose (fp);
1233 }
1234
1235 /* Save cookies, in format described above, to FILE. */
1236
1237 void
1238 cookie_jar_save (struct cookie_jar *jar, const char *file)
1239 {
1240   FILE *fp;
1241   hash_table_iterator iter;
1242
1243   DEBUGP (("Saving cookies to %s.\n", file));
1244
1245   cookies_now = time (NULL);
1246
1247   fp = fopen (file, "w");
1248   if (!fp)
1249     {
1250       logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
1251                  file, strerror (errno));
1252       return;
1253     }
1254
1255   fputs ("# HTTP cookie file.\n", fp);
1256   fprintf (fp, "# Generated by Wget on %s.\n", datetime_str (cookies_now));
1257   fputs ("# Edit at your own risk.\n\n", fp);
1258
1259   for (hash_table_iterate (jar->chains, &iter);
1260        hash_table_iter_next (&iter);
1261        )
1262     {
1263       const char *domain = iter.key;
1264       struct cookie *cookie = iter.value;
1265       for (; cookie; cookie = cookie->next)
1266         {
1267           if (!cookie->permanent && !opt.keep_session_cookies)
1268             continue;
1269           if (cookie_expired_p (cookie))
1270             continue;
1271           if (!cookie->domain_exact)
1272             fputc ('.', fp);
1273           fputs (domain, fp);
1274           if (cookie->port != PORT_ANY)
1275             fprintf (fp, ":%d", cookie->port);
1276           fprintf (fp, "\t%s\t%s\t%s\t%.0f\t%s\t%s\n",
1277                    cookie->domain_exact ? "FALSE" : "TRUE",
1278                    cookie->path, cookie->secure ? "TRUE" : "FALSE",
1279                    (double)cookie->expiry_time,
1280                    cookie->attr, cookie->value);
1281           if (ferror (fp))
1282             goto out;
1283         }
1284     }
1285  out:
1286   if (ferror (fp))
1287     logprintf (LOG_NOTQUIET, _("Error writing to `%s': %s\n"),
1288                file, strerror (errno));
1289   if (fclose (fp) < 0)
1290     logprintf (LOG_NOTQUIET, _("Error closing `%s': %s\n"),
1291                file, strerror (errno));
1292
1293   DEBUGP (("Done saving cookies.\n"));
1294 }
1295 \f
1296 /* Clean up cookie-related data. */
1297
1298 void
1299 cookie_jar_delete (struct cookie_jar *jar)
1300 {
1301   /* Iterate over chains (indexed by domain) and free them. */
1302   hash_table_iterator iter;
1303   for (hash_table_iterate (jar->chains, &iter); hash_table_iter_next (&iter); )
1304     {
1305       struct cookie *chain = iter.value;
1306       xfree (iter.key);
1307       /* Then all cookies in this chain. */
1308       while (chain)
1309         {
1310           struct cookie *next = chain->next;
1311           delete_cookie (chain);
1312           chain = next;
1313         }
1314     }
1315   hash_table_destroy (jar->chains);
1316   xfree (jar);
1317 }
1318 \f
1319 /* Test cases.  Currently this is only tests parse_set_cookies.  To
1320    use, recompile Wget with -DTEST_COOKIES and call test_cookies()
1321    from main.  */
1322
1323 #ifdef TEST_COOKIES
1324 void
1325 test_cookies (void)
1326 {
1327   /* Tests expected to succeed: */
1328   static struct {
1329     const char *data;
1330     const char *results[10];
1331   } tests_succ[] = {
1332     { "arg=value", {"arg", "value", NULL} },
1333     { "arg1=value1;arg2=value2", {"arg1", "value1", "arg2", "value2", NULL} },
1334     { "arg1=value1; arg2=value2", {"arg1", "value1", "arg2", "value2", NULL} },
1335     { "arg1=value1;  arg2=value2;", {"arg1", "value1", "arg2", "value2", NULL} },
1336     { "arg1=value1;  arg2=value2;  ", {"arg1", "value1", "arg2", "value2", NULL} },
1337     { "arg1=\"value1\"; arg2=\"\"", {"arg1", "value1", "arg2", "", NULL} },
1338     { "arg=", {"arg", "", NULL} },
1339     { "arg1=; arg2=", {"arg1", "", "arg2", "", NULL} },
1340     { "arg1 = ; arg2= ", {"arg1", "", "arg2", "", NULL} },
1341   };
1342
1343   /* Tests expected to fail: */
1344   static char *tests_fail[] = {
1345     ";",
1346     "arg=\"unterminated",
1347     "=empty-name",
1348     "arg1=;=another-empty-name",
1349   };
1350   int i;
1351
1352   for (i = 0; i < countof (tests_succ); i++)
1353     {
1354       int ind;
1355       const char *data = tests_succ[i].data;
1356       const char **expected = tests_succ[i].results;
1357       struct cookie *c;
1358
1359       c = parse_set_cookie (data, true);
1360       if (!c)
1361         {
1362           printf ("NULL cookie returned for valid data: %s\n", data);
1363           continue;
1364         }
1365
1366       /* Test whether extract_param handles these cases correctly. */
1367       {
1368         param_token name, value;
1369         const char *ptr = data;
1370         int j = 0;
1371         while (extract_param (&ptr, &name, &value, ';'))
1372           {
1373             char *n = strdupdelim (name.b, name.e);
1374             char *v = strdupdelim (value.b, value.e);
1375             if (!expected[j])
1376               {
1377                 printf ("Too many parameters for '%s'\n", data);
1378                 break;
1379               }
1380             if (0 != strcmp (expected[j], n))
1381               printf ("Invalid name %d for '%s' (expected '%s', got '%s')\n",
1382                       j / 2 + 1, data, expected[j], n);
1383             if (0 != strcmp (expected[j + 1], v))
1384               printf ("Invalid value %d for '%s' (expected '%s', got '%s')\n",
1385                       j / 2 + 1, data, expected[j + 1], v);
1386             j += 2;
1387             free (n);
1388             free (v);
1389           }
1390         if (expected[j])
1391           printf ("Too few parameters for '%s'\n", data);
1392       }
1393     }
1394
1395   for (i = 0; i < countof (tests_fail); i++)
1396     {
1397       struct cookie *c;
1398       char *data = tests_fail[i];
1399       c = parse_set_cookie (data, true);
1400       if (c)
1401         printf ("Failed to report error on invalid data: %s\n", data);
1402     }
1403 }
1404 #endif /* TEST_COOKIES */