]> sjero.net Git - wget/blob - src/cookies.c
[svn] Minor cookie fixes. Published in <sxsheyu9yp6.fsf@florida.arsdigita.de>.
[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
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 cookie-specific hash tables.  These are regular hash
108    tables, but with case-insensitive test and hash functions.  */
109
110 /* Like string_hash, but produces the same results regardless of the
111    case.  */
112
113 static unsigned long
114 unsigned_string_hash (const void *key)
115 {
116   const char *p = key;
117   unsigned int h = TOLOWER (*p);
118   
119   if (h)
120     for (p += 1; *p != '\0'; p++)
121       h = (h << 5) - h + TOLOWER (*p);
122   
123   return h;
124 }
125
126 /* Front-end to strcasecmp. */
127
128 static int
129 unsigned_string_cmp (const void *s1, const void *s2)
130 {
131   return !strcasecmp ((const char *)s1, (const char *)s2);
132 }
133
134 /* Like make_string_hash_table, but uses unsigned_string_hash and
135    unsigned_string_cmp.  */
136
137 static struct hash_table *
138 make_unsigned_string_hash_table (int initial_size)
139 {
140   return hash_table_new (initial_size,
141                          unsigned_string_hash, unsigned_string_cmp);
142 }
143
144 /* Write "HOST:PORT" to RESULT.  RESULT should be a pointer, and the
145   memory for the contents is allocated on the stack.  Useful for
146   creating HOST:PORT strings, which are the keys in the hash
147   table.  */
148
149 #define SET_HOSTPORT(host, port, result) do {           \
150   int HP_len = strlen (host);                           \
151   result = alloca (HP_len + 1 + numdigit (port) + 1);   \
152   memcpy (result, host, HP_len);                        \
153   result[HP_len] = ':';                                 \
154   long_to_string (result + HP_len + 1, port);           \
155 } while (0)
156
157 /* Find cookie chain that corresponds to DOMAIN (exact) and PORT.  */
158
159 static struct cookie *
160 find_cookie_chain_exact (const char *domain, int port)
161 {
162   char *key;
163   if (!cookies_hash_table)
164     return NULL;
165   SET_HOSTPORT (domain, port, key);
166   return hash_table_get (cookies_hash_table, key);
167 }
168 \f
169 /* Functions for storing cookies.
170
171    All cookies can be referenced through cookies_hash_table.  The key
172    in that table is the domain name, and the value is a linked list of
173    all cookies from that domain.  Every new cookie is placed on the
174    head of the list.  */
175
176 /* Find and return the cookie whose domain, path, and attribute name
177    correspond to COOKIE.  If found, PREVPTR will point to the location
178    of the cookie previous in chain, or NULL if the found cookie is the
179    head of a chain.
180
181    If no matching cookie is found, return NULL. */
182
183 static struct cookie *
184 find_matching_cookie (struct cookie *cookie, struct cookie **prevptr)
185 {
186   struct cookie *chain, *prev;
187
188   if (!cookies_hash_table)
189     goto nomatch;
190
191   chain = find_cookie_chain_exact (cookie->domain, cookie->port);
192   if (!chain)
193     goto nomatch;
194
195   prev = NULL;
196   for (; chain; prev = chain, chain = chain->next)
197     if (!strcmp (cookie->path, chain->path)
198         && !strcmp (cookie->attr, chain->attr))
199       {
200         *prevptr = prev;
201         return chain;
202       }
203
204  nomatch:
205   *prevptr = NULL;
206   return NULL;
207 }
208
209 /* Store COOKIE to memory.
210
211    This is done by placing COOKIE at the head of its chain.  However,
212    if COOKIE matches a cookie already in memory, as determined by
213    find_matching_cookie, the old cookie is unlinked and destroyed.
214
215    The key of each chain's hash table entry is allocated only the
216    first time; next hash_table_put's reuse the same key.  */
217
218 static void
219 store_cookie (struct cookie *cookie)
220 {
221   struct cookie *chain_head;
222   char *hostport;
223   char *chain_key;
224
225   if (!cookies_hash_table)
226     /* If the hash table is not initialized, do so now, because we'll
227        need to store things.  */
228     cookies_hash_table = make_unsigned_string_hash_table (0);
229
230   /* Initialize hash table key.  */
231   SET_HOSTPORT (cookie->domain, cookie->port, hostport);
232
233   if (hash_table_get_pair (cookies_hash_table, hostport,
234                            &chain_key, &chain_head))
235     {
236       /* There already exists a chain of cookies with this exact
237          domain.  We need to check for duplicates -- if an existing
238          cookie exactly matches our domain, path and name, we replace
239          it.  */
240       struct cookie *prev;
241       struct cookie *victim = find_matching_cookie (cookie, &prev);
242
243       if (victim)
244         {
245           /* Remove VICTIM from the chain.  COOKIE will be placed at
246              the head. */
247           if (prev)
248             {
249               prev->next = victim->next;
250               cookie->next = chain_head;
251             }
252           else
253             {
254               /* prev is NULL; apparently VICTIM was at the head of
255                  the chain.  This place will be taken by COOKIE, so
256                  all we need to do is:  */
257               cookie->next = victim->next;
258             }
259           delete_cookie (victim);
260           DEBUGP (("Deleted old cookie (to be replaced.)\n"));
261         }
262       else
263         cookie->next = chain_head;
264     }
265   else
266     {
267       /* We are now creating the chain.  Allocate the string that will
268          be used as a key.  It is unsafe to use cookie->domain for
269          that, because it might get deallocated by the above code at
270          some point later.  */
271       cookie->next = NULL;
272       chain_key = xstrdup (hostport);
273     }
274
275   hash_table_put (cookies_hash_table, chain_key, cookie);
276
277   DEBUGP (("\nStored cookie %s %d %s %s %d %s %s %s\n",
278            cookie->domain, cookie->port, cookie->path,
279            cookie->permanent ? "permanent" : "nonpermanent",
280            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 headlen;
709   const char *tail;
710
711   DEBUGP (("cdm: 1"));
712
713   /* Numeric address requires exact match.  It also requires HOST to
714      be an IP address.  I suppose we *could* resolve HOST with
715      store_hostaddress (it would hit the hash table), but rfc2109
716      doesn't require it, and it doesn't seem very useful, so we
717      don't.  */
718   if (numeric_address_p (cookie_domain))
719     return !strcmp (cookie_domain, host);
720
721   DEBUGP ((" 2"));
722
723   /* The domain must contain at least one embedded dot. */
724   {
725     const char *rest = cookie_domain;
726     int len = strlen (rest);
727     if (*rest == '.')
728       ++rest, --len;            /* ignore first dot */
729     if (len <= 0)
730       return 0;
731     if (rest[len - 1] == '.')
732       --len;                    /* ignore last dot */
733
734     if (!memchr (rest, '.', len))
735       /* No dots. */
736       return 0;
737   }
738
739   DEBUGP ((" 3"));
740
741   /* For the sake of efficiency, check for exact match first. */
742   if (!strcasecmp (cookie_domain, host))
743     return 1;
744
745   DEBUGP ((" 4"));
746
747   /* In rfc2109 terminology, HOST needs domain-match COOKIE_DOMAIN.
748      This means that COOKIE_DOMAIN needs to start with `.' and be an
749      FQDN, and that HOST must end with COOKIE_DOMAIN.  */
750   if (*cookie_domain != '.')
751     return 0;
752
753   DEBUGP ((" 5"));
754
755   /* Two proceed, we need to examine two parts of HOST: its head and
756      its tail.  Head and tail are defined in terms of the length of
757      the domain, like this:
758
759        HHHHTTTTTTTTTTTTTTT  <- host
760            DDDDDDDDDDDDDDD  <- domain
761
762      That is, "head" is the part of the host before (dlen - hlen), and
763      "tail" is what follows.
764
765      For the domain to match, two conditions need to be true:
766
767      1. Tail must equal DOMAIN.
768      2. Head must not contain an embedded dot.  */
769
770   headlen = strlen (host) - strlen (cookie_domain);
771
772   if (headlen <= 0)
773     /* DOMAIN must be a proper subset of HOST. */
774     return 0;
775   tail = host + headlen;
776
777   DEBUGP ((" 6"));
778
779   /* (1) */
780   if (strcasecmp (tail, cookie_domain))
781     return 0;
782
783   DEBUGP ((" 7"));
784
785   /* Test (2) is not part of the "domain-match" itself, but is
786      recommended by rfc2109 for reasons of privacy.  */
787
788   /* (2) */
789   if (memchr (host, '.', headlen))
790     return 0;
791
792   DEBUGP ((" 8"));
793
794   return 1;
795 }
796
797 static int path_matches PARAMS ((const char *, const char *));
798
799 /* Check whether PATH begins with COOKIE_PATH. */
800
801 static int
802 check_path_match (const char *cookie_path, const char *path)
803 {
804   return path_matches (path, cookie_path);
805 }
806 \f
807 /* Parse the `Set-Cookie' header and, if the cookie is legal, store it
808    to memory.  */
809
810 int
811 set_cookie_header_cb (const char *hdr, void *closure)
812 {
813   struct urlinfo *u = (struct urlinfo *)closure;
814   struct cookie *cookie;
815
816   cookies_now = time (NULL);
817
818   cookie = parse_set_cookies (hdr);
819   if (!cookie)
820     goto out;
821
822   /* Sanitize parts of cookie. */
823
824   if (!cookie->domain)
825     cookie->domain = xstrdup (u->host);
826   else
827     {
828       if (!check_domain_match (cookie->domain, u->host))
829         {
830           DEBUGP (("Attempt to fake the domain: %s, %s\n",
831                    cookie->domain, u->host));
832           goto out;
833         }
834     }
835   if (!cookie->path)
836     cookie->path = xstrdup (u->path);
837   else
838     {
839       if (!check_path_match (cookie->path, u->path))
840         {
841           DEBUGP (("Attempt to fake the path: %s, %s\n",
842                    cookie->path, u->path));
843           goto out;
844         }
845     }
846
847   cookie->port = u->port;
848
849   if (cookie->discard_requested)
850     {
851       discard_matching_cookie (cookie);
852       delete_cookie (cookie);
853       return 1;
854     }
855
856   store_cookie (cookie);
857   return 1;
858
859  out:
860   if (cookie)
861     delete_cookie (cookie);
862   return 1;
863 }
864 \f
865 /* Support for sending out cookies in HTTP requests, based on
866    previously stored cookies.  Entry point is
867    `build_cookies_request'.  */
868
869
870 /* Count how many times CHR occurs in STRING. */
871
872 static int
873 count_char (const char *string, char chr)
874 {
875   const char *p;
876   int count = 0;
877   for (p = string; *p; p++)
878     if (*p == chr)
879       ++count;
880   return count;
881 }
882
883 /* Store CHAIN to STORE if there is room in STORE.  If not, inrecement
884    COUNT anyway, so that when the function is done, we end up with the
885    exact count of how much place we actually need.  */
886
887 #define STORE_CHAIN(st_chain, st_store, st_size, st_count) do { \
888   if (st_count < st_size)                                       \
889     store[st_count] = st_chain;                                 \
890   ++st_count;                                                   \
891 } while (0)
892
893 /* Store cookie chains that match HOST, PORT.  Since more than one
894    chain can match, the matches are written to STORE.  No more than
895    SIZE matches are written; if more matches are present, return the
896    number of chains that would have been written.  */
897
898 int
899 find_matching_chains (const char *host, int port,
900                       struct cookie *store[], int size)
901 {
902   struct cookie *chain;
903   int dot_count;
904   char *hash_key;
905   int count = 0;
906
907   if (!cookies_hash_table)
908     return 0;
909
910   SET_HOSTPORT (host, port, hash_key);
911
912   /* Exact match. */
913   chain = hash_table_get (cookies_hash_table, hash_key);
914   if (chain)
915     STORE_CHAIN (chain, store, size, count);
916
917   dot_count = count_char (host, '.');
918
919   /* Match less and less specific domains.  For instance, given
920      fly.srk.fer.hr, we match .srk.fer.hr, then .fer.hr.  */
921   while (dot_count-- > 1)
922     {
923       /* Note: we operate directly on hash_key (in form host:port)
924          because we don't want to allocate new hash keys in a
925          loop.  */
926       char *p = strchr (hash_key, '.');
927       assert (p != NULL);
928       chain = hash_table_get (cookies_hash_table, p);
929       if (chain)
930         STORE_CHAIN (chain, store, size, count);
931       hash_key = p + 1;
932     }
933   return count;
934 }
935
936 /* If FULL_PATH begins with PREFIX, return the length of PREFIX, zero
937    otherwise.  */
938
939 static int
940 path_matches (const char *full_path, const char *prefix)
941 {
942   int len = strlen (prefix);
943   if (strncmp (full_path, prefix, len))
944     /* FULL_PATH doesn't begin with PREFIX. */
945     return 0;
946
947   /* Length of PREFIX determines the quality of the match. */
948   return len;
949 }
950
951 static int
952 matching_cookie (const struct cookie *cookie, const char *path,
953                  int connection_secure_p, int *path_goodness)
954 {
955   int pg;
956
957   if (cookie->expiry_time < cookies_now)
958     /* Ignore stale cookies.  There is no need to unchain the cookie
959        at this point -- Wget is a relatively short-lived application,
960        and stale cookies will not be saved by `save_cookies'.  */
961     return 0;
962   if (cookie->secure && !connection_secure_p)
963     /* Don't transmit secure cookies over an insecure connection.  */
964     return 0;
965   pg = path_matches (path, cookie->path);
966   if (!pg)
967     return 0;
968
969   if (path_goodness)
970     /* If the caller requested path_goodness, we return it.  This is
971        an optimization, so that the caller doesn't need to call
972        path_matches() again.  */
973     *path_goodness = pg;
974   return 1;
975 }
976
977 struct weighed_cookie {
978   struct cookie *cookie;
979   int domain_goodness;
980   int path_goodness;
981 };
982
983 /* Comparator used for uniquifying the list. */
984
985 static int
986 equality_comparator (const void *p1, const void *p2)
987 {
988   struct weighed_cookie *wc1 = (struct weighed_cookie *)p1;
989   struct weighed_cookie *wc2 = (struct weighed_cookie *)p2;
990
991   int namecmp  = strcmp (wc1->cookie->attr, wc2->cookie->attr);
992   int valuecmp = strcmp (wc1->cookie->value, wc2->cookie->value);
993
994   /* We only really care whether both name and value are equal.  We
995      return them in this order only for consistency...  */
996   return namecmp ? namecmp : valuecmp;
997 }
998
999 /* Eliminate duplicate cookies.  "Duplicate cookies" are any two
1000    cookies whose name and value are the same.  Whenever a duplicate
1001    pair is found, one of the cookies is removed.  */
1002
1003 static int
1004 eliminate_dups (struct weighed_cookie *outgoing, int count)
1005 {
1006   int i;
1007
1008   /* We deploy a simple uniquify algorithm: first sort the array
1009      according to our sort criterion, then uniquify it by comparing
1010      each cookie with its neighbor.  */
1011
1012   qsort (outgoing, count, sizeof (struct weighed_cookie), equality_comparator);
1013
1014   for (i = 0; i < count - 1; i++)
1015     {
1016       struct cookie *c1 = outgoing[i].cookie;
1017       struct cookie *c2 = outgoing[i + 1].cookie;
1018       if (!strcmp (c1->attr, c2->attr) && !strcmp (c1->value, c2->value))
1019         {
1020           /* c1 and c2 are the same; get rid of c2. */
1021           if (count > i + 1)
1022             /* move all ptrs from positions [i + 1, count) to i. */
1023             memmove (outgoing + i, outgoing + i + 1,
1024                      (count - (i + 1)) * sizeof (struct weighed_cookie));
1025           /* We decrement i to counter the ++i above.  Remember that
1026              we've just removed the element in front of us; we need to
1027              remain in place to check whether outgoing[i] matches what
1028              used to be outgoing[i + 2].  */
1029           --i;
1030           --count;
1031         }
1032     }
1033   return count;
1034 }
1035
1036 /* Comparator used for sorting by quality. */
1037
1038 static int
1039 goodness_comparator (const void *p1, const void *p2)
1040 {
1041   struct weighed_cookie *wc1 = (struct weighed_cookie *)p1;
1042   struct weighed_cookie *wc2 = (struct weighed_cookie *)p2;
1043
1044   /* Subtractions take `wc2' as the first argument becauase we want a
1045      sort in *decreasing* order of goodness.  */
1046   int dgdiff = wc2->domain_goodness - wc1->domain_goodness;
1047   int pgdiff = wc2->path_goodness - wc1->path_goodness;
1048
1049   /* Sort by domain goodness; if these are the same, sort by path
1050      goodness.  (The sorting order isn't really specified; maybe it
1051      should be the other way around.)  */
1052   return dgdiff ? dgdiff : pgdiff;
1053 }
1054
1055 /* Build a `Cookie' header for a request that goes to HOST:PORT and
1056    requests PATH from the server.  The resulting string is allocated
1057    with `malloc', and the caller is responsible for freeing it.  If no
1058    cookies pertain to this request, i.e. no cookie header should be
1059    generated, NULL is returned.  */
1060
1061 char *
1062 build_cookies_request (const char *host, int port, const char *path,
1063                        int connection_secure_p)
1064 {
1065   struct cookie *chain_default_store[20];
1066   struct cookie **all_chains = chain_default_store;
1067   int chain_store_size = ARRAY_SIZE (chain_default_store);
1068   int chain_count;
1069
1070   struct cookie *cookie;
1071   struct weighed_cookie *outgoing;
1072   int count, i, ocnt;
1073   char *result;
1074   int result_size, pos;
1075
1076  again:
1077   chain_count = find_matching_chains (host, port, all_chains, chain_store_size);
1078   if (chain_count > chain_store_size)
1079     {
1080       /* It's extremely unlikely that more than 20 chains will ever
1081          match.  But since find_matching_chains reports the exact size
1082          it needs, it's easy to not have the limitation, so we
1083          don't.  */
1084       all_chains = alloca (chain_count * sizeof (struct cookie *));
1085       chain_store_size = chain_count;
1086       goto again;
1087     }
1088
1089   if (!chain_count)
1090     return NULL;
1091
1092   cookies_now = time (NULL);
1093
1094   /* Count the number of cookies whose path matches. */
1095   count = 0;
1096   for (i = 0; i < chain_count; i++)
1097     for (cookie = all_chains[i]; cookie; cookie = cookie->next)
1098       if (matching_cookie (cookie, path, connection_secure_p, NULL))
1099         ++count;
1100   if (!count)
1101     /* No matching cookies. */
1102     return NULL;
1103
1104   /* Allocate the array. */
1105   outgoing = alloca (count * sizeof (struct weighed_cookie));
1106
1107   /* Fill the array with all the matching cookies from all the
1108      matching chains. */
1109   ocnt = 0;
1110   for (i = 0; i < chain_count; i++)
1111     for (cookie = all_chains[i]; cookie; cookie = cookie->next)
1112       {
1113         int pg;
1114         if (!matching_cookie (cookie, path, connection_secure_p, &pg))
1115           continue;
1116         outgoing[ocnt].cookie = cookie;
1117         outgoing[ocnt].domain_goodness = strlen (cookie->domain);
1118         outgoing[ocnt].path_goodness   = pg;
1119         ++ocnt;
1120       }
1121   assert (ocnt == count);
1122
1123   /* Eliminate duplicate cookies; that is, those whose name and value
1124      are the same.  */
1125   count = eliminate_dups (outgoing, count);
1126
1127   /* Sort the array so that best-matching domains come first, and
1128      that, within one domain, best-matching paths come first. */
1129   qsort (outgoing, count, sizeof (struct weighed_cookie), goodness_comparator);
1130
1131   /* Count the space the name=value pairs will take. */
1132   result_size = 0;
1133   for (i = 0; i < count; i++)
1134     {
1135       struct cookie *c = outgoing[i].cookie;
1136       /* name=value */
1137       result_size += strlen (c->attr) + 1 + strlen (c->value);
1138     }
1139
1140   /* Allocate output buffer:
1141      "Cookie: "       -- 8
1142      name=value pairs -- result_size
1143      "; " separators  -- (count - 1) * 2
1144      \r\n line ending -- 2
1145      \0 terminator    -- 1 */
1146   result_size = 8 + result_size + (count - 1) * 2 + 2 + 1;
1147   result = xmalloc (result_size);
1148   pos = 0;
1149   strcpy (result, "Cookie: ");
1150   pos += 8;
1151   for (i = 0; i < count; i++)
1152     {
1153       struct cookie *c = outgoing[i].cookie;
1154       int namlen = strlen (c->attr);
1155       int vallen = strlen (c->value);
1156
1157       memcpy (result + pos, c->attr, namlen);
1158       pos += namlen;
1159       result[pos++] = '=';
1160       memcpy (result + pos, c->value, vallen);
1161       pos += vallen;
1162       if (i < count - 1)
1163         {
1164           result[pos++] = ';';
1165           result[pos++] = ' ';
1166         }
1167     }
1168   result[pos++] = '\r';
1169   result[pos++] = '\n';
1170   result[pos++] = '\0';
1171   assert (pos == result_size);
1172   return result;
1173 }
1174 \f
1175 /* Support for loading and saving cookies.  The format used for
1176    loading and saving roughly matches the format of `cookies.txt' file
1177    used by Netscape and Mozilla, at least the Unix versions.  The
1178    format goes like this:
1179
1180        DOMAIN DOMAIN-FLAG PATH SECURE-FLAG TIMESTAMP ATTR-NAME ATTR-VALUE
1181
1182      DOMAIN      -- cookie domain, optionally followed by :PORT
1183      DOMAIN-FLAG -- whether all hosts in the domain match
1184      PATH        -- cookie path
1185      SECURE-FLAG -- whether cookie requires secure connection
1186      TIMESTAMP   -- expiry timestamp, number of seconds since epoch
1187      ATTR-NAME   -- name of the cookie attribute
1188      ATTR-VALUE  -- value of the cookie attribute (empty if absent)
1189
1190    The fields are separated by TABs (but Wget's loader recognizes any
1191    whitespace).  All fields are mandatory, except for ATTR-VALUE.  The
1192    `-FLAG' fields are boolean, their legal values being "TRUE" and
1193    "FALSE'.  Empty lines, lines consisting of whitespace only, and
1194    comment lines (beginning with # optionally preceded by whitespace)
1195    are ignored.
1196
1197    Example line from cookies.txt (split in two lines for readability):
1198
1199        .google.com      TRUE    /       FALSE   2147368447      \
1200        PREF     ID=34bb47565bbcd47b:LD=en:NR=20:TM=985172580:LM=985739012
1201
1202    DOMAIN-FLAG is currently not honored by Wget.  The cookies whose
1203    domain begins with `.' are treated as if DOMAIN-FLAG were true,
1204    while all other cookies are treated as if it were FALSE. */
1205
1206
1207 /* If the region [B, E) ends with :<digits>, parse the number, return
1208    it, and store new boundary (location of the `:') to DOMAIN_E_PTR.
1209    If port is not specified, return 0.  */
1210
1211 static int
1212 domain_port (const char *domain_b, const char *domain_e,
1213              const char **domain_e_ptr)
1214 {
1215   int port = 0;
1216   const char *p;
1217   const char *colon = memchr (domain_b, ':', domain_e - domain_b);
1218   if (!colon)
1219     return 0;
1220   for (p = colon + 1; p < domain_e && ISDIGIT (*p); p++)
1221     port = 10 * port + (*p - '0');
1222   if (p < domain_e)
1223     /* Garbage following port number. */
1224     return 0;
1225   *domain_e_ptr = colon;
1226   return port;
1227 }
1228
1229 #define SKIP_WS(p) do {                         \
1230   while (*p && ISSPACE (*p))                    \
1231     ++p;                                        \
1232 } while (0)
1233
1234 #define SET_WORD_BOUNDARIES(p, b, e) do {       \
1235   SKIP_WS (p);                                  \
1236   b = p;                                        \
1237   /* skip non-ws */                             \
1238   while (*p && !ISSPACE (*p))                   \
1239     ++p;                                        \
1240   e = p;                                        \
1241   if (b == e)                                   \
1242     goto next;                                  \
1243 } while (0)
1244
1245 /* Load cookies from FILE.  */
1246
1247 void
1248 load_cookies (const char *file)
1249 {
1250   char *line;
1251   FILE *fp = fopen (file, "r");
1252   if (!fp)
1253     {
1254       logprintf (LOG_NOTQUIET, "Cannot open cookies file `%s': %s\n",
1255                  file, strerror (errno));
1256       return;
1257     }
1258   cookies_now = time (NULL);
1259
1260   for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
1261     {
1262       struct cookie *cookie;
1263       char *p = line;
1264
1265       int port;
1266
1267       char *domain_b  = NULL, *domain_e  = NULL;
1268       char *ignore_b  = NULL, *ignore_e  = NULL;
1269       char *path_b    = NULL, *path_e    = NULL;
1270       char *secure_b  = NULL, *secure_e  = NULL;
1271       char *expires_b = NULL, *expires_e = NULL;
1272       char *name_b    = NULL, *name_e    = NULL;
1273       char *value_b   = NULL, *value_e   = NULL;
1274
1275       SKIP_WS (p);
1276
1277       if (!*p || *p == '#')
1278         /* empty line */
1279         continue;
1280
1281       SET_WORD_BOUNDARIES (p, domain_b,  domain_e);
1282       SET_WORD_BOUNDARIES (p, ignore_b,  ignore_e);
1283       SET_WORD_BOUNDARIES (p, path_b,    path_e);
1284       SET_WORD_BOUNDARIES (p, secure_b,  secure_e);
1285       SET_WORD_BOUNDARIES (p, expires_b, expires_e);
1286       SET_WORD_BOUNDARIES (p, name_b,    name_e);
1287
1288       /* Don't use SET_WORD_BOUNDARIES for value because it may
1289          contain whitespace.  Instead, set value_e to the end of line,
1290          modulo trailing space (this will skip the line separator.) */
1291       SKIP_WS (p);
1292       value_b = p;
1293       value_e = p + strlen (p);
1294       while (value_e > value_b && ISSPACE (*(value_e - 1)))
1295         --value_e;
1296       if (value_b == value_e)
1297         /* Hmm, should we check for empty value?  I guess that's
1298            legal, so I leave it.  */
1299         ;
1300
1301       cookie = cookie_new ();
1302
1303       cookie->attr    = strdupdelim (name_b, name_e);
1304       cookie->value   = strdupdelim (value_b, value_e);
1305       cookie->path    = strdupdelim (path_b, path_e);
1306
1307       if (BOUNDED_EQUAL (secure_b, secure_e, "TRUE"))
1308         cookie->secure = 1;
1309
1310       /* DOMAIN needs special treatment because we might need to
1311          extract the port.  */
1312       port = domain_port (domain_b, domain_e, (const char **)&domain_e);
1313       if (port)
1314         cookie->port = port;
1315       else
1316         cookie->port = cookie->secure ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;
1317
1318       cookie->domain  = strdupdelim (domain_b, domain_e);
1319
1320       /* safe default in case EXPIRES field is garbled. */
1321       cookie->expiry_time = cookies_now - 1;
1322
1323       /* I don't like changing the line, but it's completely safe.
1324          (line is malloced.)  */
1325       *expires_e = '\0';
1326       sscanf (expires_b, "%lu", &cookie->expiry_time);
1327       if (cookie->expiry_time < cookies_now)
1328         /* ignore stale cookie. */
1329         goto abort;
1330       cookie->permanent = 1;
1331
1332       store_cookie (cookie);
1333
1334     next:
1335       continue;
1336
1337     abort:
1338       delete_cookie (cookie);
1339     }
1340   fclose (fp);
1341 }
1342
1343 /* Mapper for save_cookies callable by hash_table_map.  VALUE points
1344    to the head in a chain of cookies.  The function prints the entire
1345    chain.  */
1346
1347 static int
1348 save_cookies_mapper (void *key, void *value, void *arg)
1349 {
1350   FILE *fp = (FILE *)arg;
1351   char *domain = (char *)key;
1352   struct cookie *chain = (struct cookie *)value;
1353   for (; chain; chain = chain->next)
1354     {
1355       if (!chain->permanent)
1356         continue;
1357       if (chain->expiry_time < cookies_now)
1358         continue;
1359       fprintf (fp, "%s\t%s\t%s\t%s\t%lu\t%s\t%s\n",
1360                domain, *domain == '.' ? "TRUE" : "FALSE",
1361                chain->path, chain->secure ? "TRUE" : "FALSE",
1362                chain->expiry_time,
1363                chain->attr, chain->value);
1364       if (ferror (fp))
1365         return 1;               /* stop mapping */
1366     }
1367   return 0;
1368 }
1369
1370 /* Save cookies, in format described above, to FILE. */
1371
1372 void
1373 save_cookies (const char *file)
1374 {
1375   FILE *fp;
1376
1377   if (!cookies_hash_table
1378       || !hash_table_count (cookies_hash_table))
1379     /* no cookies stored; nothing to do. */
1380     return;
1381
1382   DEBUGP (("Saving cookies to %s.\n", file));
1383
1384   cookies_now = time (NULL);
1385
1386   fp = fopen (file, "w");
1387   if (!fp)
1388     {
1389       logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
1390                  file, strerror (errno));
1391       return;
1392     }
1393
1394   fputs ("# HTTP cookie file.\n", fp);
1395   fprintf (fp, "# Generated by Wget on %s.\n", datetime_str (NULL));
1396   fputs ("# Edit at your own risk.\n\n", fp);
1397
1398   hash_table_map (cookies_hash_table, save_cookies_mapper, fp);
1399
1400   if (ferror (fp))
1401     logprintf (LOG_NOTQUIET, _("Error writing to `%s': %s\n"),
1402                file, strerror (errno));
1403
1404   if (fclose (fp) < 0)
1405     logprintf (LOG_NOTQUIET, _("Error closing `%s': %s\n"),
1406                file, strerror (errno));
1407
1408   DEBUGP (("Done saving cookies.\n"));
1409 }
1410 \f
1411 static int
1412 delete_cookie_chain_mapper (void *value, void *key, void *arg_ignored)
1413 {
1414   char *chain_key = (char *)value;
1415   struct cookie *chain = (struct cookie *)key;
1416
1417   /* Remove the chain from the table and free the key. */
1418   hash_table_remove (cookies_hash_table, chain_key);
1419   xfree (chain_key);
1420
1421   /* Then delete all the cookies in the chain. */
1422   while (chain)
1423     {
1424       struct cookie *next = chain->next;
1425       delete_cookie (chain);
1426       chain = next;
1427     }
1428
1429   /* Keep mapping. */
1430   return 0;
1431 }
1432
1433 /* Clean up cookie-related data. */
1434
1435 void
1436 cookies_cleanup (void)
1437 {
1438   if (!cookies_hash_table)
1439     return;
1440   hash_table_map (cookies_hash_table, delete_cookie_chain_mapper, NULL);
1441   hash_table_destroy (cookies_hash_table);
1442   cookies_hash_table = NULL;
1443 }