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