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