annotate dpi/cookies.c @ 0:6ee11bf9e3ea

Initial revision
author jcid
date Sun, 07 Oct 2007 00:36:34 +0200
parents
children d9e7b35430de
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>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
7 * Copyright 2002-2006 Jorge Arellano Cid <jcid@dillo.org>
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
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
16 /* Handling of cookies takes place here.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
17 * This implementation aims to follow RFC 2965:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
18 * http://www.cis.ohio-state.edu/cs/Services/rfc/rfc-text/rfc2965.txt
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
19 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
20
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
21 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
22 * TODO: Cleanup this code. Shorten some functions, order things,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
23 * add comments, remove leaks, etc.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
24 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
25
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
26 /* Todo: this server is not assembling the received packets.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
27 * This means it currently expects dillo to send full dpi tags
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
28 * within the socket; if that fails, everything stops.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
29 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
30
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
31 #ifdef DISABLE_COOKIES
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
32
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
33 int main(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
34 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
35 return 0; /* never called */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
36 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
37
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
38 #else
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
39
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
40
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
41 #include <sys/types.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
42 #include <sys/socket.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
43 #include <sys/stat.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
44 #include <sys/un.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
45 #include <fcntl.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
46 #include <unistd.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
47 #include <errno.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
48 #include <stddef.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
49 #include <string.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
50 #include <stdlib.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
51 #include <stdio.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
52 #include <time.h> /* for time() and time_t */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
53 #include <ctype.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
54 #include <netdb.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
55 #include <signal.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
56 #include "dpiutil.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
57 #include "../dpip/dpip.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
58
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
59
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
60 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
61 * Debugging macros
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
62 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
63 #define _MSG(...)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
64 #define MSG(...) printf("[cookies dpi]: " __VA_ARGS__)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
65
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
66
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
67 /* This one is tricky, some sources state it should include the byte
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
68 * for the terminating NULL, and others say it shouldn't. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
69 # define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
70 + strlen ((ptr)->sun_path))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
71
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
72
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
73 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
74 * a_List_add()
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
75 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
76 * Make sure there's space for 'num_items' items within the list
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
77 * (First, allocate an 'alloc_step' sized chunk, after that, double the
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
78 * list size --to make it faster)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
79 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
80 #define a_List_add(list,num_items,alloc_step) \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
81 if (!list) { \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
82 list = dMalloc(alloc_step * sizeof((*list))); \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
83 } \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
84 if (num_items >= alloc_step){ \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
85 while ( num_items >= alloc_step ) \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
86 alloc_step <<= 1; \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
87 list = dRealloc(list, alloc_step * sizeof((*list))); \
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
88 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
89
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
90 /* The maximum length of a line in the cookie file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
91 #define LINE_MAXLEN 4096
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
92
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
93 typedef enum {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
94 COOKIE_ACCEPT,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
95 COOKIE_ACCEPT_SESSION,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
96 COOKIE_DENY
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
97 } CookieControlAction;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
98
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
99 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
100 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
101 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
102 } CookieControl;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
103
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
104 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
105 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
106 Dlist *dlist;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
107 } CookieNode;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
108
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
109 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
110 char *name;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
111 char *value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
112 char *domain;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
113 char *path;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
114 time_t expires_at;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
115 uint_t version;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
116 char *comment;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
117 char *comment_url;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
118 bool_t secure;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
119 bool_t session_only;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
120 Dlist *ports;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
121 } CookieData_t;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
122
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
123 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
124 * Local data
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
125 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
126
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
127 /* List of CookieNode. Each node holds a domain and its list of cookies */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
128 static Dlist *cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
129
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
130 /* Variables for access control */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
131 static CookieControl *ccontrol = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
132 static int num_ccontrol = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
133 static int num_ccontrol_max = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
134 static CookieControlAction default_action = COOKIE_DENY;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
135
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
136 static bool_t disabled;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
137 static FILE *file_stream;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
138 static char *cookies_txt_header_str =
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
139 "# HTTP Cookie File\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
140 "# http://www.netscape.com/newsref/std/cookie_spec.html\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
141 "# This is a generated file! Do not edit.\n\n";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
142
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
143
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
144 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
145 * Forward declarations
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
146 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
147
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
148 static FILE *Cookies_fopen(const char *file, char *init_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
149 static CookieControlAction Cookies_control_check_domain(const char *domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
150 static int Cookie_control_init(void);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
151 static void Cookies_parse_ports(int url_port, CookieData_t *cookie,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
152 const char *port_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
153 static char *Cookies_build_ports_str(CookieData_t *cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
154 static char *Cookies_strip_path(const char *path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
155 static void Cookies_add_cookie(CookieData_t *cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
156 static void Cookies_remove_cookie(CookieData_t *cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
157 static int Cookies_cmp(const void *a, const void *b);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
158
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
159 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
160 * Compare function for searching a cookie node
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
161 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
162 int Cookie_node_cmp(const void *v1, const void *v2)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
163 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
164 const CookieNode *n1 = v1, *n2 = v2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
165
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
166 return strcmp(n1->domain, n2->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
167 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
168
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
169 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
170 * Compare function for searching a cookie node by domain
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
171 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
172 int Cookie_node_by_domain_cmp(const void *v1, const void *v2)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
173 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
174 const CookieNode *node = v1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
175 const char *domain = v2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
176
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
177 return strcmp(node->domain, domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
178 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
179
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
180 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
181 * Return a file pointer. If the file doesn't exist, try to create it,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
182 * with the optional 'init_str' as its content.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
183 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
184 static FILE *Cookies_fopen(const char *filename, char *init_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
185 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
186 FILE *F_in;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
187 int fd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
188
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
189 if ((F_in = fopen(filename, "r+")) == NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
190 /* Create the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
191 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
192 if (fd != -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
193 if (init_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
194 write(fd, init_str, strlen(init_str));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
195 close(fd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
196
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
197 MSG("Created file: %s\n", filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
198 F_in = Cookies_fopen(filename, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
199 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
200 MSG("Could not create file: %s!\n", filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
201 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
202 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
203
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
204 /* set close on exec */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
205 fcntl(fileno(F_in), F_SETFD, FD_CLOEXEC | fcntl(fileno(F_in), F_GETFD));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
206
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
207 return F_in;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
208 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
209
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
210 static void Cookies_free_cookie(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
211 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
212 dFree(cookie->name);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
213 dFree(cookie->value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
214 dFree(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
215 dFree(cookie->path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
216 dFree(cookie->comment);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
217 dFree(cookie->comment_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
218 dList_free(cookie->ports);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
219 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
220 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
221
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
222 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
223 * Initialize the cookies module
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
224 * (The 'disabled' variable is writable only within Cookies_init)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
225 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
226 void Cookies_init()
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
227 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
228 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
229 char *filename;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
230 char line[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
231 #ifndef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
232 struct flock lck;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
233 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
234 FILE *old_cookies_file_stream;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
235
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
236 /* Default setting */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
237 disabled = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
238
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
239 /* Read and parse the cookie control file (cookiesrc) */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
240 if (Cookie_control_init() != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
241 MSG("Disabling cookies.\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
242 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
243 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
244
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
245 /* Get a stream for the cookies file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
246 filename = dStrconcat(dGethomedir(), "/.dillo/cookies.txt", NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
247 file_stream = Cookies_fopen(filename, cookies_txt_header_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
248
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
249 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
250
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
251 if (!file_stream) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
252 MSG("ERROR: Can't open ~/.dillo/cookies.txt, disabling cookies\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
253 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
254 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
255
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
256 /* Try to get a lock from the file descriptor */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
257 #ifdef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
258 disabled = (lockf(fileno(file_stream), F_TLOCK, 0) == -1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
259 #else /* POSIX lock */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
260 lck.l_start = 0; /* start at beginning of file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
261 lck.l_len = 0; /* lock entire file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
262 lck.l_type = F_WRLCK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
263 lck.l_whence = SEEK_SET; /* absolute offset */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
264
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
265 disabled = (fcntl(fileno(file_stream), F_SETLK, &lck) == -1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
266 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
267 if (disabled) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
268 MSG("The cookies file has a file lock: disabling cookies!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
269 fclose(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
270 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
271 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
272
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
273 MSG("Enabling cookies as from cookiesrc...\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
274
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
275 cookies = dList_new(32);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
276
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
277 /* Get all lines in the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
278 while (!feof(file_stream)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
279 line[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
280 fgets(line, LINE_MAXLEN, file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
281
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
282 /* Remove leading and trailing whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
283 dStrstrip(line);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
284
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
285 if ((line[0] != '\0') && (line[0] != '#')) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
286 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
287 * Split the row into pieces using a tab as the delimiter.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
288 * pieces[0] The domain name
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
289 * pieces[1] TRUE/FALSE: is the domain a suffix, or a full domain?
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
290 * pieces[2] The path
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
291 * pieces[3] Is the cookie unsecure or secure (TRUE/FALSE)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
292 * pieces[4] Timestamp of expire date
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
293 * pieces[5] Name of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
294 * pieces[6] Value of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
295 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
296 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
297 char *piece;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
298 char *line_marker = line;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
299
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
300 cookie = dNew0(CookieData_t, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
301
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
302 cookie->session_only = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
303 cookie->version = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
304 cookie->domain = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
305 dStrsep(&line_marker, "\t"); /* we use domain always as sufix */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
306 cookie->path = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
307 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
308 if (piece != NULL && piece[0] == 'T')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
309 cookie->secure = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
310 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
311 if (piece != NULL)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
312 cookie->expires_at = (time_t) strtol(piece, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
313 cookie->name = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
314 cookie->value = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
315
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
316 if (!cookie->domain || cookie->domain[0] == '\0' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
317 !cookie->path || cookie->path[0] != '/' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
318 !cookie->name || cookie->name[0] == '\0' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
319 !cookie->value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
320 MSG("Malformed line in cookies.txt file!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
321 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
322 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
323 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
324
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
325 action = Cookies_control_check_domain(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
326 if (action == COOKIE_DENY) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
327 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
328 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
329 } else if (action == COOKIE_ACCEPT_SESSION) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
330 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
331 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
332
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
333 /* Save cookie in memory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
334 Cookies_add_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
335 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
336 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
337
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
338 filename = dStrconcat(dGethomedir(), "/.dillo/cookies", NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
339 if ((old_cookies_file_stream = fopen(filename, "r")) != NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
340 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
341 MSG("WARNING: Reading old cookies file ~/.dillo/cookies too\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
342
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
343 /* Get all lines in the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
344 while (!feof(old_cookies_file_stream)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
345 line[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
346 fgets(line, LINE_MAXLEN, old_cookies_file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
347
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
348 /* Remove leading and trailing whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
349 dStrstrip(line);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
350
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
351 if (line[0] != '\0') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
352 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
353 * Split the row into pieces using a tab as the delimiter.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
354 * pieces[0] The version this cookie was set as (0 / 1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
355 * pieces[1] The domain name
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
356 * pieces[2] A comma separated list of accepted ports
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
357 * pieces[3] The path
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
358 * pieces[4] Is the cookie unsecure or secure (0 / 1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
359 * pieces[5] Timestamp of expire date
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
360 * pieces[6] Name of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
361 * pieces[7] Value of the cookie
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
362 * pieces[8] Comment
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
363 * pieces[9] Comment url
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
364 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
365 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
366 char *piece;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
367 char *line_marker = line;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
368
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
369 cookie = dNew0(CookieData_t, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
370
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
371 cookie->session_only = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
372 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
373 if (piece != NULL)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
374 cookie->version = strtol(piece, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
375 cookie->domain = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
376 Cookies_parse_ports(0, cookie, dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
377 cookie->path = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
378 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
379 if (piece != NULL && piece[0] == '1')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
380 cookie->secure = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
381 piece = dStrsep(&line_marker, "\t");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
382 if (piece != NULL)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
383 cookie->expires_at = (time_t) strtol(piece, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
384 cookie->name = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
385 cookie->value = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
386 cookie->comment = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
387 cookie->comment_url = dStrdup(dStrsep(&line_marker, "\t"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
388
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
389 if (!cookie->domain || cookie->domain[0] == '\0' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
390 !cookie->path || cookie->path[0] != '/' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
391 !cookie->name || cookie->name[0] == '\0' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
392 !cookie->value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
393 MSG("Malformed line in cookies file!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
394 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
395 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
396 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
397
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
398 action = Cookies_control_check_domain(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
399 if (action == COOKIE_DENY) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
400 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
401 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
402 } else if (action == COOKIE_ACCEPT_SESSION) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
403 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
404 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
405
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
406 /* Save cookie in memory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
407 Cookies_add_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
408 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
409 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
410 fclose(old_cookies_file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
411 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
412 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
413 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
414
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 * Flush cookies to disk and free all the memory allocated.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
419 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
420 void Cookies_save_and_free()
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
421 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
422 int i, fd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
423 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
424 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
425
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
426 #ifndef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
427 struct flock lck;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
428 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
429
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
430 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
431 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
432
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
433 rewind(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
434 fd = fileno(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
435 ftruncate(fd, 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
436 fprintf(file_stream, cookies_txt_header_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
437
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
438 /* Iterate cookies per domain, saving and freeing */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
439 while ((node = dList_nth_data(cookies, 0))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
440 for (i = 0; (cookie = dList_nth_data(node->dlist, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
441 if (!cookie->session_only) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
442 /* char * ports_str = Cookies_build_ports_str(cookie); */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
443 fprintf(file_stream, "%s\tTRUE\t%s\t%s\t%ld\t%s\t%s\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
444 cookie->domain,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
445 cookie->path,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
446 cookie->secure ? "TRUE" : "FALSE",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
447 (long)cookie->expires_at,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
448 cookie->name,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
449 cookie->value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
450 /* dFree(ports_str); */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
451 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
452
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
453 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
454 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
455 dList_remove(cookies, node);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
456 dFree(node->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
457 dList_free(node->dlist);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
458 dFree(node);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
459 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
460
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
461 #ifdef HAVE_LOCKF
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
462 lockf(fd, F_ULOCK, 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
463 #else /* POSIX file lock */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
464 lck.l_start = 0; /* start at beginning of file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
465 lck.l_len = 0; /* lock entire file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
466 lck.l_type = F_UNLCK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
467 lck.l_whence = SEEK_SET; /* absolute offset */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
468
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
469 fcntl(fileno(file_stream), F_SETLKW, &lck);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
470 #endif
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
471 fclose(file_stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
472 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
473
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
474 static char *months[] =
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
475 { "",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
476 "Jan", "Feb", "Mar",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
477 "Apr", "May", "Jun",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
478 "Jul", "Aug", "Sep",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
479 "Oct", "Nov", "Dec"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
480 };
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
481
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
482 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
483 * Take a months name and return a number between 1-12.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
484 * E.g. 'April' -> 4
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
485 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
486 static int Cookies_get_month(const char *month_name)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
487 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
488 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
489
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
490 for (i = 1; i <= 12; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
491 if (!dStrncasecmp(months[i], month_name, 3))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
492 return i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
493 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
494 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
495 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
496
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
497 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
498 * Return a local timestamp from a GMT date string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
499 * Accept: RFC-1123 | RFC-850 | ANSI asctime | Old Netscape format.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
500 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
501 * Wdy, DD-Mon-YY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
502 * Wdy, DD-Mon-YYYY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
503 * Weekday, DD-Mon-YY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
504 * Weekday, DD-Mon-YYYY HH:MM:SS GMT
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
505 * Tue May 21 13:46:22 1991\n
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
506 * Tue May 21 13:46:22 1991
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
507 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
508 * (return 0 on malformed date string syntax)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
509 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
510 static time_t Cookies_create_timestamp(const char *expires)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
511 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
512 time_t ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
513 int day, month, year, hour, minutes, seconds;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
514 char *cp;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
515 char *E_msg =
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
516 "Expire date is malformed!\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
517 " (should be RFC-1123 | RFC-850 | ANSI asctime)\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
518 " Ignoring cookie: ";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
519
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
520 cp = strchr(expires, ',');
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
521 if (!cp && (strlen(expires) == 24 || strlen(expires) == 25)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
522 /* Looks like ANSI asctime format... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
523 cp = (char *)expires;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
524 day = strtol(cp + 8, NULL, 10); /* day */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
525 month = Cookies_get_month(cp + 4); /* month */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
526 year = strtol(cp + 20, NULL, 10); /* year */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
527 hour = strtol(cp + 11, NULL, 10); /* hour */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
528 minutes = strtol(cp + 14, NULL, 10); /* minutes */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
529 seconds = strtol(cp + 17, NULL, 10); /* seconds */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
530
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
531 } else if (cp && (cp - expires == 3 || cp - expires > 5) &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
532 (strlen(cp) == 24 || strlen(cp) == 26)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
533 /* RFC-1123 | RFC-850 format | Old Netscape format */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
534 day = strtol(cp + 2, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
535 month = Cookies_get_month(cp + 5);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
536 year = strtol(cp + 9, &cp, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
537 /* todo: tricky, because two digits for year IS ambiguous! */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
538 year += (year < 70) ? 2000 : ((year < 100) ? 1900 : 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
539 hour = strtol(cp + 1, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
540 minutes = strtol(cp + 4, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
541 seconds = strtol(cp + 7, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
542
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
543 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
544 MSG("%s%s\n", E_msg, expires);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
545 return (time_t) 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
546 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
547
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
548 /* Error checks --this may be overkill */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
549 if (!(day > 0 && day < 32 && month > 0 && month < 13 && year > 1970 &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
550 hour >= 0 && hour < 24 && minutes >= 0 && minutes < 60 &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
551 seconds >= 0 && seconds < 60)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
552 MSG("%s%s\n", E_msg, expires);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
553 return (time_t) 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
554 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
555
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
556 /* Calculate local timestamp.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
557 * [stolen from Lynx... (http://lynx.browser.org)] */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
558 month -= 3;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
559 if (month < 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
560 month += 12;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
561 year--;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
562 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
563
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
564 day += (year - 1968) * 1461 / 4;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
565 day += ((((month * 153) + 2) / 5) - 672);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
566 ret = (time_t)((day * 60 * 60 * 24) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
567 (hour * 60 * 60) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
568 (minutes * 60) +
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
569 seconds);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
570
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
571 MSG("Expires in %ld seconds, at %s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
572 (long)ret - time(NULL), ctime(&ret));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
573
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
574 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
575 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
576
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
577 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
578 * Parse a string containing a list of port numbers.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
579 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
580 static void Cookies_parse_ports(int url_port, CookieData_t *cookie,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
581 const char *port_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
582 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
583 if ((!port_str || !port_str[0]) && url_port != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
584 /* There was no list, so only the calling urls port should be allowed. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
585 if (!cookie->ports)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
586 cookie->ports = dList_new(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
587 dList_append(cookie->ports, INT2VOIDP(url_port));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
588 } else if (port_str[0] == '"' && port_str[1] != '"') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
589 char *tok, *str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
590 int port;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
591
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
592 str = dStrdup(port_str + 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
593 while ((tok = dStrsep(&str, ","))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
594 port = strtol(tok, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
595 if (port > 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
596 if (!cookie->ports)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
597 cookie->ports = dList_new(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
598 dList_append(cookie->ports, INT2VOIDP(port));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
599 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
600 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
601 dFree(str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
602 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
603 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
604
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
605 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
606 * Build a string of the ports in 'cookie'.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
607 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
608 static char *Cookies_build_ports_str(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
609 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
610 Dstr *dstr;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
611 char *ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
612 void *data;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
613 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
614
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
615 dstr = dStr_new("\"");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
616 for (i = 0; (data = dList_nth_data(cookie->ports, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
617 dStr_sprintfa(dstr, "%d,", VOIDP2INT(data));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
618 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
619 /* Remove any trailing comma */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
620 if (dstr->len > 1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
621 dStr_erase(dstr, dstr->len - 1, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
622 dStr_append(dstr, "\"");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
623
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
624 ret = dstr->str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
625 dStr_free(dstr, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
626
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
627 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
628 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
629
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
630 static void Cookies_add_cookie(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
631 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
632 Dlist *domain_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
633 CookieData_t *c;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
634 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
635
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
636 /* Don't add an expired cookie */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
637 if (!cookie->session_only && cookie->expires_at < time(NULL)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
638 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
639 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
640 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
641
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
642 node = dList_find_sorted(cookies, cookie->domain,Cookie_node_by_domain_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
643 domain_cookies = (node) ? node->dlist : NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
644
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
645 if (domain_cookies) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
646 /* Respect the limit of 20 cookies per domain */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
647 if (dList_length(domain_cookies) >= 20) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
648 MSG("There are too many cookies for this domain (%s)\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
649 cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
650 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
651 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
652 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
653
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
654 /* Remove any cookies with the same name and path */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
655 while ((c = dList_find_custom(domain_cookies, cookie, Cookies_cmp))){
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
656 Cookies_remove_cookie(c);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
657 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
658 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
659
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
660 /* add the cookie into the respective domain list */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
661 node = dList_find_sorted(cookies, cookie->domain,Cookie_node_by_domain_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
662 domain_cookies = (node) ? node->dlist : NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
663 if (!domain_cookies) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
664 domain_cookies = dList_new(5);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
665 dList_append(domain_cookies, cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
666 node = dNew(CookieNode, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
667 node->domain = dStrdup(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
668 node->dlist = domain_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
669 dList_insert_sorted(cookies, node, Cookie_node_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
670 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
671 dList_append(domain_cookies, cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
672 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
673 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
674
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
675 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
676 * Remove the cookie from the domain list.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
677 * If the domain list is empty, remove the node too.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
678 * Free the cookie.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
679 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
680 static void Cookies_remove_cookie(CookieData_t *cookie)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
681 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
682 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
683
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
684 node = dList_find_sorted(cookies, cookie->domain,Cookie_node_by_domain_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
685 if (node) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
686 dList_remove(node->dlist, cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
687 if (dList_length(node->dlist) == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
688 dList_remove(cookies, node);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
689 dFree(node->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
690 dList_free(node->dlist);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
691 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
692 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
693 MSG("Attempting to remove a cookie that doesn't exist!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
694 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
695
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
696 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
697 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
698
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
699 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
700 * Return the attribute that is present at *cookie_str. This function
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
701 * will also attempt to advance cookie_str past any equal-sign.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
702 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
703 static char *Cookies_parse_attr(char **cookie_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
704 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
705 char *str = *cookie_str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
706 uint_t i, end = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
707 bool_t got_attr = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
708
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
709 for (i = 0; ; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
710 switch (str[i]) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
711 case ' ':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
712 case '\t':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
713 case '=':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
714 case ';':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
715 got_attr = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
716 if (end == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
717 end = i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
718 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
719 case ',':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
720 *cookie_str = str + i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
721 return dStrndup(str, i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
722 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
723 case '\0':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
724 if (!got_attr) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
725 end = i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
726 got_attr = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
727 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
728 /* fall through! */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
729 default:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
730 if (got_attr) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
731 *cookie_str = str + i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
732 return dStrndup(str, end);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
733 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
734 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
735 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
736 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
737
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
738 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
739 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
740
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
741 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
742 * Get the value starting at *cookie_str.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
743 * broken_syntax: watch out for stupid syntax (comma in unquoted string...)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
744 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
745 static char *Cookies_parse_value(char **cookie_str,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
746 bool_t broken_syntax,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
747 bool_t keep_quotes)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
748 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
749 uint_t i, end;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
750 char *str = *cookie_str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
751
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
752 for (i = end = 0; !end; ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
753 switch (str[i]) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
754 case ' ':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
755 case '\t':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
756 if (!broken_syntax && str[0] != '\'' && str[0] != '"') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
757 *cookie_str = str + i + 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
758 end = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
759 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
760 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
761 case '\'':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
762 case '"':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
763 if (i != 0 && str[i] == str[0]) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
764 char *tmp = str + i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
765
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
766 while (*tmp != '\0' && *tmp != ';' && *tmp != ',')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
767 tmp++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
768
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
769 *cookie_str = (*tmp == ';') ? tmp + 1 : tmp;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
770
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
771 if (keep_quotes)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
772 i++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
773 end = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
774 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
775 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
776 case '\0':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
777 *cookie_str = str + i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
778 end = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
779 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
780 case ',':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
781 if (str[0] != '\'' && str[0] != '"' && !broken_syntax) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
782 /* A new cookie starts here! */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
783 *cookie_str = str + i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
784 end = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
785 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
786 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
787 case ';':
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
788 if (str[0] != '\'' && str[0] != '"') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
789 *cookie_str = str + i + 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
790 end = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
791 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
792 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
793 default:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
794 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
795 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
796 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
797 /* keep i as an index to the last char */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
798 --i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
799
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
800 if ((str[0] == '\'' || str[0] == '"') && !keep_quotes) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
801 return i > 1 ? dStrndup(str + 1, i - 1) : NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
802 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
803 return dStrndup(str, i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
804 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
805 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
806
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
807 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
808 * Parse one cookie...
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
809 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
810 static CookieData_t *Cookies_parse_one(int url_port, char **cookie_str)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
811 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
812 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
813 char *str = *cookie_str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
814 char *attr;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
815 char *value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
816 int num_attr = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
817 bool_t max_age = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
818 bool_t discard = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
819
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
820 cookie = dNew0(CookieData_t, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
821 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
822
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
823 /* Iterate until there is nothing left of the string OR we come
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
824 * across a comma representing the start of another cookie */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
825 while (*str != '\0' && *str != ',') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
826 /* Skip whitespace */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
827 while (isspace(*str))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
828 str++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
829
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
830 /* Get attribute */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
831 attr = Cookies_parse_attr(&str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
832 if (!attr) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
833 MSG("Failed to parse cookie attribute!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
834 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
835 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
836 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
837
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
838 /* Get the value for the attribute and store it */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
839 if (num_attr == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
840 /* The first attr, which always is the user supplied attr, may
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
841 * have the same name as an ordinary attr. Hence this workaround. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
842 cookie->name = dStrdup(attr);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
843 cookie->value = Cookies_parse_value(&str, FALSE, TRUE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
844 } else if (dStrcasecmp(attr, "Path") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
845 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
846 cookie->path = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
847 } else if (dStrcasecmp(attr, "Domain") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
848 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
849 cookie->domain = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
850 } else if (dStrcasecmp(attr, "Discard") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
851 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
852 discard = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
853 } else if (dStrcasecmp(attr, "Max-Age") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
854 if (!discard) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
855 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
856
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
857 if (value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
858 cookie->expires_at = time(NULL) + strtol(value, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
859 cookie->session_only = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
860 max_age = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
861 dFree(value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
862 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
863 MSG("Failed to parse cookie value!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
864 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
865 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
866 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
867 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
868 } else if (dStrcasecmp(attr, "Expires") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
869 if (!max_age && !discard) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
870 MSG("Old netscape-style cookie...\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
871 value = Cookies_parse_value(&str, TRUE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
872 if (value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
873 cookie->expires_at = Cookies_create_timestamp(value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
874 cookie->session_only = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
875 dFree(value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
876 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
877 MSG("Failed to parse cookie value!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
878 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
879 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
880 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
881 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
882 } else if (dStrcasecmp(attr, "Port") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
883 value = Cookies_parse_value(&str, FALSE, TRUE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
884 Cookies_parse_ports(url_port, cookie, value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
885 dFree(value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
886 } else if (dStrcasecmp(attr, "Comment") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
887 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
888 cookie->comment = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
889 } else if (dStrcasecmp(attr, "CommentURL") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
890 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
891 cookie->comment_url = value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
892 } else if (dStrcasecmp(attr, "Version") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
893 value = Cookies_parse_value(&str, FALSE, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
894
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
895 if (value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
896 cookie->version = strtol(value, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
897 dFree(value);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
898 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
899 MSG("Failed to parse cookie value!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
900 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
901 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
902 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
903 } else if (dStrcasecmp(attr, "Secure") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
904 cookie->secure = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
905 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
906 /* Oops! this can't be good... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
907 dFree(attr);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
908 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
909 MSG("Cookie contains illegal attribute!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
910 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
911 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
912
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
913 dFree(attr);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
914 num_attr++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
915 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
916
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
917 *cookie_str = (*str == ',') ? str + 1 : str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
918
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
919 if (cookie->name && cookie->value) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
920 return cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
921 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
922 MSG("Cookie missing name and/or value!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
923 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
924 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
925 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
926 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
927
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
928 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
929 * Iterate the cookie string until we catch all cookies.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
930 * Return Value: a list with all the cookies! (or NULL upon error)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
931 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
932 static Dlist *Cookies_parse_string(int url_port, char *cookie_string)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
933 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
934 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
935 Dlist *ret = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
936 char *str = cookie_string;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
937
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
938 /* The string may contain several cookies separated by comma.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
939 * We'll iterate until we've catched them all */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
940 while (*str) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
941 cookie = Cookies_parse_one(url_port, &str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
942
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
943 if (cookie) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
944 if (!ret)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
945 ret = dList_new(4);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
946 dList_append(ret, cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
947 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
948 MSG("Malformed cookie field, ignoring cookie: %s\n", cookie_string);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
949 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
950 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
951
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
952 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
953 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
954
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
955 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
956 * Compare cookies by name and path (return 0 if equal)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
957 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
958 static int Cookies_cmp(const void *a, const void *b)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
959 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
960 const CookieData_t *ca = a, *cb = b;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
961 int ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
962
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
963 if (!(ret = strcmp(ca->name, cb->name)))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
964 ret = strcmp(ca->path, cb->path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
965 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
966 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
967
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
968 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
969 * Validate cookies domain against some security checks.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
970 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
971 static bool_t Cookies_validate_domain(CookieData_t *cookie, char *host,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
972 char *url_path)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
973 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
974 int dots, diff, i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
975 bool_t is_ip;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
976
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
977 /* Make sure that the path is set to something */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
978 if (!cookie->path || cookie->path[0] != '/') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
979 dFree(cookie->path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
980 cookie->path = Cookies_strip_path(url_path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
981 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
982
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
983 /* If the server never set a domain, or set one without a leading
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
984 * dot (which isn't allowed), we use the calling URL's hostname. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
985 if (cookie->domain == NULL || cookie->domain[0] != '.') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
986 dFree(cookie->domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
987 cookie->domain = dStrdup(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
988 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
989 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
990
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
991 /* Count the number of dots and also find out if it is an IP-address */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
992 is_ip = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
993 for (i = 0, dots = 0; cookie->domain[i] != '\0'; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
994 if (cookie->domain[i] == '.')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
995 dots++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
996 else if (!isdigit(cookie->domain[i]))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
997 is_ip = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
998 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
999
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1000 /* A valid domain must have at least two dots in it */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1001 /* NOTE: this breaks cookies on localhost... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1002 if (dots < 2) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1003 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1004 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1005
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1006 /* Now see if the url matches the domain */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1007 diff = strlen(host) - i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1008 if (diff > 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1009 if (dStrcasecmp(host + diff, cookie->domain))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1010 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1011
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1012 if (!is_ip) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1013 /* "x.y.test.com" is not allowed to set cookies for ".test.com";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1014 * only an url of the form "y.test.com" would be. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1015 while ( diff-- )
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1016 if (host[diff] == '.')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1017 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1018 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1019 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1020
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1021 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1022 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1023
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1024 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1025 * Strip of the filename from a full path
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1026 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1027 static char *Cookies_strip_path(const char *path)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1028 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1029 char *ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1030 uint_t len;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1031
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1032 if (path) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1033 len = strlen(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1034
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1035 while (len && path[len] != '/')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1036 len--;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1037 ret = dStrndup(path, len + 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1038 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1039 ret = dStrdup("/");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1040 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1041
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1042 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1043 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1044
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1045 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1046 * Set the value corresponding to the cookie string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1047 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1048 void Cookies_set(char *cookie_string, char *url_host,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1049 char *url_path, int url_port)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1050 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1051 CookieControlAction action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1052 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1053 Dlist *list;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1054 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1055
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1056 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1057 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1058
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1059 action = Cookies_control_check_domain(url_host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1060 if (action == COOKIE_DENY) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1061 MSG("denied SET for %s\n", url_host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1062 return;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1063 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1064
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1065 if ((list = Cookies_parse_string(url_port, cookie_string))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1066 for (i = 0; (cookie = dList_nth_data(list, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1067 if (Cookies_validate_domain(cookie, url_host, url_path)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1068 if (action == COOKIE_ACCEPT_SESSION)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1069 cookie->session_only = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1070 Cookies_add_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1071 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1072 MSG("Rejecting cookie for %s from host %s path %s\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1073 cookie->domain, url_host, url_path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1074 Cookies_free_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1075 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1076 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1077 dList_free(list);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1078 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1079 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1080
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1081 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1082 * Compare the cookie with the supplied data to see if it matches
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1083 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1084 static bool_t Cookies_match(CookieData_t *cookie, int port,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1085 const char *path, bool_t is_ssl)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1086 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1087 void *data;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1088 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1089
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1090 /* Insecure cookies matches both secure and insecure urls, secure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1091 cookies matches only secure urls */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1092 if (cookie->secure && !is_ssl)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1093 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1094
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1095 /* Check that the cookie path is a subpath of the current path */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1096 if (strncmp(cookie->path, path, strlen(cookie->path)) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1097 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1098
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1099 /* Check if the port of the request URL matches any
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1100 * of those set in the cookie */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1101 if (cookie->ports) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1102 for (i = 0; (data = dList_nth_data(cookie->ports, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1103 if (VOIDP2INT(data) == port)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1104 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1105 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1106 return FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1107 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1108
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1109 /* It's a match */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1110 return TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1111 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1112
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1113 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1114 * Return a string that contains all relevant cookies as headers.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1115 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1116 char *Cookies_get(char *url_host, char *url_path,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1117 char *url_scheme, int url_port)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1118 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1119 char *domain_str, *q, *str, *path;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1120 CookieData_t *cookie;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1121 Dlist *matching_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1122 CookieNode *node;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1123 Dlist *domain_cookies;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1124 bool_t is_ssl;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1125 Dstr *cookie_dstring;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1126 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1127
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1128 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1129 return dStrdup("");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1130
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1131 matching_cookies = dList_new(8);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1132
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1133 path = Cookies_strip_path(url_path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1134
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1135 /* Check if the protocol is secure or not */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1136 is_ssl = (!dStrcasecmp(url_scheme, "https"));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1137
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1138 for (domain_str = (char *) url_host;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1139 domain_str != NULL && *domain_str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1140 domain_str = strchr(domain_str+1, '.')) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1141
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1142 node = dList_find_sorted(cookies, domain_str, Cookie_node_by_domain_cmp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1143 domain_cookies = (node) ? node->dlist : NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1144
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1145 for (i = 0; (cookie = dList_nth_data(domain_cookies, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1146 /* Remove expired cookie. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1147 if (!cookie->session_only && cookie->expires_at < time(NULL)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1148 Cookies_remove_cookie(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1149 --i; continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1150 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1151 /* Check if the cookie matches the requesting URL */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1152 if (Cookies_match(cookie, url_port, path, is_ssl)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1153 dList_append(matching_cookies, cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1154 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1155 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1156 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1157
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1158 /* Found the cookies, now make the string */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1159 cookie_dstring = dStr_new("");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1160 if (dList_length(matching_cookies) > 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1161 CookieData_t *first_cookie = dList_nth_data(matching_cookies, 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1162
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1163 dStr_sprintfa(cookie_dstring, "Cookie: ");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1164
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1165 if (first_cookie->version != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1166 dStr_sprintfa(cookie_dstring, "$Version=\"%d\"; ",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1167 first_cookie->version);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1168
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1169
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1170 for (i = 0; (cookie = dList_nth_data(matching_cookies, i)); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1171 q = (cookie->version == 0 ? "" : "\"");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1172 dStr_sprintfa(cookie_dstring,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1173 "%s=%s; $Path=%s%s%s; $Domain=%s%s%s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1174 cookie->name, cookie->value,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1175 q, cookie->path, q, q, cookie->domain, q);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1176 if (cookie->ports) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1177 char *ports_str = Cookies_build_ports_str(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1178 dStr_sprintfa(cookie_dstring, "; $Port=%s", ports_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1179 dFree(ports_str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1180 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1181
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1182 dStr_append(cookie_dstring,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1183 dList_length(matching_cookies) > i + 1 ? "; " : "\r\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1184 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1185 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1186
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1187 dList_free(matching_cookies);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1188 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1189 str = cookie_dstring->str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1190 dStr_free(cookie_dstring, FALSE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1191 return str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1192 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1193
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1194 /* -------------------------------------------------------------
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1195 * Access control routines
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1196 * ------------------------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1197
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1198
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1199 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1200 * Get the cookie control rules (from cookiesrc).
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1201 * Return value:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1202 * 0 = Parsed OK, with cookies enabled
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1203 * 1 = Parsed OK, with cookies disabled
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1204 * 2 = Can't open the control file
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1205 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1206 static int Cookie_control_init(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1207 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1208 CookieControl cc;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1209 FILE *stream;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1210 char *filename;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1211 char line[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1212 char domain[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1213 char rule[LINE_MAXLEN];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1214 int i, j;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1215 bool_t enabled = FALSE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1216
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1217 /* Get a file pointer */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1218 filename = dStrconcat(dGethomedir(), "/.dillo/cookiesrc", NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1219 stream = Cookies_fopen(filename, "DEFAULT DENY\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1220 dFree(filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1221
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1222 if (!stream)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1223 return 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1224
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1225 /* Get all lines in the file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1226 while (!feof(stream)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1227 line[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1228 fgets(line, LINE_MAXLEN, stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1229
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1230 /* Remove leading and trailing whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1231 dStrstrip(line);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1232
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1233 if (line[0] != '\0' && line[0] != '#') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1234 i = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1235 j = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1236
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1237 /* Get the domain */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1238 while (!isspace(line[i]))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1239 domain[j++] = line[i++];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1240 domain[j] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1241
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1242 /* Skip past whitespaces */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1243 i++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1244 while (isspace(line[i]))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1245 i++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1246
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1247 /* Get the rule */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1248 j = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1249 while (line[i] != '\0' && !isspace(line[i]))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1250 rule[j++] = line[i++];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1251 rule[j] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1252
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1253 if (dStrcasecmp(rule, "ACCEPT") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1254 cc.action = COOKIE_ACCEPT;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1255 else if (dStrcasecmp(rule, "ACCEPT_SESSION") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1256 cc.action = COOKIE_ACCEPT_SESSION;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1257 else if (dStrcasecmp(rule, "DENY") == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1258 cc.action = COOKIE_DENY;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1259 else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1260 MSG("Cookies: rule '%s' for domain '%s' is not recognised.\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1261 rule, domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1262 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1263 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1264
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1265 cc.domain = dStrdup(domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1266 if (dStrcasecmp(cc.domain, "DEFAULT") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1267 /* Set the default action */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1268 default_action = cc.action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1269 dFree(cc.domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1270 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1271 a_List_add(ccontrol, num_ccontrol, num_ccontrol_max);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1272 ccontrol[num_ccontrol++] = cc;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1273 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1274
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1275 if (cc.action != COOKIE_DENY)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1276 enabled = TRUE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1277 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1278 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1279
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1280 fclose(stream);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1281
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1282 return (enabled ? 0 : 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1283 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1284
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1285 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1286 * Check the rules for an appropriate action for this domain
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1287 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1288 static CookieControlAction Cookies_control_check_domain(const char *domain)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1289 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1290 int i, diff;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1291
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1292 for (i = 0; i < num_ccontrol; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1293 if (ccontrol[i].domain[0] == '.') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1294 diff = strlen(domain) - strlen(ccontrol[i].domain);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1295 if (diff >= 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1296 if (dStrcasecmp(domain + diff, ccontrol[i].domain) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1297 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1298 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1299 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1300 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1301 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1302 if (dStrcasecmp(domain, ccontrol[i].domain) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1303 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1304 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1305
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1306 /* If we got here we have a match */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1307 return( ccontrol[i].action );
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1308 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1309
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1310 return default_action;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1311 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1312
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1313 /* -- Dpi parser ----------------------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1314
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1315 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1316 * Parse a data stream (dpi protocol)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1317 * Note: Buf is a zero terminated string
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1318 * Return code: { 0:OK, 1:Abort, 2:Close }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1319 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1320 static int srv_parse_buf(SockHandler *sh, char *Buf, size_t BufSize)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1321 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1322 char *p, *cmd, *cookie, *host, *path, *scheme;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1323 int port;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1324
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1325 if (!(p = strchr(Buf, '>'))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1326 /* Haven't got a full tag */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1327 MSG("Haven't got a full tag!\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1328 return 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1329 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1330
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1331 cmd = a_Dpip_get_attr(Buf, BufSize, "cmd");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1332
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1333 if (cmd && strcmp(cmd, "DpiBye") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1334 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1335 MSG("Cookies dpi (pid %d): Got DpiBye.\n", (int)getpid());
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1336 exit(0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1337
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1338 } else if (cmd && strcmp(cmd, "set_cookie") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1339 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1340 cookie = a_Dpip_get_attr(Buf, BufSize, "cookie");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1341 host = a_Dpip_get_attr(Buf, BufSize, "host");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1342 path = a_Dpip_get_attr(Buf, BufSize, "path");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1343 p = a_Dpip_get_attr(Buf, BufSize, "port");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1344 port = strtol(p, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1345 dFree(p);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1346
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1347 Cookies_set(cookie, host, path, port);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1348
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1349 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1350 dFree(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1351 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1352 return 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1353
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1354 } else if (cmd && strcmp(cmd, "get_cookie") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1355 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1356 scheme = a_Dpip_get_attr(Buf, BufSize, "scheme");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1357 host = a_Dpip_get_attr(Buf, BufSize, "host");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1358 path = a_Dpip_get_attr(Buf, BufSize, "path");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1359 p = a_Dpip_get_attr(Buf, BufSize, "port");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1360 port = strtol(p, NULL, 10);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1361 dFree(p);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1362
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1363 cookie = Cookies_get(host, path, scheme, port);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1364 dFree(scheme);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1365 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1366 dFree(host);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1367
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1368 cmd = a_Dpip_build_cmd("cmd=%s cookie=%s", "get_cookie_answer", cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1369
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1370 if (sock_handler_write_str(sh, 1, cmd)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1371 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1372 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1373 return 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1374 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1375 dFree(cookie);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1376 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1377
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1378 return 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1379 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1380
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1381 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1382 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1383
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1384 /* -- Termination handlers ----------------------------------------------- */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1385 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1386 * (was to delete the local namespace socket),
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1387 * but this is handled by 'dpid' now.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1388 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1389 static void cleanup(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1390 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1391 Cookies_save_and_free();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1392 MSG("cleanup\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1393 /* no more cleanup required */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1394 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1395
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1396 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1397 * Perform any necessary cleanups upon abnormal termination
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1398 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1399 static void termination_handler(int signum)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1400 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1401 exit(signum);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1402 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1403
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1404
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1405 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1406 * -- MAIN -------------------------------------------------------------------
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1407 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1408 int main (void) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1409 struct sockaddr_un spun;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1410 int temp_sock_descriptor;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1411 socklen_t address_size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1412 char *buf;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1413 int code;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1414 SockHandler *sh;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1415
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1416 /* Arrange the cleanup function for terminations via exit() */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1417 atexit(cleanup);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1418
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1419 /* Arrange the cleanup function for abnormal terminations */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1420 if (signal (SIGINT, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1421 signal (SIGINT, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1422 if (signal (SIGHUP, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1423 signal (SIGHUP, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1424 if (signal (SIGTERM, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1425 signal (SIGTERM, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1426
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1427 Cookies_init();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1428 MSG("(v.1) accepting connections...\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1429
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1430 if (disabled)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1431 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1432
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1433 /* some OSes may need this... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1434 address_size = sizeof(struct sockaddr_un);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1435
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1436 while (1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1437 temp_sock_descriptor =
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1438 accept(STDIN_FILENO, (struct sockaddr *)&spun, &address_size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1439 if (temp_sock_descriptor == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1440 perror("[accept]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1441 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1442 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1443
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1444 /* create the SockHandler structure */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1445 sh = sock_handler_new(temp_sock_descriptor,temp_sock_descriptor,8*1024);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1446
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1447 while (1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1448 code = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1449 if ((buf = sock_handler_read(sh)) != NULL) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1450 /* Let's see what we fished... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1451 code = srv_parse_buf(sh, buf, strlen(buf));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1452 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1453 if (code == 1)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1454 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1455 else if (code == 2)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1456 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1457 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1458
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1459 _MSG("Closing SockHandler\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1460 sock_handler_close(sh);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1461 sock_handler_free(sh);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1462
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1463 }/*while*/
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1464 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1465
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1466 #endif /* !DISABLE_COOKIES */