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