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