aboutsummaryrefslogtreecommitdiff
path: root/gencookie.c
blob: 9a71b3e421eface26bce9d2fd11d995e61c556c2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#define _POSIX_C_SOURCE 200809L

#include "jwt.h"
#include <cjson/cJSON.h>
#include <libweb/http.h>
#include <sodium.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <time.h>

char *gencookie(const char *const name, const char *const key)
{
    char *ret = NULL, *sname = NULL, *c = NULL, *jwt = NULL;
    unsigned char dkey[crypto_auth_hmacsha256_KEYBYTES];
    size_t len;
    cJSON *j = NULL;
    time_t t = time(NULL);
    struct tm tm;

    if (t == (time_t)-1)
    {
        fprintf(stderr, "%s: time(2): %s\n", __func__, strerror(errno));
        goto end;
    }

    /* Set 5-year lifetime for cookies. */
    t += 5 * 365 * 24 * 60 * 60;

    if (!localtime_r(&t, &tm))
    {
        fprintf(stderr, "%s: localtime_r(3): %s\n", __func__, strerror(errno));
        goto end;
    }
    else if (!(j = cJSON_CreateObject()))
    {
        fprintf(stderr, "%s: cJSON_CreateObject failed\n", __func__);
        goto end;
    }
    else if (!cJSON_AddStringToObject(j, "name", name))
    {
        fprintf(stderr, "%s: cJSON_AddStringToObject failed\n", __func__);
        goto end;
    }
    else if (sodium_hex2bin(dkey, sizeof dkey, key, strlen(key), NULL, &len,
        NULL))
    {
        fprintf(stderr, "%s: sodium_hex2bin failed\n", __func__);
        goto end;
    }
    else if (!(jwt = jwt_encode(j, dkey, sizeof dkey)))
    {
        fprintf(stderr, "%s: jwt_encode failed\n", __func__);
        goto end;
    }
    else if (!(c = http_cookie_create(name, jwt, &tm)))
    {
        fprintf(stderr, "%s: http_cookie_create failed\n", __func__);
        goto end;
    }

    ret = c;

end:
    if (!ret)
        free(c);

    free(jwt);
    free(sname);
    cJSON_Delete(j);
    return ret;
}