bincookie v0.1.7
A library to parse Apple's binarycookies format.
Loading...
Searching...
No Matches
bincookie.h
Go to the documentation of this file.
1
8#ifndef _BINCOOKIE_H
9#define _BINCOOKIE_H
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
16// https://github.com/nodejs/http-parser/blob/master/http_parser.h#L32
17#include <sys/types.h>
18#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER < 1600) && \
19 !defined(__WINE__)
20#include <BaseTsd.h>
21#include <stddef.h>
22typedef unsigned __int32 uint32_t;
23typedef unsigned __int8 bool;
24#else
25#include <stdbool.h>
26#include <stdint.h>
27#endif
28#include <errno.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <time.h>
34
37
40#define bincookie_is_secure(cookie_ptr) (cookie_ptr->flags & secure)
42
45#define bincookie_domain_access_full(cookie_ptr) \
46 (((char *)cookie_ptr + cookie_ptr->domain_offset)[0] == '.')
48
51#define bincookie_iter_state_init(s) \
52 s.page_offset = 0; \
53 s.page_index = 0;
55
58#define bincookie_domain(c) ((char *)c + c->domain_offset)
60
63#define bincookie_path(c) \
64 ((char *)c + c->path_offset)
67
70#define bincookie_name(c) \
71 ((char *)c + c->name_offset)
74
77#define bincookie_value(c) ((char *)c + c->value_offset)
79#define APPLE_EPOCH_OFFSET 978307200
81
84#define bincookie_expiration_time(c) \
85 (c->expiry_date_epoch + APPLE_EPOCH_OFFSET)
87
90#define bincookie_creation_time(c) \
91 (c->create_date_epoch + APPLE_EPOCH_OFFSET)
94
96typedef enum {
97 secure = 1,
98 http_only = 1 << 2,
100
102typedef struct {
103 uint32_t page_offset;
104 uint32_t page_index;
106
108typedef struct {
109 uint32_t size;
110 unsigned char unk1[4];
112 unsigned char unk2[4];
113
114 uint32_t domain_offset;
115 uint32_t name_offset;
116 uint32_t path_offset;
117 uint32_t value_offset;
119 unsigned char unk[8];
120
124
126typedef struct {
127 unsigned char unk1[4];
129 uint32_t num_cookies;
130 uint32_t cookie_offsets[];
132
134typedef struct {
135 unsigned char magic[4];
136 uint32_t num_pages;
137 uint32_t page_sizes[];
139
141
145static inline bincookie_t *const bincookie_init_file(FILE *fin) {
146 const long last_pos = ftell(fin);
147 rewind(fin);
148 char magic[4];
149 bincookie_t *cook = NULL;
150 size_t read = fread(magic, sizeof(magic), 1, fin);
151 bool is_cook = magic[0] == 'c' && magic[1] == 'o' && magic[2] == 'o' && magic[3] == 'k';
152 if (read != 1 || !is_cook) {
153 errno = EIO;
154 goto done;
155 }
156 // Read entire file
157 fseek(fin, 0, SEEK_END);
158 size_t num_bytes = (size_t)ftell(fin);
159 cook = (bincookie_t *)malloc(num_bytes);
160 // LCOV_EXCL_START
161 if (cook == NULL) {
162 goto done;
163 } // LCOV_EXCL_STOP
164 memset(cook, 0, num_bytes);
165 rewind(fin);
166 // LCOV_EXCL_START
167 if (fread(cook, num_bytes, 1, fin) != 1) {
168 free(cook);
169 cook = NULL;
170 goto done;
171 } // LCOV_EXCL_STOP
172 cook->num_pages = __builtin_bswap32(cook->num_pages);
173 // Fix page size numbers
174 for (uint32_t i = 0; i < cook->num_pages; i++) {
175 *(cook->page_sizes + i) = __builtin_bswap32(*(cook->page_sizes + i));
176 }
177done:
178 fseek(fin, last_pos, SEEK_SET);
179 return cook;
180}
182
186static inline bincookie_t *const bincookie_init_path(const char *file_path) {
187 FILE *binary_file = fopen(file_path, "rb");
188 if (!binary_file) {
189 return NULL;
190 }
191 bincookie_t *ret = bincookie_init_file(binary_file);
192 fclose(binary_file);
193 return ret;
194}
196
201static inline bincookie_page_t *const bincookie_iter_pages(const bincookie_t *bc,
202 bincookie_iter_state_t *const state) {
203 if (state->page_offset == 0) {
204 state->page_offset = (uint32_t)(4 + sizeof(uint32_t) + (sizeof(uint32_t) * bc->num_pages));
205 }
206 if (state->page_index < bc->num_pages) {
207 bincookie_page_t *page = (bincookie_page_t *)((char *)bc + state->page_offset);
208 state->page_offset += bc->page_sizes[state->page_index];
209 state->page_index++;
210 return page;
211 }
212 return NULL;
213}
215
221 unsigned int *i) {
222 if (*i < page->num_cookies) {
223 bincookie_cookie_t *ptr = (bincookie_cookie_t *)((char *)page + page->cookie_offsets[*i]);
224 (*i)++;
225 return ptr;
226 }
227 return NULL;
228}
229
230#ifdef __cplusplus
231}
232#endif
233
234#endif // _BINCOOKIE_H
uint32_t num_cookies
Definition bincookie.h:129
static bincookie_page_t *const bincookie_iter_pages(const bincookie_t *bc, bincookie_iter_state_t *const state)
Iterate pages of a binarycookies file.
Definition bincookie.h:201
uint32_t cookie_offsets[]
Definition bincookie.h:130
static bincookie_t *const bincookie_init_file(FILE *fin)
Read a binarycookies file.
Definition bincookie.h:145
static bincookie_t *const bincookie_init_path(const char *file_path)
Read a binarycookies file.
Definition bincookie.h:186
uint32_t name_offset
Definition bincookie.h:115
double create_date_epoch
Definition bincookie.h:122
uint32_t domain_offset
Definition bincookie.h:114
uint32_t page_sizes[]
Definition bincookie.h:137
double expiry_date_epoch
Definition bincookie.h:121
bincookie_flag flags
Definition bincookie.h:111
uint32_t path_offset
Definition bincookie.h:116
uint32_t value_offset
Definition bincookie.h:117
uint32_t num_pages
Definition bincookie.h:136
static bincookie_cookie_t *const bincookie_iter_cookies(const bincookie_page_t *page, unsigned int *i)
Iterate cookies of a page.
Definition bincookie.h:220
bincookie_flag
Security enabled for a cookie.
Definition bincookie.h:96
@ http_only
Definition bincookie.h:98
@ secure
Definition bincookie.h:97
Keeps track of iteration state when iterating cookie file pages.
Definition bincookie.h:102
Cookie page structure. A page can consist of 1 or more cookies.
Definition bincookie.h:126
bincookie file structure.
Definition bincookie.h:134