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