[BACK]Return to cookie.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ftp

Annotation of src/usr.bin/ftp/cookie.c, Revision 1.10

1.10    ! naddy       1: /*     $OpenBSD: cookie.c,v 1.9 2019/05/16 12:44:17 florian Exp $      */
1.5       martynas    2:
1.1       pyr         3: /*
                      4:  * Copyright (c) 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
1.6       deraadt    19: #ifndef NOSSL
1.5       martynas   20:
1.1       pyr        21: #include <sys/types.h>
                     22: #include <sys/queue.h>
                     23:
                     24: #include <err.h>
                     25: #include <errno.h>
                     26: #include <fnmatch.h>
                     27: #include <stdio.h>
                     28: #include <string.h>
                     29: #include <stdlib.h>
                     30: #include <time.h>
                     31:
                     32: #include "ftp_var.h"
                     33:
                     34: struct cookie {
                     35:        TAILQ_ENTRY(cookie)      entry;
                     36:        TAILQ_ENTRY(cookie)      tempentry;
                     37:        u_int8_t                 flags;
                     38: #define F_SECURE                0x01
                     39: #define F_TAILMATCH             0x02
                     40: #define F_NOEXPIRY              0x04
                     41: #define F_MATCHPATH             0x08
                     42:        time_t                   expires;
                     43:        char                    *domain;
                     44:        char                    *path;
                     45:        char                    *key;
                     46:        char                    *val;
                     47: };
                     48: TAILQ_HEAD(cookiejar, cookie);
                     49:
                     50: typedef enum {
                     51:        DOMAIN = 0, TAILMATCH = 1, PATH = 2, SECURE = 3,
1.7       krw        52:        EXPIRES = 4, NAME = 5, VALUE = 6, DONE = 7
1.1       pyr        53: } field_t;
                     54:
                     55: static struct cookiejar jar;
                     56:
                     57: void
                     58: cookie_load(void)
                     59: {
                     60:        field_t          field;
                     61:        time_t           date;
                     62:        char            *line;
1.10    ! naddy      63:        char            *lbuf = NULL;
        !            64:        size_t           lbufsize = 0;
1.1       pyr        65:        char            *param;
                     66:        const char      *estr;
                     67:        FILE            *fp;
                     68:        struct cookie   *ck;
                     69:
                     70:        if (cookiefile == NULL)
                     71:                return;
                     72:
                     73:        TAILQ_INIT(&jar);
                     74:        fp = fopen(cookiefile, "r");
                     75:        if (fp == NULL)
                     76:                err(1, "cannot open cookie file %s", cookiefile);
                     77:        date = time(NULL);
1.10    ! naddy      78:        while (getline(&lbuf, &lbufsize, fp) != -1) {
        !            79:                line = lbuf;
        !            80:                line[strcspn(line, "\r\n")] = '\0';
1.1       pyr        81:
                     82:                line += strspn(line, " \t");
                     83:                if ((*line == '#') || (*line == '\0')) {
                     84:                        continue;
                     85:                }
                     86:                field = DOMAIN;
                     87:                ck = calloc(1, sizeof(*ck));
                     88:                if (ck == NULL)
                     89:                        err(1, NULL);
                     90:                while ((param = strsep(&line, "\t")) != NULL) {
                     91:                        switch (field) {
                     92:                        case DOMAIN:
                     93:                                if (*param == '.') {
                     94:                                        if (asprintf(&ck->domain,
                     95:                                            "*%s", param) == -1)
                     96:                                                err(1, NULL);
                     97:                                } else {
                     98:                                        ck->domain = strdup(param);
                     99:                                        if (ck->domain == NULL)
                    100:                                                err(1, NULL);
                    101:                                }
                    102:                                break;
                    103:                        case TAILMATCH:
                    104:                                if (strcasecmp(param, "TRUE") == 0) {
                    105:                                        ck->flags |= F_TAILMATCH;
                    106:                                } else if (strcasecmp(param, "FALSE") != 0) {
                    107:                                        errx(1, "invalid cookie file");
                    108:                                }
                    109:                                break;
                    110:                        case PATH:
                    111:                                if (strcmp(param, "/") != 0) {
                    112:                                        ck->flags |= F_MATCHPATH;
                    113:                                        if (asprintf(&ck->path,
                    114:                                            "%s*", param) == -1)
                    115:                                                err(1, NULL);
                    116:                                }
                    117:                                break;
                    118:                        case SECURE:
                    119:                                if (strcasecmp(param, "TRUE") == 0) {
                    120:                                        ck->flags |= F_SECURE;
                    121:                                } else if (strcasecmp(param, "FALSE") != 0) {
                    122:                                        errx(1, "invalid cookie file");
                    123:                                }
                    124:                                break;
                    125:                        case EXPIRES:
                    126:                                /*
                    127:                                 * rely on sizeof(time_t) being 4
                    128:                                 */
                    129:                                ck->expires = strtonum(param, 0,
1.4       cloder    130:                                    INT_MAX, &estr);
1.1       pyr       131:                                if (estr) {
                    132:                                        if (errno == ERANGE)
                    133:                                                ck->flags |= F_NOEXPIRY;
                    134:                                        else
                    135:                                                errx(1, "invalid cookie file");
                    136:                                }
                    137:                                break;
                    138:                        case NAME:
                    139:                                ck->key = strdup(param);
                    140:                                if (ck->key == NULL)
                    141:                                        err(1, NULL);
                    142:                                break;
                    143:                        case VALUE:
                    144:                                ck->val = strdup(param);
                    145:                                if (ck->val == NULL)
                    146:                                        err(1, NULL);
                    147:                                break;
                    148:                        case DONE:
                    149:                                errx(1, "invalid cookie file");
                    150:                                break;
                    151:                        }
                    152:                        field++;
                    153:                }
                    154:                if (field != DONE)
                    155:                        errx(1, "invalid cookie file");
                    156:                if (ck->expires < date && !(ck->flags & F_NOEXPIRY)) {
                    157:                        free(ck->val);
                    158:                        free(ck->key);
                    159:                        free(ck->path);
                    160:                        free(ck->domain);
                    161:                        free(ck);
                    162:                } else
                    163:                        TAILQ_INSERT_TAIL(&jar, ck, entry);
