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