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