1.7       krw       164:        }
1.1       pyr       165:        free(lbuf);
                    166:        fclose(fp);
                    167: }
                    168:
                    169: void
                    170: cookie_get(const char *domain, const char *path, int secure, char **pstr)
                    171: {
                    172:        size_t           len;
                    173:        size_t           headlen;
                    174:        char            *head;
                    175:        char            *str;
                    176:        struct cookie   *ck;
                    177:        struct cookiejar tempjar;
                    178:
                    179:        *pstr = NULL;
                    180:
                    181:        if (cookiefile == NULL)
                    182:                return;
                    183:
                    184:        TAILQ_INIT(&tempjar);
                    185:        len = strlen("Cookie\r\n");
                    186:
                    187:        TAILQ_FOREACH(ck, &jar, entry) {
                    188:                if (fnmatch(ck->domain, domain, 0) == 0 &&
                    189:                    (secure || !(ck->flags & F_SECURE))) {
                    190:
                    191:                        if (ck->flags & F_MATCHPATH &&
                    192:                            fnmatch(ck->path, path, 0) != 0)
                    193:                                continue;
                    194:
                    195:                        len += strlen(ck->key) + strlen(ck->val) +
                    196:                            strlen("; =");
                    197:                        TAILQ_INSERT_TAIL(&tempjar, ck, tempentry);
                    198:                }
                    199:        }
                    200:        if (TAILQ_EMPTY(&tempjar))
                    201:                return;
                    202:        len += 1;
                    203:        str = malloc(len);
                    204:        if (str == NULL)
                    205:                err(1, NULL);
                    206:
                    207:        (void)strlcpy(str, "Cookie:", len);
                    208:        TAILQ_FOREACH(ck, &tempjar, tempentry) {
                    209:                head = str + strlen(str);
                    210:                headlen = len - strlen(str);
                    211:
                    212:                snprintf(head, headlen, "%s %s=%s",
                    213:                    (ck == TAILQ_FIRST(&tempjar))? "" : ";", ck->key, ck->val);
                    214:        }
                    215:        if (strlcat(str, "\r\n", len) >= len)
                    216:                errx(1, "cookie header truncated");
                    217:        *pstr = str;
                    218: }
                    219:
1.3       martynas  220: #endif /* !SMALL */
1.5       martynas  221: