Dillo v3.1.1-91-g6d5b3ee3
Loading...
Searching...
No Matches
cookies.c
Go to the documentation of this file.
1/*
2 * File: cookies.c
3 *
4 * Copyright 2001 Lars Clausen <lrclause@cs.uiuc.edu>
5 * Jörgen Viksell <jorgen.viksell@telia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
18#include "msg.h"
19
20#ifdef DISABLE_COOKIES
21
25void a_Cookies_init(void)
26{
27 MSG("Cookies: absolutely disabled at compilation time.\n");
28}
29
30#else
31
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/file.h>
35#include <fcntl.h>
36#include <unistd.h>
37#include <stdlib.h>
38#include <stdio.h>
39#include <ctype.h>
40#include <errno.h>
41
42#include "IO/Url.h"
43#include "list.h"
44#include "cookies.h"
45#include "capi.h"
46#include "../dpip/dpip.h"
47
48
50#define LINE_MAXLEN 4096
51
57
58typedef struct {
60 char *domain;
61} CookieControl;
62
63/* Variables for access control */
64static CookieControl *ccontrol = NULL;
65static int num_ccontrol = 0;
66static int num_ccontrol_max = 1;
68
70
71static FILE *Cookies_fopen(const char *file, char *init_str);
73static CookieControlAction Cookies_control_check_domain(const char *domain);
74static int Cookie_control_init(void);
75
80static FILE *Cookies_fopen(const char *filename, char *init_str)
81{
82 FILE *F_in;
83 int fd, rc;
84
85 if ((F_in = fopen(filename, "r")) == NULL) {
86 /* Create the file */
87 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
88 if (fd != -1) {
89 if (init_str) {
90 rc = write(fd, init_str, strlen(init_str));
91 if (rc == -1) {
92 MSG("Cookies: Could not write initial string to file %s: %s\n",
93 filename, dStrerror(errno));
94 }
95 }
96 dClose(fd);
97
98 MSG("Cookies: Created file: %s\n", filename);
99 F_in = fopen(filename, "r");
100 } else {
101 MSG("Cookies: Could not create file: %s!\n", filename);
102 }
103 }
104
105 if (F_in) {
106 /* set close on exec */
107 fcntl(fileno(F_in), F_SETFD, FD_CLOEXEC | fcntl(fileno(F_in), F_GETFD));
108 }
109
110 return F_in;
111}
112
118{
119 /* Default setting */
120 disabled = TRUE;
121
122 /* Read and parse the cookie control file (cookiesrc) */
123 if (Cookie_control_init() != 0) {
124 MSG("Disabling cookies.\n");
125 return;
126 }
127
128 MSG("Enabling cookies as from cookiesrc...\n");
129 disabled = FALSE;
130}
131
136{
137}
138
142void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url,
143 const char *date)
144{
145 CookieControlAction action;
146 char *cmd, *cookie_string, *dpip_tag;
147 const char *path;
148 int i;
149
150 if (disabled)
151 return;
152
153 action = Cookies_control_check(set_url);
154 if (action == COOKIE_DENY) {
155 _MSG("Cookies: denied SET for %s\n", URL_HOST_(set_url));
156 return;
157 }
158
159 for (i = 0; (cookie_string = dList_nth_data(cookie_strings, i)); ++i) {
160 path = URL_PATH_(set_url);
161 if (date)
162 cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s date=%s",
163 "set_cookie", cookie_string,
164 URL_HOST_(set_url), path ? path : "/", date);
165 else
166 cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s",
167 "set_cookie", cookie_string,
168 URL_HOST_(set_url), path ? path : "/");
169
170 _MSG("Cookies.c: a_Cookies_set \n\t \"%s\" \n",cmd );
171 /* This call is commented because it doesn't guarantee the order
172 * in which cookies are set and got. (It may deadlock too) */
173 //a_Capi_dpi_send_cmd(NULL, NULL, cmd, "cookies", 1);
174
175 dpip_tag = a_Dpi_send_blocking_cmd("cookies", cmd);
176 _MSG("a_Cookies_set: dpip_tag = {%s}\n", dpip_tag);
177 dFree(dpip_tag);
178 dFree(cmd);
179 }
180}
181
185char *a_Cookies_get_query(const DilloUrl *query_url, const DilloUrl *requester)
186{
187 char *cmd, *dpip_tag, *query;
188 const char *path;
189 CookieControlAction action;
190
191 if (disabled)
192 return dStrdup("");
193
194 action = Cookies_control_check(query_url);
195 if (action == COOKIE_DENY) {
196 _MSG("Cookies: denied GET for %s\n", URL_HOST_(query_url));
197 return dStrdup("");
198 }
199
200 if (requester == NULL) {
201 /* request made by user */
202 } else if (!a_Url_same_organization(query_url, requester)) {
203 MSG("Cookies: not sent for request by '%s' for '%s'\n",
204 URL_HOST(requester), URL_HOST(query_url));
205 return dStrdup("");
206 }
207
208 path = URL_PATH_(query_url);
209
210 cmd = a_Dpip_build_cmd("cmd=%s scheme=%s host=%s path=%s",
211 "get_cookie", URL_SCHEME(query_url),
212 URL_HOST(query_url), path ? path : "/");
213
214 /* Get the answer from cookies.dpi */
215 _MSG("cookies.c: a_Dpi_send_blocking_cmd cmd = {%s}\n", cmd);
216 dpip_tag = a_Dpi_send_blocking_cmd("cookies", cmd);
217 _MSG("cookies.c: after a_Dpi_send_blocking_cmd resp={%s}\n", dpip_tag);
218 dFree(cmd);
219
220 if (dpip_tag != NULL) {
221 query = a_Dpip_get_attr(dpip_tag, "cookie");
222 dFree(dpip_tag);
223 } else {
224 query = dStrdup("");
225 }
226 return query;
227}
228
229/* -------------------------------------------------------------
230 * Access control routines
231 * ------------------------------------------------------------- */
232
233
241static int Cookie_control_init(void)
242{
243 CookieControl cc;
244 FILE *stream;
245 char *filename, *rc;
246 char line[LINE_MAXLEN];
247 char domain[LINE_MAXLEN];
248 char rule[LINE_MAXLEN];
249 bool_t enabled = FALSE;
250
251 /* Get a file pointer */
252 filename = dStrconcat(dGethomedir(), "/.dillo/cookiesrc", NULL);
253 stream = Cookies_fopen(filename, "DEFAULT DENY\n");
254 dFree(filename);
255
256 if (!stream)
257 return 2;
258
259 /* Get all lines in the file */
260 while (!feof(stream)) {
261 line[0] = '\0';
262 rc = fgets(line, LINE_MAXLEN, stream);
263 if (!rc && ferror(stream)) {
264 MSG("Cookies1: Error while reading rule from cookiesrc: %s\n",
265 dStrerror(errno));
266 fclose(stream);
267 return 2; /* bail out */
268 }
269
270 /* Remove leading and trailing whitespaces */
271 dStrstrip(line);
272
273 if (line[0] != '\0' && line[0] != '#') {
274 int i = 0, j = 0;
275
276 /* Get the domain */
277 while (line[i] != '\0' && !dIsspace(line[i]))
278 domain[j++] = line[i++];
279 domain[j] = '\0';
280
281 /* Skip past whitespaces */
282 while (dIsspace(line[i]))
283 i++;
284
285 /* Get the rule */
286 j = 0;
287 while (line[i] != '\0' && !dIsspace(line[i]))
288 rule[j++] = line[i++];
289 rule[j] = '\0';
290
291 if (dStrAsciiCasecmp(rule, "ACCEPT") == 0)
292 cc.action = COOKIE_ACCEPT;
293 else if (dStrAsciiCasecmp(rule, "ACCEPT_SESSION") == 0)
294 cc.action = COOKIE_ACCEPT_SESSION;
295 else if (dStrAsciiCasecmp(rule, "DENY") == 0)
296 cc.action = COOKIE_DENY;
297 else {
298 MSG("Cookies: rule '%s' for domain '%s' is not recognised.\n",
299 rule, domain);
300 continue;
301 }
302
303 cc.domain = dStrdup(domain);
304 if (dStrAsciiCasecmp(cc.domain, "DEFAULT") == 0) {
305 /* Set the default action */
306 default_action = cc.action;
307 dFree(cc.domain);
308 } else {
309 int i;
310 uint_t len = strlen(cc.domain);
311
312 /* Insert into list such that longest rules come first. */
314 for (i = num_ccontrol++;
315 i > 0 && (len > strlen(ccontrol[i-1].domain));
316 i--) {
317 ccontrol[i] = ccontrol[i-1];
318 }
319 ccontrol[i] = cc;
320 }
321
322 if (cc.action != COOKIE_DENY)
323 enabled = TRUE;
324 }
325 }
326
327 fclose(stream);
328
329 return (enabled ? 0 : 1);
330}
331
338{
339 int i, diff;
340
341 for (i = 0; i < num_ccontrol; i++) {
342 if (ccontrol[i].domain[0] == '.') {
343 diff = strlen(domain) - strlen(ccontrol[i].domain);
344 if (diff >= 0) {
345 if (dStrAsciiCasecmp(domain + diff, ccontrol[i].domain) != 0)
346 continue;
347 } else {
348 continue;
349 }
350 } else {
351 if (dStrAsciiCasecmp(domain, ccontrol[i].domain) != 0)
352 continue;
353 }
354
355 /* If we got here we have a match */
356 return( ccontrol[i].action );
357 }
358
359 return default_action;
360}
361
369
370#endif /* !DISABLE_COOKIES */
unsigned int uint_t
Definition d_size.h:20
unsigned char bool_t
Definition d_size.h:21
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dFree(void *mem)
Definition dlib.c:68
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
char * dStrstrip(char *s)
Remove leading and trailing whitespace.
Definition dlib.c:122
char * dStrdup(const char *s)
Definition dlib.c:77
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:662
int dClose(int fd)
Close a FD handling EINTR.
Definition dlib.c:951
char * dGethomedir(void)
Return the home directory in a static string (don't free)
Definition dlib.c:906
#define dStrerror
Definition dlib.h:95
#define dIsspace(c)
Definition dlib.h:33
#define TRUE
Definition dlib.h:23
#define FALSE
Definition dlib.h:19
static int num_ccontrol
Definition cookies.c:128
#define _MSG(...)
Definition cookies.c:58
#define MSG(...)
Definition cookies.c:59
static int num_ccontrol_max
Definition cookies.c:129
static CookieControl * ccontrol
Definition cookies.c:127
static int Cookie_control_init(void)
Definition cookies.c:1418
#define a_List_add(list, num_items, alloc_step)
Definition cookies.c:68
static CookieControlAction default_action
Definition cookies.c:130
CookieControlAction
Definition cookies.c:84
@ COOKIE_ACCEPT_SESSION
Definition cookies.c:86
@ COOKIE_ACCEPT
Definition cookies.c:85
@ COOKIE_DENY
Definition cookies.c:87
static CookieControlAction Cookies_control_check_domain(const char *domain)
Definition cookies.c:1513
static bool_t disabled
Definition cookies.c:133
static FILE * Cookies_fopen(const char *filename, const char *mode, const char *init_str)
Definition cookies.c:191
#define LINE_MAXLEN
Definition cookies.c:79
char * a_Dpip_build_cmd(const char *format,...)
Printf like function for building dpip commands.
Definition dpip.c:83
char * a_Dpip_get_attr(const char *tag, const char *attrname)
Task: given a tag and an attribute name, return its value.
Definition dpip.c:192
Fast list methods.
char * a_Dpi_send_blocking_cmd(const char *server_name, const char *cmd)
Send a command to a dpi server, and block until the answer is got.
Definition dpi.c:770
void a_Cookies_init(void)
Initialize the cookies module (The 'disabled' variable is writable only within a_Cookies_init)
Definition cookies.c:117
static CookieControlAction Cookies_control_check(const DilloUrl *url)
Same as Cookies_control_check_domain except it takes an URL.
Definition cookies.c:365
void a_Cookies_freeall(void)
Flush cookies to disk and free all the memory allocated.
Definition cookies.c:135
char * a_Cookies_get_query(const DilloUrl *query_url, const DilloUrl *requester)
Return a string containing cookie data for an HTTP query.
Definition cookies.c:185
void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url, const char *date)
Set the value corresponding to the cookie string.
Definition cookies.c:142
Definition url.h:88
Definition dlib.h:131
static void path()
Definition cookies.c:859
bool_t a_Url_same_organization(const DilloUrl *u1, const DilloUrl *u2)
Definition url.c:798
#define URL_HOST_(u)
Definition url.h:54
#define URL_SCHEME(u)
Definition url.h:70
#define URL_PATH_(u)
Definition url.h:51
#define URL_HOST(u)
Definition url.h:75