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