⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lycookie.c

📁 基于rtos开发的浏览器!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*			       Lynx Cookie Support		   LYCookie.c**			       ===================****	Author: AMK	A.M. Kuchling (amk@magnet.com)	12/25/96****	Incorporated with mods by FM			01/16/97****  Based on:**	http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-state-mgmt-05.txt****	Updated for:**   http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-state-man-mec-02.txt**		- FM					1997-07-09****	Updated for:**   ftp://ds.internic.net/internet-drafts/draft-ietf-http-state-man-mec-03.txt**		- FM					1997-08-02****  TO DO: (roughly in order of decreasing priority)      * A means to specify "always allow" and "never allow" domains via	a configuration file is needed.      * Hex escaping isn't considered at all.  Any semi-colons, commas,	or spaces actually in cookie names or values (i.e., not serving	as punctuation for the overall Set-Cookie value) should be hex	escaped if not quoted, but presumeably the server is expecting	them to be hex escaped in our Cookie request header as well, so	in theory we need not unescape them.  We'll see how this works	out in practice.      * The prompt should show more information about the cookie being	set in Novice mode.      * The truncation heuristic in HTConfirmCookie should probably be	smarter, smart enough to leave a really short name/value string	alone.      * We protect against denial-of-service attacks (see section 6.3.1	of the draft) by limiting a domain to 50 cookies, limiting the	total number of cookies to 500, and limiting a processed cookie	to a maximum of 4096 bytes, but we count on the normal garbage	collections to bring us back down under the limits, rather than	actively removing cookies and/or domains based on age or frequency	of use.      * If a cookie has the secure flag set, we presently treat only SSL	connections as secure.	This may need to be expanded for other	secure communication protocols that become standarized.      * Cookies could be optionally stored in a file from session to session.*/#include "HTUtils.h"#include "tcp.h"#include "HTAccess.h"#include "HTParse.h"#include "HTAlert.h"#include "LYCurses.h"#include "LYSignal.h"#include "LYUtils.h"#include "LYCharUtils.h"#include "LYClean.h"#include "LYGlobalDefs.h"#include "LYEdit.h"#include "LYStrings.h"#include "LYSystem.h"#include "GridText.h"#include "LYUtils.h"#include "LYCharUtils.h"#include "LYCookie.h"#include "LYLeaks.h"#define FREE(x) if (x) {free(x); x = NULL;}/***  The first level of the cookie list is a list indexed by the domain**  string; cookies with the same domain will be placed in the same**  list.  Thus, finding the cookies that apply to a given URL is a**  two-level scan; first we check each domain to see if it applies,**  and if so, then we check the paths of all the cookies on that**  list.   We keep a running total of cookies as we add or delete**  them*/PRIVATE HTList *domain_list = NULL;PRIVATE HTList *cookie_list = NULL;PRIVATE int total_cookies = 0;struct _cookie {    char *lynxID;  /* Lynx cookie identifier */    char *name;    /* Name of this cookie */    char *value;   /* Value of this cookie */    int version;   /* Cookie protocol version (=1) */    char *comment; /* Comment to show to user */    char *commentURL; /* URL for comment to show to user */    char *domain;  /* Domain for which this cookie is valid */    int port;	   /* Server port from which this cookie was given (usu. 80) */    char *PortList;/* List of ports for which cookie can be sent */    char *path;    /* Path prefix for which this cookie is valid */    int pathlen;   /* Length of the path */    int flags;	   /* Various flags */    time_t expires;/* The time when this cookie expires */    BOOL quoted;   /* Was a value quoted in the Set-Cookie header? */};typedef struct _cookie cookie;#define COOKIE_FLAG_SECURE 1	   /* If set, cookie requires secure links */#define COOKIE_FLAG_DISCARD 2	   /* If set, expire at end of session */#define COOKIE_FLAG_EXPIRES_SET 4  /* If set, an expiry date was set */#define COOKIE_FLAG_DOMAIN_SET 8   /* If set, an non-default domain was set */#define COOKIE_FLAG_PATH_SET 16    /* If set, an non-default path was set */struct _HTStream{  HTStreamClass * isa;};PRIVATE void MemAllocCopy ARGS3(	char **,	dest,	CONST char *,	start,	CONST char *,	end){    char *temp;    if (!(start && end) || (end <= start)) {	HTSACopy(dest, "");	return;    }    temp = (char *)calloc(1, ((end - start) + 1));    if (temp == NULL)	outofmem(__FILE__, "MemAllocCopy");    LYstrncpy(temp, start, (end - start));    HTSACopy(dest, temp);    FREE(temp);}PRIVATE cookie * newCookie NOARGS{    cookie *p = (cookie *)calloc(1, sizeof(cookie));    char lynxID[64];    if (p == NULL)	outofmem(__FILE__, "newCookie");    sprintf(lynxID, "%p", p);    StrAllocCopy(p->lynxID, lynxID);    p->port = 80;    return p;}PRIVATE void freeCookie ARGS1(	cookie *,	co){    if (co) {	FREE(co->lynxID);	FREE(co->name);	FREE(co->value);	FREE(co->comment);	FREE(co->commentURL);	FREE(co->domain);	FREE(co->path);	FREE(co->PortList);	FREE(co);    }}PRIVATE void LYCookieJar_free NOARGS{    HTList *dl = domain_list;    domain_entry *de = NULL;    HTList *cl = NULL, *next = NULL;    cookie *co = NULL;    while (dl) {	if ((de = dl->object) != NULL) {	    cl = de->cookie_list;	    while (cl) {		next = cl->next;		co = cl->object;		if (co) {		    HTList_removeObject(de->cookie_list, co);		    freeCookie(co);		}		cl = next;	    }	    FREE(de->domain);	    HTList_delete(de->cookie_list);	    de->cookie_list = NULL;	}	dl = dl->next;    }    if (dump_output_immediately) {	cl = cookie_list;	while (cl) {	    next = cl->next;	    co = cl->object;	    if (co) {		HTList_removeObject(cookie_list, co);		freeCookie(co);	    }	    cl = next;	}	HTList_delete(cookie_list);    }    cookie_list = NULL;    HTList_delete(domain_list);    domain_list = NULL;}/***  Compare two hostnames as specified in Section 2 of:**   http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-state-man-mec-02.txt**	- AK & FM*/PRIVATE BOOLEAN host_matches ARGS2(	CONST char *,	A,	CONST char *,	B){    /*     *	The following line will handle both numeric IP addresses and     *	FQDNs.	Do numeric addresses require special handling?     */    if (*B != '.' && !strcmp(A, B))	return YES;    /*     *	The following will pass a "dotted tail" match to "a.b.c.e"     *	as described in Section 2 of the -05 draft.     */    if (*B == '.') {	int diff = (strlen(A) - strlen(B));	if (diff > 0) {	    if (!strcmp((A + diff), B))		return YES;	}    }    return NO;}/***  Compare the current port with a port list as specified in Section 4.3 of:**   http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-state-man-mec-02.txt**	- FM*/PRIVATE BOOLEAN port_matches ARGS2(	int,		port,	CONST char *,	list){    CONST char *number = list;    if (!(number && isdigit(*number)))	return(FALSE);    while (*number != '\0') {	if (atoi(number) == port) {	    return(TRUE);	}	while (isdigit(*number)) {	    number++;	}	while (*number != '\0' && !isdigit(*number)) {	    number++;	}    }    return(FALSE);}/***  Store a cookie somewhere in the domain list. - AK & FM*/PRIVATE void store_cookie ARGS3(	cookie *,	co,	CONST char *,	hostname,	CONST char *,	path){    HTList *hl, *next;    cookie *c2;    time_t now = time(NULL);    int pos;    CONST char *ptr;    domain_entry *de = NULL;    BOOL Replacement = FALSE;    if (co == NULL)	return;    /*     *	Apply sanity checks.     *     *	Section 4.3.2, condition 1: The value for the Path attribute is     *	not a prefix of the request-URI.     */    if (strncmp(co->path, path, co->pathlen) != 0) {	if (TRACE)	    fprintf(stderr,	    "store_cookie: Rejecting because '%s' is not a prefix of '%s'.\n",		    co->path, path);	freeCookie(co);	co = NULL;	return;    }    /*     *	The next 4 conditions do NOT apply if the domain is still     *	the default of request-host.     */    if (strcmp(co->domain, hostname) != 0) {	/*	 *  The hostname does not contain a dot.	 */	if (strchr(hostname, '.') == NULL) {	    if (TRACE)		fprintf(stderr,			"store_cookie: Rejecting because '%s' has no dot.\n",			hostname);	    freeCookie(co);	    co = NULL;	    return;	}	/*	 *  Section 4.3.2, condition 2: The value for the Domain attribute	 *  contains no embedded dots or does not start with a dot.	 *  (A dot is embedded if it's neither the first nor last character.)	 *  Note that we added a lead dot ourselves if a domain attribute	 *  value otherwise qualified. - FM	 */	if (co->domain[0] != '.' || co->domain[1] == '\0') {	    if (TRACE)		fprintf(stderr,			"store_cookie: Rejecting domain '%s'.\n",			co->domain);	    freeCookie(co);	    co = NULL;	    return;	}	ptr = strchr((co->domain + 1), '.');	if (ptr == NULL || ptr[1] == '\0') {	    if (TRACE)		fprintf(stderr,			"store_cookie: Rejecting domain '%s'.\n",			co->domain);	    freeCookie(co);	    co = NULL;	    return;	}	/*	 *  Section 4.3.2, condition 3: The value for the request-host does	 *  not domain-match the Domain attribute.	 */	if (!host_matches(hostname, co->domain)) {	    if (TRACE)		fprintf(stderr,			"store_cookie: Rejecting domain '%s' for host '%s'.\n",			co->domain, hostname);	    freeCookie(co);	    co = NULL;	    return;	}	/*	 *  Section 4.3.2, condition 4: The request-host is an HDN (not IP	 *  address) and has the form HD, where D is the value of the Domain	 *  attribute, and H is a string that contains one or more dots.	 */	ptr = ((hostname + strlen(hostname)) - strlen(co->domain));	if (strchr(hostname, '.') < ptr) {	    char *msg = calloc(1,			       (strlen(co->domain) +				strlen(hostname) +				strlen(INVALID_COOKIE_DOMAIN_CONFIRMATION) +				1));	    sprintf(msg,		    INVALID_COOKIE_DOMAIN_CONFIRMATION,		    co->domain,		    hostname);	    if (!HTConfirm(msg)) {		if (TRACE) {		    fprintf(stderr,		       "store_cookie: Rejecting domain '%s' for host '%s'.\n",			    co->domain,			    hostname);		}		freeCookie(co);		co = NULL;		FREE(msg);		return;	    }	    FREE(msg);	}    }    /*     *	Ensure that the domain list exists.     */    if (domain_list == NULL) {	atexit(LYCookieJar_free);	domain_list = HTList_new();	total_cookies = 0;    }    /*     *	Look through domain_list to see if the cookie's domain     *	is already listed.     */    if (dump_output_immediately) { /* Non-interactive, can't respond */	if (cookie_list == NULL)	    cookie_list = HTList_new();    } else {	cookie_list = NULL;	for (hl = domain_list; hl != NULL; hl = hl->next) {	    de = (domain_entry *)hl->object;	    if ((de != NULL && de->domain != NULL) &&		!strcmp(co->domain, de->domain)) {		cookie_list = de->cookie_list;		break;	    }	}	if (hl == NULL) {	    /*	     *	Domain not found; add a new entry for this domain.	     */	    de = (domain_entry *)calloc(1, sizeof(domain_entry));	    if (de == NULL)		outofmem(__FILE__, "store_cookie");	    de->bv = QUERY_USER;	    cookie_list = de->cookie_list = HTList_new();	    StrAllocCopy(de->domain, co->domain);	    HTList_addObject(domain_list, de);	}    }    /*     *	Loop over the cookie list, deleting expired and matching cookies.     */    hl = cookie_list;    pos = 0;    while (hl) {	c2 = (cookie *)hl->object;	next = hl->next;	/*	 *  Check if this cookie has expired.	 */	if ((c2 != NULL) &&	    (c2->flags & COOKIE_FLAG_EXPIRES_SET) &&	    c2->expires < now) {	    HTList_removeObject(cookie_list, c2);	    freeCookie(c2);	    c2 = NULL;	    total_cookies--;	/*	 *  Check if this cookie matches the one we're inserting.	 */	} else if ((c2) &&		   !strcmp(co->domain, c2->domain) &&		   !strcmp(co->path, c2->path) &&		   !strcmp(co->name, c2->name)) {	    HTList_removeObject(cookie_list, c2);	    freeCookie(c2);	    c2 = NULL;	    total_cookies--;	    Replacement = TRUE;	} else if ((c2) && (c2->pathlen) > (co->pathlen)) {	    pos++;	}	hl = next;    }    /*     *	Don't bother to add the cookie if it's already expired.     */    if ((co->flags & COOKIE_FLAG_EXPIRES_SET) && co->expires < now) {	freeCookie(co);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -