📄 cookies.c
字号:
len--; ret = g_strndup(path, len + 1); } else { ret = g_strdup("/"); } return ret;}/* * Set the value corresponding to the cookie string */void a_Cookies_set(GList *cookie_strings, const DilloUrl *set_url){ CookieControlAction action; if (disabled) return; action = Cookies_control_check(set_url); if (action == COOKIE_DENY) { DEBUG_MSG(5, "Cookies: denied SET for %s\n", URL_HOST_(set_url)); return; } while (cookie_strings != NULL ) { char *cookie_string = (char *)cookie_strings->data; CookieData_t *cookie = Cookies_parse_string(cookie_string); GList *domain_cookies; if (cookie == NULL) { DEBUG_MSG(8, "Malformed cookie field %s\n", cookie_string); return; } if (action == COOKIE_ACCEPT_SESSION) cookie->session_only = TRUE; if (cookie->ports) { GList *first = g_list_first(cookie->ports); if (GPOINTER_TO_INT(first->data) == -1) { /* Now set it to the port we are accessing */ cookie->ports = g_list_insert(cookie->ports, GINT_TO_POINTER(URL_PORT(set_url)), 0); } } if (Cookies_validate_domain(cookie, set_url)) { if (cookie->path == NULL) { cookie->path = Cookies_strip_path(URL_PATH_(set_url)); } domain_cookies = (GList *)g_hash_table_lookup(cookies, cookie->domain); if (domain_cookies != NULL) { GList *list_temp = g_list_first(domain_cookies); CookieData_t *old_cookie; for (; list_temp != NULL; list_temp = g_list_next(list_temp)) { old_cookie = list_temp->data; if (Cookies_equals(cookie, old_cookie)) { DEBUG_MSG(4, "Found old cookie %s, replacing with new %s\n", old_cookie->name, cookie->name); domain_cookies = g_list_remove(domain_cookies, old_cookie); if (domain_cookies == NULL) { Cookies_free_domain(old_cookie->domain); } else { g_hash_table_insert(cookies, old_cookie->domain, g_list_first(domain_cookies)); } Cookies_free_cookie(old_cookie); break; } } } /* If this is non-expiring, add it */ if (g_list_length(domain_cookies) < 20 && (cookie->session_only || cookie->expires_at > time(NULL))) { DEBUG_MSG(5, "Adding cookie '%s' for %s\n", cookie->name, cookie->domain); domain_cookies = g_list_append(domain_cookies, cookie); if (!g_hash_table_lookup(cookies, cookie->domain)) g_hash_table_insert(cookies, g_strdup(cookie->domain), domain_cookies); } else { DEBUG_MSG(5, "Removing cookie '%s'\n", cookie->name); Cookies_free_cookie(cookie); } } else { DEBUG_MSG(5, "Rejecting cookie for %s from %s:\n", cookie->domain, URL_STR_(set_url)); Cookies_free_cookie(cookie); } cookie_strings = g_list_next(cookie_strings); }}/* * Used by g_list_insert_sorted() to sort the cookies by most specific path */static gint Cookies_compare(gconstpointer a, gconstpointer b){ return strcmp(((CookieData_t *) b)->path, ((CookieData_t *) a)->path);}/* * Return a string that contains all relevant cookies as headers. */char *a_Cookies_get(const DilloUrl *request_url){ char *domain_string, *q, *str, *path; CookieControlAction action; CookieData_t *cookie; GList *matching_cookies = NULL; GList *domain_cookie; gboolean is_ssl; gboolean cookies_removed; GString *cookie_gstring; if (disabled) return g_strdup(""); action = Cookies_control_check(request_url); if (action == COOKIE_DENY) { DEBUG_MSG(5, "Cookies: denied GET for %s\n", URL_HOST_(request_url)); return g_strdup(""); } path = Cookies_strip_path(URL_PATH_(request_url)); /* Check if the protocol is secure or not */ is_ssl = (!g_strcasecmp(URL_SCHEME(request_url), "https")); for (domain_string = (char *) URL_HOST(request_url); domain_string != NULL && *domain_string; domain_string = strchr(domain_string+1, '.')) { domain_cookie = g_hash_table_lookup(cookies, domain_string); cookies_removed = FALSE; for (domain_cookie = g_list_first(domain_cookie); domain_cookie != NULL; domain_cookie = g_list_next(domain_cookie)) { cookie = (CookieData_t*)domain_cookie->data; /* Insecure cookies matches both secure and insecure urls, secure cookies matches only secure urls */ if (!cookie->secure || (cookie->secure == is_ssl)) { /* Check that the cookie path is a subpath of the current path */ if (!(strncmp(cookie->path, path, strlen(cookie->path)))) { if (!cookie->session_only && cookie->expires_at < time(NULL)) { /* Expired cookies die here. RIP */ DEBUG_MSG(4, "Cookie %s expiring\n", cookie->name); domain_cookie = g_list_remove(domain_cookie, cookie); Cookies_free_cookie(cookie); cookies_removed = TRUE; } else { /* Check if the port of the request URL matches any * of those set in the cookie */ if (cookie->ports) { GList *list; int port = URL_PORT(request_url); for (list = g_list_first(cookie->ports); list; list = g_list_next(list)) { if (GPOINTER_TO_INT(list->data) == port) { matching_cookies = g_list_insert_sorted(matching_cookies, cookie, Cookies_compare); break; } } } else { matching_cookies = g_list_insert_sorted(matching_cookies, cookie, Cookies_compare); } } } } } if (cookies_removed) { if (domain_cookie == NULL) { Cookies_free_domain(domain_string); } else { g_hash_table_insert(cookies, domain_string, g_list_first(domain_cookie)); } } } /* Found the cookies, now make the string */ cookie_gstring = g_string_new(""); if (matching_cookies != NULL) { CookieData_t *first_cookie = (CookieData_t*)matching_cookies->data; g_string_sprintfa(cookie_gstring, "Cookie: "); if (first_cookie->version != 0) { g_string_sprintfa(cookie_gstring, "\"%d\"; ", first_cookie->version); } for (; matching_cookies != NULL; matching_cookies = g_list_next(matching_cookies)) { cookie = (CookieData_t *) matching_cookies->data; q = (cookie->version == 0 ? "" : "\""); g_string_sprintfa(cookie_gstring, "%s=%s%s%s", cookie->name, q, cookie->value, q); if (cookie->path) g_string_sprintfa(cookie_gstring, "; $Path=%s%s%s", q, cookie->path, q); if (cookie->domain) g_string_sprintfa(cookie_gstring, "; $Domain=%s%s%s", q, cookie->domain, q); if (cookie->ports) { char *ports_str = Cookies_build_ports_str(cookie); g_string_sprintfa(cookie_gstring, "; $Port=%s", ports_str); g_free(ports_str); } if (g_list_next(matching_cookies) != NULL) g_string_append(cookie_gstring, "; "); else g_string_append(cookie_gstring, "\r\n"); } DEBUG_MSG(4, "Final cookie string: %s", cookie_gstring->str); } g_free(path); str = cookie_gstring->str; g_string_free(cookie_gstring, FALSE); return str;}/* ------------------------------------------------------------- * Access control routines * ------------------------------------------------------------- *//* * Get the cookie control rules */static void Cookie_control_init(){ CookieControl cc; FILE *stream; char *filename; char line[LINE_MAXLEN]; char domain[LINE_MAXLEN]; char rule[LINE_MAXLEN]; int i, j; /* Get a file pointer */ filename = a_Misc_prepend_user_home(".dillo/cookiesrc"); stream = Cookies_fopen(filename, "DEFAULT DENY\n"); g_free(filename); if (!stream) return; /* Get all lines in the file */ while (!feof(stream)) { line[0] = '\0'; fgets(line, LINE_MAXLEN, stream); /* Remove leading and trailing whitespaces */ g_strstrip(line); if (line[0] != '\0' && line[0] != '#') { i = 0; j = 0; /* Get the domain */ while (!isspace(line[i])) domain[j++] = line[i++]; domain[j] = '\0'; /* Skip past whitespaces */ i++; while (isspace(line[i])) i++; /* Get the rule */ j = 0; while (line[i] != '\0' && !isspace(line[i])) rule[j++] = line[i++]; rule[j] = '\0'; if (g_strcasecmp(rule, "ACCEPT") == 0) cc.action = COOKIE_ACCEPT; else if (g_strcasecmp(rule, "ACCEPT_SESSION") == 0) cc.action = COOKIE_ACCEPT_SESSION; else if (g_strcasecmp(rule, "DENY") == 0) cc.action = COOKIE_DENY; else { g_print("Cookies: rule '%s' for domain '%s' is not recognised.\n", rule, domain); continue; } cc.domain = g_strdup(domain); if (g_strcasecmp(cc.domain, "DEFAULT") == 0) { /* Set the default action */ default_action = cc.action; g_free(cc.domain); } else { a_List_add(ccontrol, num_ccontrol, num_ccontrol_max); ccontrol[num_ccontrol++] = cc; } } } fclose(stream);}/* * Check the rules for an appropriate action for this domain */static CookieControlAction Cookies_control_check_domain(const char *domain){ int i, diff; for (i = 0; i < num_ccontrol; i++) { if (ccontrol[i].domain[0] == '.') { diff = strlen(domain) - strlen(ccontrol[i].domain); if (diff >= 0) { if (g_strcasecmp(domain + diff, ccontrol[i].domain) != 0) continue; } else { continue; } } else { if (g_strcasecmp(domain, ccontrol[i].domain) != 0) continue; } /* If we got here we have a match */ return( ccontrol[i].action ); } return default_action;}/* * Same as the above except it takes an URL */static CookieControlAction Cookies_control_check(const DilloUrl *url){ return Cookies_control_check_domain(URL_HOST(url));}#endif /* !DISABLE_COOKIES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -