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