annotate dpi/cookies.c @ 1522:85062b64ae9d

cookies allow Expires attr's value to be quoted. sourceforge sends cookies this way. It seems that quotes around values are generally to be ignored, i.e., not stripped or anything, but I asked the draft spec author about this case, and he reports that he has fixed his algorithm to allow leading and trailing delimiters around cookie-date. If I/someone eventually does make the timestamp code follow the algorithm more closely, the stripping would no longer need to be done here. As for whether we'd want to continue to use that code for the stricter server_date that we get from the HTTP Date header, I'm not sure at the moment. I've already added one case to it that wouldn't be legal for the header, though...
author corvid <corvid@lavabit.com>
date Mon, 18 Jan 2010 00:57:58 +0000
parents 6fcb13a8b680
children 03752405e0a9
rev   line source
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
2 * File: cookies.c
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
3 * Cookies server.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
4 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
5 * Copyright 2001 Lars Clausen <lrclause@cs.uiuc.edu>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
6 * Jörgen Viksell <jorgen.viksell@telia.com>
35
d9e7b35430de Updated copyright lines
jcid
parents: 0
diff changeset
7 * Copyright 2002-2007 Jorge Arellano Cid <jcid@dillo.org>
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
8 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
9 * This program is free software; you can redistribute it and/or modify
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
10 * it under the terms of the GNU General Public License as published by
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
11 * the Free Software Foundation; either version 3 of the License, or
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
12 * (at your option) any later version.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
13 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
14 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
15
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
16 /* This is written to follow the HTTP State Working Group's
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
17 * draft-ietf-httpstate-cookie-01.txt.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
18 *
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
19 * We depart from the draft spec's domain format in that, rather than
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
20 * using a host-only flag, we continue to use the .domain notation
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
21 * internally to indicate cookies that may also be returned to subdomains.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
22 *
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
23 * Info on cookies in the wild:
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
24 * http://www.ietf.org/mail-archive/web/http-state/current/msg00078.html
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
25 * And dates specifically:
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
26 * http://www.ietf.org/mail-archive/web/http-state/current/msg00128.html
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
27 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
28
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
29 #ifdef DISABLE_COOKIES
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
30
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
31 int main(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
32 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
33 return 0; /* never called */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
34 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
35
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
36 #else
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
37
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
38
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
39 #include <sys/types.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
40 #include <sys/socket.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
41 #include <sys/stat.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
42 #include <sys/un.h>
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
43 #include <netinet/in.h>
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
44 #include <fcntl.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
45 #include <unistd.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
46 #include <errno.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
47 #include <stddef.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
48 #include <string.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
49 #include <stdlib.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
50 #include <stdio.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
51 #include <time.h> /* for time() and time_t */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
52 #include <ctype.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
53 #include <netdb.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
54 #include <signal.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
55 #include "dpiutil.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
56 #include "../dpip/dpip.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
57
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
58
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
59 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
60 * Debugging macros
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
61 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
62 #define _MSG(...)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
63 #define MSG(...) printf("[cookies dpi]: " __VA_ARGS__)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
64
1508
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
65 #define DILLO_TIME_MAX ((time_t) ((1UL << (sizeof(time_t) * 8 - 1)) - 1))
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
66
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
67 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
68 * a_List_add()
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
69 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
70 * Make sure there's space for 'num_items' items within the list
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
71 * (First, allocate an 'alloc_step' sized chunk, after that, double the
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
72 * list size --to make it faster)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
73 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
74 #define a_List_add(list,num_items,alloc_step) \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
75 if (!list) { \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
76 list = dMalloc(alloc_step * sizeof((*list))); \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
77 } \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
78 if (num_items >= alloc_step){ \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
79 while ( num_items >= alloc_step ) \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
80 alloc_step <<= 1; \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
81 list = dRealloc(list, alloc_step * sizeof((*list))); \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
82 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
83
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
84 /* The maximum length of a line in the cookie file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
85 #define LINE_MAXLEN 4096
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
86
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
87 typedef enum {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
88 COOKIE_ACCEPT,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
89 COOKIE_ACCEPT_SESSION,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
90 COOKIE_DENY
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
91 } CookieControlAction;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
92
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
93 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
94 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
95 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
96 } CookieControl;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
97
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
98 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
99 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
100 Dlist *dlist;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
101 } CookieNode;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
102
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
103 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
104 char *name;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
105 char *value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
106 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
107 char *path;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
108 time_t expires_at;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
109 bool_t secure;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
110 bool_t session_only;
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
111 long last_used;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
112 } CookieData_t;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
113
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
114 typedef struct {
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
115 Dsh *sh;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
116 int status;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
117 } ClientInfo;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
118
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
119 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
120 * Local data
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
121 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
122
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
123 /* List of CookieNode. Each node holds a domain and its list of cookies */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
124 static Dlist *cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
125
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
126 /* Variables for access control */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
127 static CookieControl *ccontrol = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
128 static int num_ccontrol = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
129 static int num_ccontrol_max = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
130 static CookieControlAction default_action = COOKIE_DENY;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
131
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
132 static long cookies_use_counter = 0;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
133 static bool_t disabled;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
134 static FILE *file_stream;
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
135 static const char *const cookies_txt_header_str =
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
136 "# HTTP Cookie File\n"
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
137 "# This is a generated file! Do not edit.\n"
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
138 "# [domain TRUE path secure expiry_time name value]\n\n";
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
139
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
140
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
141 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
142 * Forward declarations
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
143 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
144
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
145 static CookieControlAction Cookies_control_check_domain(const char *domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
146 static int Cookie_control_init(void);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
147 static void Cookies_add_cookie(CookieData_t *cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
148 static int Cookies_cmp(const void *a, const void *b);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
149
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
150 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
151 * Compare function for searching a cookie node
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
152 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
153 static int Cookie_node_cmp(const void *v1, const void *v2)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
154 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
155 const CookieNode *n1 = v1, *n2 = v2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
156
1484
29d892265da0 domain comparison not case-sensitive
corvid <corvid@lavabit.com>
parents: 1483
diff changeset
157 return dStrcasecmp(n1->domain, n2->domain);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
158 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
159
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
160 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
161 * Compare function for searching a cookie node by domain
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
162 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
163 static int Cookie_node_by_domain_cmp(const void *v1, const void *v2)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
164 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
165 const CookieNode *node = v1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
166 const char *domain = v2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
167
1484
29d892265da0 domain comparison not case-sensitive
corvid <corvid@lavabit.com>
parents: 1483
diff changeset
168 return dStrcasecmp(node->domain, domain);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
169 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
170
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
171 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
172 * Return a file pointer. If the file doesn't exist, try to create it,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
173 * with the optional 'init_str' as its content.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
174 */
219
201d89d1d002 - Allowed readonly permissions for cookiesrc.
jcid
parents: 174
diff changeset
175 static FILE *Cookies_fopen(const char *filename, const char *mode,
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
176 const char *init_str)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
177 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
178 FILE *F_in;
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
179 int fd, rc;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
180
219
201d89d1d002 - Allowed readonly permissions for cookiesrc.
jcid
parents: 174
diff changeset
181 if ((F_in = fopen(filename, mode)) == NULL) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
182 /* Create the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
183 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
184 if (fd != -1) {
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
185 if (init_str) {
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
186 rc = write(fd, init_str, strlen(init_str));
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
187 if (rc == -1) {
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
188 MSG("Cookies: Could not write initial string to file %s: %s\n",
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
189 filename, dStrerror(errno));
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
190 }
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
191 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
192 close(fd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
193
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
194 MSG("Created file: %s\n", filename);
219
201d89d1d002 - Allowed readonly permissions for cookiesrc.
jcid
parents: 174
diff changeset
195 F_in = fopen(filename, mode);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
196 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
197 MSG("Could not create file: %s!\n", filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
198 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
199 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
200
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
201 if (F_in) {
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
202 /* set close on exec */
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
203 fcntl(fileno(F_in), F_SETFD, FD_CLOEXEC | fcntl(fileno(F_in), F_GETFD));
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
204 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
205
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
206 return F_in;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
207 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
208
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
209 static void Cookies_free_cookie(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
210 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
211 dFree(cookie->name);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
212 dFree(cookie->value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
213 dFree(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
214 dFree(cookie->path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
215 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
216 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
217
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
218 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
219 * Initialize the cookies module
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
220 * (The 'disabled' variable is writeable only within Cookies_init)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
221 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
222 static void Cookies_init()
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
223 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
224 CookieData_t *cookie;
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
225 char *filename, *rc = NULL;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
226 char line[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
227 #ifndef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
228 struct flock lck;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
229 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
230
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
231 /* Default setting */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
232 disabled = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
233
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
234 /* Read and parse the cookie control file (cookiesrc) */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
235 if (Cookie_control_init() != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
236 MSG("Disabling cookies.\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
237 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
238 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
239
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
240 /* Get a stream for the cookies file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
241 filename = dStrconcat(dGethomedir(), "/.dillo/cookies.txt", NULL);
219
201d89d1d002 - Allowed readonly permissions for cookiesrc.
jcid
parents: 174
diff changeset
242 file_stream = Cookies_fopen(filename, "r+", cookies_txt_header_str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
243
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
244 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
245
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
246 if (!file_stream) {
1495
a83b066cbcb3 rm support for ancient ~/.dillo/cookies file
corvid <corvid@lavabit.com>
parents: 1491
diff changeset
247 MSG("ERROR: Can't open ~/.dillo/cookies.txt; disabling cookies\n");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
248 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
249 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
250
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
251 /* Try to get a lock from the file descriptor */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
252 #ifdef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
253 disabled = (lockf(fileno(file_stream), F_TLOCK, 0) == -1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
254 #else /* POSIX lock */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
255 lck.l_start = 0; /* start at beginning of file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
256 lck.l_len = 0; /* lock entire file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
257 lck.l_type = F_WRLCK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
258 lck.l_whence = SEEK_SET; /* absolute offset */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
259
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
260 disabled = (fcntl(fileno(file_stream), F_SETLK, &lck) == -1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
261 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
262 if (disabled) {
1495
a83b066cbcb3 rm support for ancient ~/.dillo/cookies file
corvid <corvid@lavabit.com>
parents: 1491
diff changeset
263 MSG("The cookies file has a file lock; disabling cookies!\n");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
264 fclose(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
265 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
266 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
267
1495
a83b066cbcb3 rm support for ancient ~/.dillo/cookies file
corvid <corvid@lavabit.com>
parents: 1491
diff changeset
268 MSG("Enabling cookies as per cookiesrc...\n");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
269
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
270 cookies = dList_new(32);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
271
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
272 /* Get all lines in the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
273 while (!feof(file_stream)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
274 line[0] = '\0';
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
275 rc = fgets(line, LINE_MAXLEN, file_stream);
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
276 if (!rc && ferror(file_stream)) {
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
277 MSG("Error while reading from cookies.txt: %s\n", dStrerror(errno));
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
278 break; /* bail out */
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
279 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
280
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
281 /* Remove leading and trailing whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
282 dStrstrip(line);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
283
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
284 if ((line[0] != '\0') && (line[0] != '#')) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
285 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
286 * Split the row into pieces using a tab as the delimiter.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
287 * pieces[0] The domain name
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
288 * pieces[1] TRUE/FALSE: is the domain a suffix, or a full domain?
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
289 * pieces[2] The path
1495
a83b066cbcb3 rm support for ancient ~/.dillo/cookies file
corvid <corvid@lavabit.com>
parents: 1491
diff changeset
290 * pieces[3] TRUE/FALSE: is the cookie for secure use only?
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
291 * pieces[4] Timestamp of expire date
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
292 * pieces[5] Name of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
293 * pieces[6] Value of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
294 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
295 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
296 char *piece;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
297 char *line_marker = line;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
298
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
299 cookie = dNew0(CookieData_t, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
300
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
301 cookie->session_only = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
302 cookie->domain = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
303 dStrsep(&line_marker, "\t"); /* we use domain always as sufix */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
304 cookie->path = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
305 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
306 if (piece != NULL && piece[0] == 'T')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
307 cookie->secure = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
308 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
309 if (piece != NULL)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
310 cookie->expires_at = (time_t) strtol(piece, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
311 cookie->name = dStrdup(dStrsep(&line_marker, "\t"));
1518
deccee022a42 handle nameless/valueless cookies in cookies.txt
corvid <corvid@lavabit.com>
parents: 1517
diff changeset
312 cookie->value = dStrdup(line_marker ? line_marker : "");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
313
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
314 if (!cookie->domain || cookie->domain[0] == '\0' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
315 !cookie->path || cookie->path[0] != '/' ||
1518
deccee022a42 handle nameless/valueless cookies in cookies.txt
corvid <corvid@lavabit.com>
parents: 1517
diff changeset
316 !cookie->name || !cookie->value) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
317 MSG("Malformed line in cookies.txt file!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
318 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
319 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
320 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
321
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
322 action = Cookies_control_check_domain(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
323 if (action == COOKIE_DENY) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
324 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
325 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
326 } else if (action == COOKIE_ACCEPT_SESSION) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
327 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
328 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
329
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
330 /* Save cookie in memory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
331 Cookies_add_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
332 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
333 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
334 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
335
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
336 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
337 * Flush cookies to disk and free all the memory allocated.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
338 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
339 static void Cookies_save_and_free()
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
340 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
341 int i, fd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
342 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
343 CookieData_t *cookie;
1512
bd36920f32d4 don't bother to save expired cookies
corvid <corvid@lavabit.com>
parents: 1510
diff changeset
344 time_t now;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
345
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
346 #ifndef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
347 struct flock lck;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
348 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
349
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
350 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
351 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
352
1512
bd36920f32d4 don't bother to save expired cookies
corvid <corvid@lavabit.com>
parents: 1510
diff changeset
353 now = time(NULL);
bd36920f32d4 don't bother to save expired cookies
corvid <corvid@lavabit.com>
parents: 1510
diff changeset
354
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
355 rewind(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
356 fd = fileno(file_stream);
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
357 if (ftruncate(fd, 0) == -1)
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
358 MSG("Cookies: Truncate file stream failed: %s\n", dStrerror(errno));
454
c0d3c2ec7140 - Fixed a printf bug in cookies dpi.
jcid
parents: 445
diff changeset
359 fprintf(file_stream, "%s", cookies_txt_header_str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
360
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
361 /* Iterate cookies per domain, saving and freeing */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
362 while ((node = dList_nth_data(cookies, 0))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
363 for (i = 0; (cookie = dList_nth_data(node->dlist, i)); ++i) {
1512
bd36920f32d4 don't bother to save expired cookies
corvid <corvid@lavabit.com>
parents: 1510
diff changeset
364 if (!cookie->session_only && (cookie->expires_at > now)) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
365 fprintf(file_stream, "%s\tTRUE\t%s\t%s\t%ld\t%s\t%s\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
366 cookie->domain,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
367 cookie->path,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
368 cookie->secure ? "TRUE" : "FALSE",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
369 (long)cookie->expires_at,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
370 cookie->name,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
371 cookie->value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
372 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
373
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
374 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
375 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
376 dList_remove(cookies, node);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
377 dFree(node->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
378 dList_free(node->dlist);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
379 dFree(node);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
380 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
381
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
382 #ifdef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
383 lockf(fd, F_ULOCK, 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
384 #else /* POSIX file lock */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
385 lck.l_start = 0; /* start at beginning of file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
386 lck.l_len = 0; /* lock entire file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
387 lck.l_type = F_UNLCK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
388 lck.l_whence = SEEK_SET; /* absolute offset */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
389
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
390 fcntl(fileno(file_stream), F_SETLKW, &lck);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
391 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
392 fclose(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
393 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
394
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
395 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
396 * Take a months name and return a number between 1-12.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
397 * E.g. 'April' -> 4
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
398 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
399 static int Cookies_get_month(const char *month_name)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
400 {
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
401 static const char *const months[] =
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
402 { "",
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
403 "Jan", "Feb", "Mar",
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
404 "Apr", "May", "Jun",
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
405 "Jul", "Aug", "Sep",
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
406 "Oct", "Nov", "Dec"
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
407 };
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
408 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
409
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
410 for (i = 1; i <= 12; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
411 if (!dStrncasecmp(months[i], month_name, 3))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
412 return i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
413 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
414 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
415 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
416
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
417 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
418 * Return a local timestamp from a GMT date string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
419 * Accept: RFC-1123 | RFC-850 | ANSI asctime | Old Netscape format.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
420 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
421 * Wdy, DD-Mon-YY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
422 * Wdy, DD-Mon-YYYY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
423 * Weekday, DD-Mon-YY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
424 * Weekday, DD-Mon-YYYY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
425 * Tue May 21 13:46:22 1991\n
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
426 * Tue May 21 13:46:22 1991
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
427 *
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
428 * Let's add:
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
429 * Mon Jan 11 08:00:00 2010 GMT
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
430 *
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
431 * (return 0 on malformed date string syntax)
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
432 *
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
433 * NOTE that the draft spec wants user agents to be more flexible in what
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
434 * they accept. For now, let's hack in special cases when they're encountered.
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
435 * Why? Because this function is currently understandable, and I don't want to
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
436 * abandon that (or at best decrease that -- see section 5.1.1) until there
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
437 * is known to be good reason.
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
438 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
439 static time_t Cookies_create_timestamp(const char *expires)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
440 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
441 time_t ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
442 int day, month, year, hour, minutes, seconds;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
443 char *cp;
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
444 const char *const E_msg =
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
445 "Expire date is malformed!\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
446 " (should be RFC-1123 | RFC-850 | ANSI asctime)\n"
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
447 " Discarding cookie: ";
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
448
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
449 cp = strchr(expires, ',');
1500
335f1b3692c9 timestamps a little less strict
corvid <corvid@lavabit.com>
parents: 1499
diff changeset
450 if (!cp && strlen(expires)>20 && expires[13] == ':' && expires[16] == ':') {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
451 /* Looks like ANSI asctime format... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
452 cp = (char *)expires;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
453 day = strtol(cp + 8, NULL, 10); /* day */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
454 month = Cookies_get_month(cp + 4); /* month */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
455 year = strtol(cp + 20, NULL, 10); /* year */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
456 hour = strtol(cp + 11, NULL, 10); /* hour */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
457 minutes = strtol(cp + 14, NULL, 10); /* minutes */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
458 seconds = strtol(cp + 17, NULL, 10); /* seconds */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
459
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
460 } else if (cp && (cp - expires == 3 || cp - expires > 5) &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
461 (strlen(cp) == 24 || strlen(cp) == 26)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
462 /* RFC-1123 | RFC-850 format | Old Netscape format */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
463 day = strtol(cp + 2, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
464 month = Cookies_get_month(cp + 5);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
465 year = strtol(cp + 9, &cp, 10);
368
2242da885677 - s/todo:/TODO:/g
jcid
parents: 235
diff changeset
466 /* TODO: tricky, because two digits for year IS ambiguous! */
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
467 year += (year < 70) ? 2000 : ((year < 100) ? 1900 : 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
468 hour = strtol(cp + 1, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
469 minutes = strtol(cp + 4, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
470 seconds = strtol(cp + 7, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
471
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
472 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
473 MSG("%s%s\n", E_msg, expires);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
474 return (time_t) 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
475 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
476
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
477 /* Error checks --this may be overkill */
1127
65c7e33e4466 allow year 1970 in cookies
corvid <corvid@lavabit.com>
parents: 454
diff changeset
478 if (!(day > 0 && day < 32 && month > 0 && month < 13 && year >= 1970 &&
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
479 hour >= 0 && hour < 24 && minutes >= 0 && minutes < 60 &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
480 seconds >= 0 && seconds < 60)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
481 MSG("%s%s\n", E_msg, expires);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
482 return (time_t) 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
483 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
484
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
485 /* Calculate local timestamp.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
486 * [stolen from Lynx... (http://lynx.browser.org)] */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
487 month -= 3;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
488 if (month < 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
489 month += 12;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
490 year--;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
491 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
492
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
493 day += (year - 1968) * 1461 / 4;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
494 day += ((((month * 153) + 2) / 5) - 672);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
495 ret = (time_t)((day * 60 * 60 * 24) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
496 (hour * 60 * 60) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
497 (minutes * 60) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
498 seconds);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
499
1508
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
500 /* handle overflow */
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
501 if (year >= 1970 && ret < 0)
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
502 ret = DILLO_TIME_MAX;
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
503
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
504 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
505 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
506
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
507 /*
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
508 * Remove the least recently used cookie in the list.
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
509 */
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
510 static void Cookies_remove_LRU(Dlist *cookies)
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
511 {
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
512 int n = dList_length(cookies);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
513
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
514 if (n > 0) {
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
515 int i;
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
516 CookieData_t *lru = dList_nth_data(cookies, 0);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
517
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
518 for (i = 1; i < n; i++) {
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
519 CookieData_t *curr = dList_nth_data(cookies, i);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
520
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
521 if (curr->last_used < lru->last_used)
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
522 lru = curr;
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
523 }
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
524 dList_remove(cookies, lru);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
525 MSG("removed LRU cookie \'%s=%s\'\n", lru->name, lru->value);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
526 Cookies_free_cookie(lru);
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
527 }
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
528 }
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
529
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
530 static void Cookies_add_cookie(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
531 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
532 Dlist *domain_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
533 CookieData_t *c;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
534 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
535
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
536 node = dList_find_sorted(cookies, cookie->domain,Cookie_node_by_domain_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
537 domain_cookies = (node) ? node->dlist : NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
538
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
539 if (domain_cookies) {
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
540 /* Remove any cookies with the same name and path */
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
541 while ((c = dList_find_custom(domain_cookies, cookie, Cookies_cmp))) {
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
542 dList_remove(domain_cookies, c);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
543 Cookies_free_cookie(c);
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
544 }
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
545
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
546 /* Respect the limit of 20 cookies per domain */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
547 if (dList_length(domain_cookies) >= 20) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
548 MSG("There are too many cookies for this domain (%s)\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
549 cookie->domain);
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
550 Cookies_remove_LRU(domain_cookies);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
551 }
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
552 }
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
553
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
554 /* Don't add an expired cookie. Whether expiring now == expired, exactly,
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
555 * is arguable, but we definitely do not want to add a Max-Age=0 cookie.
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
556 */
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
557 if (cookie->expires_at <= time(NULL)) {
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
558 MSG("Goodbye, expired cookie %s=%s d:%s p:%s\n", cookie->name,
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
559 cookie->value, cookie->domain, cookie->path);
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
560 Cookies_free_cookie(cookie);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
561 } else {
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
562 cookie->last_used = cookies_use_counter++;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
563
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
564 /* add cookie to domain list */
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
565 if (!domain_cookies) {
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
566 domain_cookies = dList_new(5);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
567 dList_append(domain_cookies, cookie);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
568 node = dNew(CookieNode, 1);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
569 node->domain = dStrdup(cookie->domain);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
570 node->dlist = domain_cookies;
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
571 dList_insert_sorted(cookies, node, Cookie_node_cmp);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
572 } else {
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
573 dList_append(domain_cookies, cookie);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
574 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
575 }
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
576 if (domain_cookies && (dList_length(domain_cookies) == 0)) {
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
577 dList_remove(cookies, node);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
578 dFree(node->domain);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
579 dList_free(domain_cookies);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
580 dFree(node);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
581 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
582 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
583
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
584 /*
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
585 * Return the attribute that is present at *cookie_str.
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
586 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
587 static char *Cookies_parse_attr(char **cookie_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
588 {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
589 char *str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
590 uint_t len;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
591
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
592 while (dIsspace(**cookie_str))
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
593 (*cookie_str)++;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
594
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
595 str = *cookie_str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
596 /* find '=' at end of attr, ';' after attr/val pair, '\0' end of string */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
597 len = strcspn(str, "=;");
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
598 *cookie_str += len;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
599
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
600 while (len && (str[len - 1] == ' ' || str[len - 1] == '\t'))
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
601 len--;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
602 return dStrndup(str, len);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
603 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
604
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
605 /*
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
606 * Get the value in *cookie_str.
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
607 */
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
608 static char *Cookies_parse_value(char **cookie_str)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
609 {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
610 uint_t len;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
611 char *str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
612
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
613 if (**cookie_str == '=') {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
614 (*cookie_str)++;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
615 while (dIsspace(**cookie_str))
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
616 (*cookie_str)++;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
617
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
618 str = *cookie_str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
619 /* finds ';' after attr/val pair or '\0' at end of string */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
620 len = strcspn(str, ";");
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
621 *cookie_str += len;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
622
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
623 while (len && (str[len - 1] == ' ' || str[len - 1] == '\t'))
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
624 len--;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
625 } else {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
626 str = *cookie_str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
627 len = 0;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
628 }
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
629 return dStrndup(str, len);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
630 }
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
631
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
632 /*
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
633 * Advance past any value
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
634 */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
635 static void Cookies_eat_value(char **cookie_str)
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
636 {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
637 if (**cookie_str == '=')
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
638 *cookie_str += strcspn(*cookie_str, ";");
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
639 }
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
640
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
641 /*
1522
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
642 * Handle Expires attribute.
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
643 * Note that this CAN MODIFY the value string.
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
644 */
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
645 static time_t Cookies_expires_attr(char *value, const char *server_date)
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
646 {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
647 time_t exptime;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
648
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
649 if (*value == '"' && value[strlen(value) - 1] == '"') {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
650 /* In this one case, pay attention to quotes */
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
651 value[strlen(value) - 1] = '\0';
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
652 value++;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
653 }
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
654 exptime = Cookies_create_timestamp(value);
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
655 if (exptime && server_date) {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
656 time_t server_time = Cookies_create_timestamp(server_date);
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
657
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
658 if (server_time) {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
659 time_t now = time(NULL);
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
660 time_t client_time = exptime + now - server_time;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
661
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
662 if (server_time == exptime) {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
663 exptime = now;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
664 } else if ((exptime > now) == (client_time > now)) {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
665 exptime = client_time;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
666 } else {
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
667 /* Don't want to wrap around at the extremes of representable
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
668 * values thanks to clock skew.
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
669 */
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
670 MSG("At %ld, %ld was trying to turn into %ld\n",
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
671 (long)now, (long)exptime,
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
672 (long)client_time);
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
673 }
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
674 }
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
675 }
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
676 return exptime;
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
677 }
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
678
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
679 /*
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
680 * Parse cookie. A cookie might look something like:
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
681 * "Name=Val; Domain=example.com; Max-Age=3600; HttpOnly"
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
682 */
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
683 static CookieData_t *Cookies_parse(char *cookie_str, const char *server_date)
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
684 {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
685 CookieData_t *cookie = NULL;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
686 char *str = cookie_str;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
687 bool_t first_attr = TRUE;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
688 bool_t max_age = FALSE;
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
689 bool_t expires = FALSE;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
690
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
691 /* Iterate until there is nothing left of the string */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
692 while (*str) {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
693 char *attr;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
694 char *value;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
695
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
696 /* Get attribute */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
697 attr = Cookies_parse_attr(&str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
698
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
699 /* Get the value for the attribute and store it */
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
700 if (first_attr) {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
701 if (!*str && !*attr) {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
702 dFree(attr);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
703 return NULL;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
704 }
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
705 cookie = dNew0(CookieData_t, 1);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
706 /* let's arbitrarily choose a year for now */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
707 cookie->expires_at = time(NULL) + 60 * 60 * 24 * 365;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
708
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
709 if (*str != '=') {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
710 /* NOTE it seems possible that the Working Group will decide
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
711 * against allowing nameless cookies.
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
712 */
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
713 cookie->name = dStrdup("");
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
714 cookie->value = attr;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
715 } else {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
716 cookie->name = dStrdup(attr);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
717 cookie->value = Cookies_parse_value(&str);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
718 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
719 } else if (dStrcasecmp(attr, "Path") == 0) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
720 value = Cookies_parse_value(&str);
1491
a10148c0bcab cookies don't leak extra domain/path attrs
corvid <corvid@lavabit.com>
parents: 1490
diff changeset
721 dFree(cookie->path);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
722 cookie->path = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
723 } else if (dStrcasecmp(attr, "Domain") == 0) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
724 value = Cookies_parse_value(&str);
1491
a10148c0bcab cookies don't leak extra domain/path attrs
corvid <corvid@lavabit.com>
parents: 1490
diff changeset
725 dFree(cookie->domain);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
726 cookie->domain = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
727 } else if (dStrcasecmp(attr, "Max-Age") == 0) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
728 value = Cookies_parse_value(&str);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
729 if (isdigit(*value) || *value == '-') {
1508
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
730 time_t now = time(NULL);
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
731 long age = strtol(value, NULL, 10);
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
732
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
733 cookie->expires_at = now + age;
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
734 if (age > 0 && cookie->expires_at < 0) {
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
735 /* handle overflow */
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
736 cookie->expires_at = DILLO_TIME_MAX;
3a82485edd3f cookie handle time overflow
corvid <corvid@lavabit.com>
parents: 1506
diff changeset
737 }
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
738 expires = max_age = TRUE;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
739 }
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
740 dFree(value);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
741 } else if (dStrcasecmp(attr, "Expires") == 0) {
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
742 if (!max_age) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
743 value = Cookies_parse_value(&str);
1522
85062b64ae9d cookies allow Expires attr's value to be quoted.
corvid <corvid@lavabit.com>
parents: 1519
diff changeset
744 cookie->expires_at = Cookies_expires_attr(value, server_date);
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
745 expires = TRUE;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
746 dFree(value);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
747 MSG("Expires in %ld seconds, at %s",
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
748 (long)cookie->expires_at - time(NULL),
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
749 ctime(&cookie->expires_at));
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
750
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
751 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
752 } else if (dStrcasecmp(attr, "Secure") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
753 cookie->secure = TRUE;
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
754 Cookies_eat_value(&str);
418
b7265ec32e33 - Allow login to wikipedia by ignoring the HttpOnly attribute (cookies)
jcid
parents: 379
diff changeset
755 } else if (dStrcasecmp(attr, "HttpOnly") == 0) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
756 Cookies_eat_value(&str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
757 } else {
379
52f65d7a0e7c - minor cookie MSG improvement.
jcid
parents: 368
diff changeset
758 MSG("Cookie contains unknown attribute: '%s'\n", attr);
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
759 Cookies_eat_value(&str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
760 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
761
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
762 if (first_attr)
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
763 first_attr = FALSE;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
764 else
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
765 dFree(attr);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
766
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
767 if (*str == ';')
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
768 str++;
159
70da40b41e3a - Fixed a bug in Cookies_parse_one. Set it to a single return potint too!
jcid
parents: 154
diff changeset
769 }
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
770 cookie->session_only = expires == FALSE;
159
70da40b41e3a - Fixed a bug in Cookies_parse_one. Set it to a single return potint too!
jcid
parents: 154
diff changeset
771 return cookie;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
772 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
773
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
774 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
775 * Compare cookies by name and path (return 0 if equal)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
776 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
777 static int Cookies_cmp(const void *a, const void *b)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
778 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
779 const CookieData_t *ca = a, *cb = b;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
780 int ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
781
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
782 if (!(ret = strcmp(ca->name, cb->name)))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
783 ret = strcmp(ca->path, cb->path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
784 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
785 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
786
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
787 /*
1517
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
788 * Is the domain an IP address?
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
789 */
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
790 static bool_t Cookies_domain_is_ip(const char *domain)
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
791 {
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
792 uint_t len;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
793
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
794 if (!domain)
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
795 return FALSE;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
796
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
797 len = strlen(domain);
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
798
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
799 if (len == strspn(domain, "0123456789.")) {
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
800 MSG("an IPv4 address\n");
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
801 return TRUE;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
802 }
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
803 if (*domain == '[' &&
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
804 (len == strspn(domain, "0123456789abcdefABCDEF:.[]"))) {
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
805 /* The precise format is shown in section 3.2.2 of rfc 3986 */
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
806 MSG("an IPv6 address\n");
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
807 return TRUE;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
808 }
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
809 return FALSE;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
810 }
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
811
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
812 /*
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
813 * Check whether url_path path-matches cookie_path
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
814 *
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
815 * Note different user agents apparently vary in path-matching behaviour,
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
816 * but this is the recommended method at the moment.
1486
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
817 */
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
818 static bool_t Cookies_path_matches(const char *url_path,
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
819 const char *cookie_path)
1486
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
820 {
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
821 bool_t ret = TRUE;
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
822
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
823 if (!url_path || !cookie_path) {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
824 ret = FALSE;
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
825 } else {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
826 uint_t c_len = strlen(cookie_path);
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
827 uint_t u_len = strlen(url_path);
1486
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
828
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
829 ret = (!strncmp(cookie_path, url_path, c_len) &&
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
830 ((c_len == u_len) ||
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
831 (c_len > 0 && cookie_path[c_len - 1] == '/') ||
1505
4f98690a951a unnecessary test
corvid <corvid@lavabit.com>
parents: 1504
diff changeset
832 (url_path[c_len] == '/')));
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
833 }
1486
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
834 return ret;
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
835 }
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
836
4fbeadf3191b cookie paths
corvid <corvid@lavabit.com>
parents: 1485
diff changeset
837 /*
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
838 * If cookie path is not properly set, remedy that.
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
839 */
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
840 static void Cookies_validate_path(CookieData_t *cookie, const char *url_path)
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
841 {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
842 if (!cookie->path || cookie->path[0] != '/') {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
843 dFree(cookie->path);
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
844
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
845 if (url_path) {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
846 uint_t len = strlen(url_path);
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
847
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
848 while (len && url_path[len] != '/')
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
849 len--;
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
850 cookie->path = dStrndup(url_path, len ? len : 1);
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
851 } else {
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
852 cookie->path = dStrdup("/");
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
853 }
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
854 }
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
855 }
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
856
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
857 /*
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
858 * Check whether host name A domain-matches host name B.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
859 */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
860 static bool_t Cookies_domain_matches(char *A, char *B)
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
861 {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
862 int diff;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
863
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
864 if (!A || !*A || !B || !*B)
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
865 return FALSE;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
866
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
867 if (*B == '.')
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
868 B++;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
869
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
870 /* Should we concern ourselves with trailing dots in matching (here or
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
871 * elsewhere)? The HTTP State people have found that most user agents
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
872 * don't, so: No.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
873 */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
874
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
875 if (!dStrcasecmp(A, B))
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
876 return TRUE;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
877
1517
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
878 if (Cookies_domain_is_ip(B))
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
879 return FALSE;
773b44547931 cookies: be more robust in rejecting IP addr partial matches
corvid <corvid@lavabit.com>
parents: 1516
diff changeset
880
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
881 diff = strlen(A) - strlen(B);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
882
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
883 if (diff > 0) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
884 /* B is the tail of A, and the match is preceded by a '.' */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
885 return (dStrcasecmp(A + diff, B) == 0 && A[diff - 1] == '.');
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
886 } else {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
887 return FALSE;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
888 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
889 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
890
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
891 /*
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
892 * Based on the host, how many internal dots do we need in a cookie domain
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
893 * to make it valid? e.g., "org" is not on the list, so dillo.org is a safe
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
894 * cookie domain, but "uk" is on the list, so ac.uk is not safe.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
895 *
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
896 * This is imperfect, but it's something. Specifically, checking for these
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
897 * TLDs is the solution that Konqueror used once upon a time, according to
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
898 * reports.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
899 */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
900 static uint_t Cookies_internal_dots_required(const char *host)
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
901 {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
902 uint_t ret = 1;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
903
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
904 if (host) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
905 int start, after, tld_len;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
906
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
907 /* We may be able to trust the format of the host string more than
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
908 * I am here. Trailing dots and no dots are real possibilities, though.
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
909 */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
910 after = strlen(host);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
911 if (after > 0 && host[after - 1] == '.')
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
912 after--;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
913 start = after;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
914 while (start > 0 && host[start - 1] != '.')
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
915 start--;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
916 tld_len = after - start;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
917
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
918 if (tld_len > 0) {
1510
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
919 /* These TLDs were chosen by examining the current publicsuffix list
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
920 * in January 2010 and picking out those where it was simplest for
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
921 * them to describe the situation by beginning with a "*.[tld]" rule.
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
922 */
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
923 const char *const tlds[] = {"ar","au","bd","bn","bt","ck","cy","do",
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
924 "eg","er","et","fj","fk","gt","gu","id",
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
925 "il","jm","ke","kh","kw","ml","mm","mt",
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
926 "mz","ni","np","nz","om","pg","py","qa",
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
927 "sv","tr","uk","uy","ve","ye","yu","za",
f08bcca10105 cookies update TLDs
corvid <corvid@lavabit.com>
parents: 1508
diff changeset
928 "zm","zw"};
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
929 uint_t i, tld_num = sizeof(tlds) / sizeof(tlds[0]);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
930
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
931 for (i = 0; i < tld_num; i++) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
932 if (strlen(tlds[i]) == (uint_t) tld_len &&
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
933 !dStrncasecmp(tlds[i], host + start, tld_len)) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
934 MSG("TLD code matched %s\n", tlds[i]);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
935 ret++;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
936 break;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
937 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
938 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
939 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
940 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
941 return ret;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
942 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
943
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
944 /*
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
945 * Validate cookies domain against some security checks.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
946 */
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
947 static bool_t Cookies_validate_domain(CookieData_t *cookie, char *host)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
948 {
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
949 uint_t i, internal_dots;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
950
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
951 if (!cookie->domain) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
952 cookie->domain = dStrdup(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
953 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
954 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
955
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
956 if (cookie->domain[0] != '.' && !Cookies_domain_is_ip(cookie->domain)) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
957 char *d = dStrconcat(".", cookie->domain, NULL);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
958 dFree(cookie->domain);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
959 cookie->domain = d;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
960 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
961
1488
afe771c1d19f cookie domains
corvid <corvid@lavabit.com>
parents: 1487
diff changeset
962 if (!Cookies_domain_matches(host, cookie->domain))
afe771c1d19f cookie domains
corvid <corvid@lavabit.com>
parents: 1487
diff changeset
963 return FALSE;
afe771c1d19f cookie domains
corvid <corvid@lavabit.com>
parents: 1487
diff changeset
964
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
965 internal_dots = 0;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
966 for (i = 1; i < strlen(cookie->domain) - 1; i++) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
967 if (cookie->domain[i] == '.')
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
968 internal_dots++;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
969 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
970
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
971 /* All of this dots business is a weak hack.
1488
afe771c1d19f cookie domains
corvid <corvid@lavabit.com>
parents: 1487
diff changeset
972 * TODO: accept the publicsuffix.org list as an optional external file.
afe771c1d19f cookie domains
corvid <corvid@lavabit.com>
parents: 1487
diff changeset
973 */
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
974 if (internal_dots < Cookies_internal_dots_required(host)) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
975 MSG("not enough dots in %s\n", cookie->domain);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
976 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
977 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
978
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
979 MSG("host %s and domain %s is all right\n", host, cookie->domain);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
980 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
981 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
982
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
983 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
984 * Set the value corresponding to the cookie string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
985 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
986 static void Cookies_set(char *cookie_string, char *url_host,
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
987 char *url_path, char *server_date)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
988 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
989 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
990 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
991
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
992 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
993 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
994
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
995 action = Cookies_control_check_domain(url_host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
996 if (action == COOKIE_DENY) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
997 MSG("denied SET for %s\n", url_host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
998 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
999 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1000
1506
408f86fed820 make cookies very chatty for now
corvid <corvid@lavabit.com>
parents: 1505
diff changeset
1001 MSG("%s SETTING: %s\n", url_host, cookie_string);
1482
a749c1b10fbe clean up cookie expiration/replacement and sessions
corvid <corvid@lavabit.com>
parents: 1481
diff changeset
1002
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1003 if ((cookie = Cookies_parse(cookie_string, server_date))) {
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1004 if (Cookies_validate_domain(cookie, url_host)) {
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1005 Cookies_validate_path(cookie, url_path);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1006 if (action == COOKIE_ACCEPT_SESSION)
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1007 cookie->session_only = TRUE;
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1008 Cookies_add_cookie(cookie);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1009 } else {
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
1010 MSG("Rejecting cookie for domain %s from host %s path %s\n",
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1011 cookie->domain, url_host, url_path);
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1012 Cookies_free_cookie(cookie);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1013 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1014 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1015 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1016
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1017 /*
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
1018 * Compare the cookie with the supplied data to see whether it matches
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1019 */
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
1020 static bool_t Cookies_match(CookieData_t *cookie, const char *url_path,
1496
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1021 bool_t is_ssl)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1022 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1023 /* Insecure cookies matches both secure and insecure urls, secure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1024 cookies matches only secure urls */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1025 if (cookie->secure && !is_ssl)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1026 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1027
1497
4ecebf934b44 cookies follow draft spec for paths
corvid <corvid@lavabit.com>
parents: 1496
diff changeset
1028 if (!Cookies_path_matches(url_path, cookie->path))
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1029 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1030
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1031 /* It's a match */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1032 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1033 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1034
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1035 static void Cookies_add_matching_cookies(const char *domain,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1036 const char *url_path,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1037 Dlist *matching_cookies,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1038 bool_t is_ssl)
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1039 {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1040 CookieNode *node = dList_find_sorted(cookies, domain,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1041 Cookie_node_by_domain_cmp);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1042 if (node) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1043 int i;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1044 CookieData_t *cookie;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1045 Dlist *domain_cookies = node->dlist;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1046
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1047 for (i = 0; (cookie = dList_nth_data(domain_cookies, i)); ++i) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1048 /* Remove expired cookie. */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1049 if (cookie->expires_at < time(NULL)) {
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
1050 MSG("Goodbye, expired cookie %s=%s d:%s p:%s\n", cookie->name,
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1051 cookie->value, cookie->domain, cookie->path);
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1052 dList_remove(domain_cookies, cookie);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1053 Cookies_free_cookie(cookie);
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1054 --i; continue;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1055 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1056 /* Check if the cookie matches the requesting URL */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1057 if (Cookies_match(cookie, url_path, is_ssl)) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1058 int j;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1059 CookieData_t *curr;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1060 uint_t path_length = strlen(cookie->path);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1061
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1062 cookie->last_used = cookies_use_counter;
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1063
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1064 /* Longest cookies go first */
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1065 for (j = 0;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1066 (curr = dList_nth_data(matching_cookies, j)) &&
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1067 strlen(curr->path) >= path_length;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1068 j++) ;
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1069 dList_insert_pos(matching_cookies, cookie, j);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1070 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1071 }
1519
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1072
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1073 if (dList_length(domain_cookies) == 0) {
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1074 dList_remove(cookies, node);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1075 dFree(node->domain);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1076 dList_free(domain_cookies);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1077 dFree(node);
6fcb13a8b680 Be careful not to delete domain_cookies while still using it.
corvid <corvid@lavabit.com>
parents: 1518
diff changeset
1078 }
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1079 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1080 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1081
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1082 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1083 * Return a string that contains all relevant cookies as headers.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1084 */
51
6ff7b6758e0c Added the "static" qualifier where missing.
jcid
parents: 35
diff changeset
1085 static char *Cookies_get(char *url_host, char *url_path,
1496
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1086 char *url_scheme)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1087 {
1496
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1088 char *domain_str, *str;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1089 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1090 Dlist *matching_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1091 bool_t is_ssl;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1092 Dstr *cookie_dstring;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1093 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1094
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1095 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1096 return dStrdup("");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1097
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1098 matching_cookies = dList_new(8);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1099
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1100 /* Check if the protocol is secure or not */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1101 is_ssl = (!dStrcasecmp(url_scheme, "https"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1102
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1103 for (domain_str = (char *) url_host;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1104 domain_str != NULL && *domain_str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1105 domain_str = strchr(domain_str+1, '.')) {
1498
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1106 Cookies_add_matching_cookies(domain_str, url_path, matching_cookies,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1107 is_ssl);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1108 }
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1109 if (!Cookies_domain_is_ip(url_host)) {
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1110 domain_str = dStrconcat(".", url_host, NULL);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1111 Cookies_add_matching_cookies(domain_str, url_path, matching_cookies,
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1112 is_ssl);
c04b0de69b00 cookies follow draft spec for domains
corvid <corvid@lavabit.com>
parents: 1497
diff changeset
1113 dFree(domain_str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1114 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1115
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1116 /* Found the cookies, now make the string */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1117 cookie_dstring = dStr_new("");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1118 if (dList_length(matching_cookies) > 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1119
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1120 dStr_sprintfa(cookie_dstring, "Cookie: ");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1121
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1122 for (i = 0; (cookie = dList_nth_data(matching_cookies, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1123 dStr_sprintfa(cookie_dstring,
1499
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1124 "%s%s%s",
1803fe44871e cookies follow draft spec's simple parsing
corvid <corvid@lavabit.com>
parents: 1498
diff changeset
1125 cookie->name, *cookie->name ? "=" : "", cookie->value);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1126 dStr_append(cookie_dstring,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1127 dList_length(matching_cookies) > i + 1 ? "; " : "\r\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1128 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1129 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1130
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1131 dList_free(matching_cookies);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1132 str = cookie_dstring->str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1133 dStr_free(cookie_dstring, FALSE);
1504
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1134
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1135 if (*str)
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1136 cookies_use_counter++;
d10adebe95fb when too many cookies for domain, rm least recently used
corvid <corvid@lavabit.com>
parents: 1503
diff changeset
1137
1506
408f86fed820 make cookies very chatty for now
corvid <corvid@lavabit.com>
parents: 1505
diff changeset
1138 MSG("%s GETTING: %s\n", url_host, str);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1139 return str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1140 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1141
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1142 /* -------------------------------------------------------------
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1143 * Access control routines
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1144 * ------------------------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1145
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1146
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1147 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1148 * Get the cookie control rules (from cookiesrc).
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1149 * Return value:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1150 * 0 = Parsed OK, with cookies enabled
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1151 * 1 = Parsed OK, with cookies disabled
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1152 * 2 = Can't open the control file
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1153 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1154 static int Cookie_control_init(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1155 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1156 CookieControl cc;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1157 FILE *stream;
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1158 char *filename, *rc;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1159 char line[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1160 char domain[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1161 char rule[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1162 int i, j;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1163 bool_t enabled = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1164
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1165 /* Get a file pointer */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1166 filename = dStrconcat(dGethomedir(), "/.dillo/cookiesrc", NULL);
219
201d89d1d002 - Allowed readonly permissions for cookiesrc.
jcid
parents: 174
diff changeset
1167 stream = Cookies_fopen(filename, "r", "DEFAULT DENY\n");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1168 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1169
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1170 if (!stream)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1171 return 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1172
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1173 /* Get all lines in the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1174 while (!feof(stream)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1175 line[0] = '\0';
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1176 rc = fgets(line, LINE_MAXLEN, stream);
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1177 if (!rc && ferror(stream)) {
1503
f02eb59edc7d cookies: a little cleaning
corvid <corvid@lavabit.com>
parents: 1501
diff changeset
1178 MSG("Error while reading rule from cookiesrc: %s\n",
1200
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1179 dStrerror(errno));
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1180 break; /* bail out */
6bdf6ea2637a Removed compiler warnings for unused return values
Michal Nowak newman.x@gmail.com
parents: 1127
diff changeset
1181 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1182
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1183 /* Remove leading and trailing whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1184 dStrstrip(line);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1185
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1186 if (line[0] != '\0' && line[0] != '#') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1187 i = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1188 j = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1189
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1190 /* Get the domain */
1221
f34b803b8639 Handle signed chars. Aadded dIsspace() and dIsalnum() to dlib
Jorge Arellano Cid <jcid@dillo.org>
parents: 1201
diff changeset
1191 while (line[i] != '\0' && !dIsspace(line[i]))
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1192 domain[j++] = line[i++];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1193 domain[j] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1194
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1195 /* Skip past whitespaces */
1221
f34b803b8639 Handle signed chars. Aadded dIsspace() and dIsalnum() to dlib
Jorge Arellano Cid <jcid@dillo.org>
parents: 1201
diff changeset
1196 while (dIsspace(line[i]))
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1197 i++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1198
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1199 /* Get the rule */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1200 j = 0;
1221
f34b803b8639 Handle signed chars. Aadded dIsspace() and dIsalnum() to dlib
Jorge Arellano Cid <jcid@dillo.org>
parents: 1201
diff changeset
1201 while (line[i] != '\0' && !dIsspace(line[i]))
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1202 rule[j++] = line[i++];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1203 rule[j] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1204
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1205 if (dStrcasecmp(rule, "ACCEPT") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1206 cc.action = COOKIE_ACCEPT;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1207 else if (dStrcasecmp(rule, "ACCEPT_SESSION") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1208 cc.action = COOKIE_ACCEPT_SESSION;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1209 else if (dStrcasecmp(rule, "DENY") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1210 cc.action = COOKIE_DENY;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1211 else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1212 MSG("Cookies: rule '%s' for domain '%s' is not recognised.\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1213 rule, domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1214 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1215 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1216
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1217 cc.domain = dStrdup(domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1218 if (dStrcasecmp(cc.domain, "DEFAULT") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1219 /* Set the default action */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1220 default_action = cc.action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1221 dFree(cc.domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1222 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1223 a_List_add(ccontrol, num_ccontrol, num_ccontrol_max);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1224 ccontrol[num_ccontrol++] = cc;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1225 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1226
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1227 if (cc.action != COOKIE_DENY)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1228 enabled = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1229 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1230 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1231
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1232 fclose(stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1233
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1234 return (enabled ? 0 : 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1235 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1236
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1237 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1238 * Check the rules for an appropriate action for this domain
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1239 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1240 static CookieControlAction Cookies_control_check_domain(const char *domain)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1241 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1242 int i, diff;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1243
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1244 for (i = 0; i < num_ccontrol; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1245 if (ccontrol[i].domain[0] == '.') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1246 diff = strlen(domain) - strlen(ccontrol[i].domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1247 if (diff >= 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1248 if (dStrcasecmp(domain + diff, ccontrol[i].domain) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1249 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1250 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1251 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1252 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1253 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1254 if (dStrcasecmp(domain, ccontrol[i].domain) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1255 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1256 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1257
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1258 /* If we got here we have a match */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1259 return( ccontrol[i].action );
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1260 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1261
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1262 return default_action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1263 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1264
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1265 /* -- Dpi parser ----------------------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1266
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1267 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1268 * Parse a data stream (dpi protocol)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1269 * Note: Buf is a zero terminated string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1270 * Return code: { 0:OK, 1:Abort, 2:Close }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1271 */
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1272 static int srv_parse_tok(Dsh *sh, ClientInfo *client, char *Buf)
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1273 {
1496
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1274 char *cmd, *cookie, *host, *path, *scheme;
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1275 int ret = 1;
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1276 size_t BufSize = strlen(Buf);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1277
1236
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1278 cmd = a_Dpip_get_attr_l(Buf, BufSize, "cmd");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1279
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1280 if (!cmd) {
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1281 /* abort */
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1282 } else if (client->status == 0) {
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1283 /* authenticate */
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1284 if (a_Dpip_check_auth(Buf) == 1) {
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1285 client->status = 1;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1286 ret = 0;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1287 }
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1288 } else if (strcmp(cmd, "DpiBye") == 0) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1289 dFree(cmd);
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1290 MSG("(pid %d): Got DpiBye.\n", (int)getpid());
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1291 exit(0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1292
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1293 } else if (cmd && strcmp(cmd, "set_cookie") == 0) {
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1294 char *date;
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1295
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1296 dFree(cmd);
1236
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1297 cookie = a_Dpip_get_attr_l(Buf, BufSize, "cookie");
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1298 host = a_Dpip_get_attr_l(Buf, BufSize, "host");
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1299 path = a_Dpip_get_attr_l(Buf, BufSize, "path");
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1300 date = a_Dpip_get_attr_l(Buf, BufSize, "date");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1301
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1302 Cookies_set(cookie, host, path, date);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1303
1501
6fd1c55d8022 cookies use server date to interpret Expires attr
corvid <corvid@lavabit.com>
parents: 1500
diff changeset
1304 dFree(date);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1305 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1306 dFree(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1307 dFree(cookie);
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1308 ret = 2;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1309
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1310 } else if (cmd && strcmp(cmd, "get_cookie") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1311 dFree(cmd);
1236
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1312 scheme = a_Dpip_get_attr_l(Buf, BufSize, "scheme");
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1313 host = a_Dpip_get_attr_l(Buf, BufSize, "host");
b912173aecd1 Added a_Dpip_get_attr_l() to DPIP's API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1221
diff changeset
1314 path = a_Dpip_get_attr_l(Buf, BufSize, "path");
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1315
1496
5bec8ce33a42 cookies: rm version, comment, comment url, port, Cookie2
corvid <corvid@lavabit.com>
parents: 1495
diff changeset
1316 cookie = Cookies_get(host, path, scheme);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1317 dFree(scheme);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1318 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1319 dFree(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1320
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1321 cmd = a_Dpip_build_cmd("cmd=%s cookie=%s", "get_cookie_answer", cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1322
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1323 if (a_Dpip_dsh_write_str(sh, 1, cmd)) {
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1324 ret = 1;
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1325 } else {
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1326 _MSG("a_Dpip_dsh_write_str: SUCCESS cmd={%s}\n", cmd);
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1327 ret = 2;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1328 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1329 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1330 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1331 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1332
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1333 return ret;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1334 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1335
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1336 /* -- Termination handlers ----------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1337 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1338 * (was to delete the local namespace socket),
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1339 * but this is handled by 'dpid' now.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1340 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1341 static void cleanup(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1342 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1343 Cookies_save_and_free();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1344 MSG("cleanup\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1345 /* no more cleanup required */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1346 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1347
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1348 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1349 * Perform any necessary cleanups upon abnormal termination
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1350 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1351 static void termination_handler(int signum)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1352 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1353 exit(signum);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1354 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1355
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1356
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1357 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1358 * -- MAIN -------------------------------------------------------------------
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1359 */
1385
eb98997886ec Introduced the new tokenizing dsh API to DPIP
Jorge Arellano Cid <jcid@dillo.org>
parents: 1236
diff changeset
1360 int main(void) {
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1361 struct sockaddr_in sin;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1362 socklen_t address_size;
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1363 ClientInfo *client;
1439
79fcf67eeea0 Fixed bookmarks "cancel" link (Add/Mod URL, Add Sec). Also s/tmp_fd/sock_fd.
Jorge Arellano Cid <jcid@dillo.org>
parents: 1388
diff changeset
1364 int sock_fd, code;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1365 char *buf;
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1366 Dsh *sh;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1367
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1368 /* Arrange the cleanup function for terminations via exit() */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1369 atexit(cleanup);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1370
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1371 /* Arrange the cleanup function for abnormal terminations */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1372 if (signal (SIGINT, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1373 signal (SIGINT, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1374 if (signal (SIGHUP, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1375 signal (SIGHUP, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1376 if (signal (SIGTERM, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1377 signal (SIGTERM, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1378
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1379 Cookies_init();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1380 MSG("(v.1) accepting connections...\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1381
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1382 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1383 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1384
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1385 /* some OSes may need this... */
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1386 address_size = sizeof(struct sockaddr_in);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1387
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1388 while (1) {
1439
79fcf67eeea0 Fixed bookmarks "cancel" link (Add/Mod URL, Add Sec). Also s/tmp_fd/sock_fd.
Jorge Arellano Cid <jcid@dillo.org>
parents: 1388
diff changeset
1389 sock_fd = accept(STDIN_FILENO, (struct sockaddr *)&sin, &address_size);
79fcf67eeea0 Fixed bookmarks "cancel" link (Add/Mod URL, Add Sec). Also s/tmp_fd/sock_fd.
Jorge Arellano Cid <jcid@dillo.org>
parents: 1388
diff changeset
1390 if (sock_fd == -1) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1391 perror("[accept]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1392 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1393 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1394
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1395 /* create the Dsh structure */
1439
79fcf67eeea0 Fixed bookmarks "cancel" link (Add/Mod URL, Add Sec). Also s/tmp_fd/sock_fd.
Jorge Arellano Cid <jcid@dillo.org>
parents: 1388
diff changeset
1396 sh = a_Dpip_dsh_new(sock_fd, sock_fd, 8*1024);
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1397 client = dNew(ClientInfo,1);
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1398 client->sh = sh;
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1399 client->status = 0;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1400
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1401 while (1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1402 code = 1;
1388
eb35203124e4 Implemented the file dpi based on select() (removed its pthreads dependency)
Jorge Arellano Cid <jcid@dillo.org>
parents: 1387
diff changeset
1403 if ((buf = a_Dpip_dsh_read_token(sh, 1)) != NULL) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1404 /* Let's see what we fished... */
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1405 _MSG(" buf = {%s}\n", buf);
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1406 code = srv_parse_tok(sh, client, buf);
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1407 dFree(buf);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1408 }
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1409
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1410 _MSG(" code = %d %s\n", code, code == 1 ? "EXIT" : "BREAK");
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1411 if (code == 1) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1412 exit(1);
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1413 } else if (code == 2) {
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1414 break;
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1415 }
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1416 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1417
1387
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1418 _MSG("Closing Dsh\n");
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1419 a_Dpip_dsh_close(sh);
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1420 a_Dpip_dsh_free(sh);
16cf380cd04c Convert dpid, file dpi and cookies dpi to dsh API
Jorge Arellano Cid <jcid@dillo.org>
parents: 1385
diff changeset
1421 dFree(client);
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1422
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1423 }/*while*/
174
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1424
67e98a1211f0 - Fixed a cookies-related dillo freeze bug happening at:
jcid
parents: 159
diff changeset
1425 return 0;
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1426 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1427
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1428 #endif /* !DISABLE_COOKIES */