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