"Fossies" - the Fresh Open Source Software Archive

Member "links-1.03/cookies.c" (20 Sep 2011, 7326 Bytes) of archive /linux/www/links-1.03.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cookies.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8_vs_1.03.

    1 #include "links.h"
    2 
    3 #define ACCEPT_NONE 0
    4 #define ACCEPT_ASK  1
    5 #define ACCEPT_ALL  2
    6 
    7 int accept_cookies = ACCEPT_ALL;
    8 
    9 tcount cookie_id = 0;
   10 
   11 struct cookie {
   12     struct cookie *next;
   13     struct cookie *prev;
   14     unsigned char *name, *value;
   15     unsigned char *server;
   16     unsigned char *path, *domain;
   17     time_t expires; /* zero means undefined */
   18     int secure;
   19     int id;
   20 };
   21 
   22 struct list_head cookies = { &cookies, &cookies };
   23 
   24 struct c_domain {
   25     struct c_domain *next;
   26     struct c_domain *prev;
   27     unsigned char domain[1];
   28 };
   29 
   30 struct list_head c_domains = { &c_domains, &c_domains };
   31 
   32 struct c_server {
   33     struct c_server *next;
   34     struct c_server *prev;
   35     int accept;
   36     unsigned char server[1];
   37 };
   38 
   39 struct list_head c_servers = { &c_servers, &c_servers };
   40 
   41 void accept_cookie(struct cookie *);
   42 void delete_cookie(struct cookie *);
   43 
   44 void free_cookie(struct cookie *c)
   45 {
   46     mem_free(c->name);
   47     if (c->value) mem_free(c->value);
   48     if (c->server) mem_free(c->server);
   49     if (c->path) mem_free(c->path);
   50     if (c->domain) mem_free(c->domain);
   51 }
   52 
   53 int check_domain_security(unsigned char *server, unsigned char *domain)
   54 {
   55     size_t i, j, dl;
   56     int nd;
   57     if (domain[0] == '.') domain++;
   58     dl = strlen(domain);
   59     if (dl > strlen(server)) return 1;
   60     for (i = strlen(server) - dl, j = 0; server[i]; i++, j++)
   61         if (upcase(server[i]) != upcase(domain[j])) return 1;
   62     nd = 2;
   63     if (dl > 4 && domain[dl - 4] == '.') {
   64         unsigned char *tld[] = { "com", "edu", "net", "org", "gov", "mil", "int", NULL };
   65         for (i = 0; tld[i]; i++) if (!casecmp(tld[i], &domain[dl - 3], 3)) {
   66             nd = 1;
   67             break;
   68         }
   69     }
   70     for (i = 0; domain[i]; i++) if (domain[i] == '.') if (!--nd) break;
   71     if (nd > 0) return 1;
   72     return 0;
   73 }
   74 
   75 int set_cookie(struct terminal *term, unsigned char *url, unsigned char *str)
   76 {
   77     int noval = 0;
   78     struct cookie *cookie;
   79     struct c_server *cs;
   80     unsigned char *p, *q, *s, *server, *date;
   81     if (accept_cookies == ACCEPT_NONE) return 0;
   82     for (p = str; *p != ';' && *p; p++) /*if (WHITECHAR(*p)) return 0*/;
   83     for (q = str; *q != '='; q++) if (!*q || q >= p) {
   84         noval = 1;
   85         break;
   86     }
   87     if (str == q || q + 1 == p) return 0;
   88     cookie = mem_alloc(sizeof(struct cookie));
   89     server = get_host_name(url);
   90     cookie->name = memacpy(str, q - str);
   91     cookie->value = !noval ? memacpy(q + 1, p - q - 1) : NULL;
   92     cookie->server = stracpy(server);
   93     date = parse_header_param(str, "expires");
   94     if (date) {
   95         cookie->expires = parse_http_date(date);
   96         /* kdo tohle napsal a proc ?? */
   97         /*if (! cookie->expires) cookie->expires++;*/ /* no harm and we can use zero then */
   98         mem_free(date);
   99     } else
  100         cookie->expires = 0;
  101     if (!(cookie->path = parse_header_param(str, "path"))) {
  102         /*unsigned char *w;*/
  103         cookie->path = stracpy("/");
  104         /*
  105         add_to_strn(&cookie->path, document);
  106         for (w = cookie->path; *w; w++) if (end_of_dir(*w)) {
  107             *w = 0;
  108             break;
  109         }
  110         for (w = cookie->path + strlen(cookie->path) - 1; w >= cookie->path; w--)
  111             if (*w == '/') {
  112                 w[1] = 0;
  113                 break;
  114             }
  115         */
  116     } else {
  117         if (cookie->path[0] != '/') {
  118             add_to_strn(&cookie->path, "x");
  119             memmove(cookie->path + 1, cookie->path, strlen(cookie->path) - 1);
  120             cookie->path[0] = '/';
  121         }
  122     }
  123     if (!(cookie->domain = parse_header_param(str, "domain"))) cookie->domain = stracpy(server);
  124     if (cookie->domain[0] == '.') memmove(cookie->domain, cookie->domain + 1, strlen(cookie->domain));
  125     if ((s = parse_header_param(str, "secure"))) {
  126         cookie->secure = 1;
  127         mem_free(s);
  128     } else cookie->secure = 0;
  129     if (check_domain_security(server, cookie->domain)) {
  130         mem_free(cookie->domain);
  131         cookie->domain = stracpy(server);
  132     }
  133     cookie->id = cookie_id++;
  134     foreach (cs, c_servers) if (!strcasecmp(cs->server, server)) {
  135         if (cs->accept) goto ok;
  136         else {
  137             free_cookie(cookie);
  138             mem_free(cookie);
  139             mem_free(server);
  140             return 0;
  141         }
  142     }
  143     if (accept_cookies != ACCEPT_ALL) {
  144         free_cookie(cookie);
  145         mem_free(cookie);
  146         mem_free(server);
  147         return 1;
  148     }
  149     ok:
  150     accept_cookie(cookie);
  151     mem_free(server);
  152     return 0;
  153 }
  154 
  155 void accept_cookie(struct cookie *c)
  156 {
  157     struct c_domain *cd;
  158     struct cookie *d, *e;
  159     foreach(d, cookies) if (!strcasecmp(d->name, c->name) && !strcasecmp(d->domain, c->domain)) {
  160         e = d;
  161         d = d->prev;
  162         del_from_list(e);
  163         free_cookie(e);
  164         mem_free(e);
  165     }
  166     if (c->value && !strcasecmp(c->value, "deleted")) {
  167         free_cookie(c);
  168         mem_free(c);
  169         return;
  170     }
  171     add_to_list(cookies, c);
  172     foreach(cd, c_domains) if (!strcasecmp(cd->domain, c->domain)) return;
  173     cd = mem_alloc(sizeof(struct c_domain) + strlen(c->domain) + 1);
  174     strcpy(cd->domain, c->domain);
  175     add_to_list(c_domains, cd);
  176 }
  177 
  178 void delete_cookie(struct cookie *c)
  179 {
  180     struct c_domain *cd;
  181     struct cookie *d;
  182     foreach(d, cookies) if (!strcasecmp(d->domain, c->domain)) goto x;
  183     foreach(cd, c_domains) if (!strcasecmp(cd->domain, c->domain)) {
  184         del_from_list(cd);
  185         mem_free(cd);
  186         break;
  187     }
  188     x:
  189     del_from_list(c);
  190     free_cookie(c);
  191     mem_free(c);
  192 }
  193 
  194 struct cookie *find_cookie_id(void *idp)
  195 {
  196     int id = (int)idp;
  197     struct cookie *c;
  198     foreach(c, cookies) if (c->id == id) return c;
  199     return NULL;
  200 }
  201 
  202 void reject_cookie(void *idp)
  203 {
  204     struct cookie *c;
  205     if (!(c = find_cookie_id(idp))) return;
  206     delete_cookie(c);
  207 }
  208 
  209 void cookie_default(void *idp, int a)
  210 {
  211     struct cookie *c;
  212     struct c_server *s;
  213     if (!(c = find_cookie_id(idp))) return;
  214     foreach(s, c_servers) if (!strcasecmp(s->server, c->server)) goto found;
  215     s = mem_alloc(sizeof(struct c_server) + strlen(c->server) + 1);
  216     strcpy(s->server, c->server);
  217     add_to_list(c_servers, s);
  218     found:
  219     s->accept = a;
  220 }
  221 
  222 void accept_cookie_always(void *idp)
  223 {
  224     cookie_default(idp, 1);
  225 }
  226 
  227 void accept_cookie_never(void *idp)
  228 {
  229     cookie_default(idp, 0);
  230     reject_cookie(idp);
  231 }
  232 
  233 int is_in_domain(unsigned char *d, unsigned char *s)
  234 {
  235     int dl = strlen(d);
  236     int sl = strlen(s);
  237     if (dl > sl) return 0;
  238     if (dl == sl) return !strcasecmp(d, s);
  239     if (s[sl - dl - 1] != '.') return 0;
  240     return !casecmp(d, s + sl - dl, dl);
  241 }
  242 
  243 int is_path_prefix(unsigned char *d, unsigned char *s)
  244 {
  245     int dl = strlen(d);
  246     int sl = strlen(s);
  247     if (!dl) return 1;
  248     if (dl > sl) return 0;
  249     if (memcmp(d, s, dl)) return 0;
  250     return d[dl - 1] == '/' || !s[dl] || s[dl] == '/' || s[dl] == POST_CHAR || s[dl] == '?' || s[dl] == '&';
  251 }
  252 
  253 int cookie_expired(struct cookie *c)    /* parse_http_date is broken */
  254 {
  255     return 0 && (c->expires && c->expires < time(NULL));
  256 }
  257 
  258 void send_cookies(unsigned char **s, int *l, unsigned char *url)
  259 {
  260     int nc = 0;
  261     struct c_domain *cd;
  262     struct cookie *c, *d;
  263     unsigned char *server = get_host_name(url);
  264     unsigned char *data = get_url_data(url);
  265     if (data > url) data--;
  266     foreach (cd, c_domains) if (is_in_domain(cd->domain, server)) goto ok;
  267     mem_free(server);
  268     return;
  269     ok:
  270     foreach (c, cookies) if (is_in_domain(c->domain, server)) if (is_path_prefix(c->path, data)) {
  271         if (cookie_expired(c)) {
  272             d = c;
  273             c = c->prev;
  274             del_from_list(d);
  275             free_cookie(d);
  276             mem_free(d);
  277             continue;
  278         }
  279         if (c->secure && casecmp(url, "https://", 8)) continue;
  280         if (!nc) add_to_str(s, l, "Cookie: "), nc = 1;
  281         else add_to_str(s, l, "; ");
  282         add_to_str(s, l, c->name);
  283         if (c->value) {
  284             add_to_str(s, l, "=");
  285             add_to_str(s, l, c->value);
  286         }
  287     }
  288     if (nc) add_to_str(s, l, "\r\n");
  289     mem_free(server);
  290 }
  291 
  292 void init_cookies()
  293 {
  294     /* !!! FIXME: read cookies */
  295 }
  296 
  297 void cleanup_cookies()
  298 {
  299     struct cookie *c;
  300     free_list(c_domains);
  301     /* !!! FIXME: save cookies */
  302     foreach (c, cookies) free_cookie(c);
  303     free_list(cookies);
  304 }
  305