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