Files: b9f9b0d3e41bae8e43e88364803fdbc7f7656dc1 / dillo-patch.diff
9671 bytesRaw
1 | diff --git a/src/cache.c b/src/cache.c |
2 | index bdda48fd..6d2fa56b 100644 |
3 | --- a/src/cache.c |
4 | +++ b/src/cache.c |
5 | |
6 | |
7 | #include <sys/types.h> |
8 | |
9 | +#include <errno.h> |
10 | #include <limits.h> |
11 | #include <stdlib.h> |
12 | #include <string.h> |
13 | +#include <time.h> |
14 | +#include <unistd.h> |
15 | |
16 | #include "msg.h" |
17 | #include "IO/Url.h" |
18 | |
19 | #include "timeout.hh" |
20 | #include "uicmd.hh" |
21 | |
22 | +#include <mbedtls/sha256.h> |
23 | + |
24 | /* Maximum initial size for the automatically-growing data buffer */ |
25 | #define MAX_INIT_BUF 1024*1024 |
26 | /* Maximum filesize for a URL, before offering a download */ |
27 | @@ -62,6 +67,7 @@ typedef struct { |
28 | int ExpectedSize; /* Goal size of the HTTP transfer (0 if unknown)*/ |
29 | int TransferSize; /* Actual length of the HTTP transfer */ |
30 | uint_t Flags; /* See Flag Defines in cache.h */ |
31 | + mbedtls_sha256_context Hash; /* sha256 hash state */ |
32 | } CacheEntry_t; |
33 | |
34 | |
35 | @@ -207,6 +213,7 @@ static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url) |
36 | NewEntry->ExpectedSize = 0; |
37 | NewEntry->TransferSize = 0; |
38 | NewEntry->Flags = CA_IsEmpty | CA_InProgress | CA_KeepAlive; |
39 | + mbedtls_sha256_init(&NewEntry->Hash); |
40 | } |
41 | |
42 | /* |
43 | @@ -247,6 +254,7 @@ static CacheEntry_t *Cache_entry_search_with_redirect(const DilloUrl *Url) |
44 | */ |
45 | static CacheEntry_t *Cache_entry_add(const DilloUrl *Url) |
46 | { |
47 | + int rc; |
48 | CacheEntry_t *old_entry, *new_entry; |
49 | |
50 | if ((old_entry = Cache_entry_search(Url))) { |
51 | @@ -256,6 +264,10 @@ static CacheEntry_t *Cache_entry_add(const DilloUrl *Url) |
52 | |
53 | new_entry = dNew(CacheEntry_t, 1); |
54 | Cache_entry_init(new_entry, Url); /* Set safe values */ |
55 | + rc = mbedtls_sha256_starts_ret(&new_entry->Hash, 0); |
56 | + if (rc < 0) { |
57 | + MSG_WARN("Failed to start SHA-256 calculation.\n"); |
58 | + } |
59 | dList_insert_sorted(CachedURLs, new_entry, Cache_entry_cmp); |
60 | return new_entry; |
61 | } |
62 | @@ -312,6 +324,7 @@ static void Cache_entry_free(CacheEntry_t *entry) |
63 | a_Decode_transfer_free(entry->TransferDecoder); |
64 | if (entry->ContentDecoder) |
65 | a_Decode_free(entry->ContentDecoder); |
66 | + mbedtls_sha256_init(&entry->Hash); |
67 | dFree(entry); |
68 | } |
69 | |
70 | @@ -845,6 +858,143 @@ static int Cache_get_header(CacheEntry_t *entry, |
71 | return 0; |
72 | } |
73 | |
74 | +static char *dGetblobsdir () |
75 | +{ |
76 | + static char *blobsdir = NULL; |
77 | + |
78 | + if (!blobsdir) { |
79 | + blobsdir = dStrconcat(dGethomedir(), "/.ssb/blobs", NULL); |
80 | + } |
81 | + return blobsdir; |
82 | +} |
83 | + |
84 | +static int hash_to_path(char *buf, size_t *lenp, unsigned char id[32]) |
85 | +{ |
86 | + int len = snprintf(buf, *lenp, "%s/sha256/%02x/" |
87 | + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", |
88 | + dGetblobsdir(), |
89 | + id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], |
90 | + id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15], |
91 | + id[16], id[17], id[18], id[19], id[20], id[21], id[22], id[23], |
92 | + id[24], id[25], id[26], id[27], id[28], id[29], id[30], id[31]); |
93 | + if (len < 0 || len >= (int)*lenp) { errno = EMSGSIZE; return -1; } |
94 | + *lenp = len; |
95 | + return 0; |
96 | +} |
97 | + |
98 | +static void Cache_finish_write(CacheEntry_t *entry) |
99 | +{ |
100 | + int rc; |
101 | + FILE *entry_fp, *history_fp; |
102 | + unsigned char hash_result[32]; |
103 | + char *hash_b64; |
104 | + char filename_tmp[512], filename[512], history_filename[512]; |
105 | + char history_line[512]; |
106 | + char time_str[64]; |
107 | + const char *url = URL_STR_(entry->Url); |
108 | + int url_len = strlen(url); |
109 | + size_t filename_len = sizeof(filename); |
110 | + size_t history_line_len; |
111 | + time_t tmp_time; |
112 | + static unsigned int tmp_i = 0; |
113 | + |
114 | + rc = mbedtls_sha256_finish_ret(&entry->Hash, hash_result); |
115 | + if (rc < 0) { |
116 | + MSG_WARN("Failed to finish SHA-256 calculation.\n"); |
117 | + return; |
118 | + } |
119 | + |
120 | + hash_b64 = a_Misc_encode_base64_2((char *)hash_result, 32); |
121 | + |
122 | + tmp_time = time(NULL); |
123 | + rc = snprintf(filename_tmp, sizeof(filename_tmp), "%s/tmp/%d-%d", |
124 | + dGetblobsdir(), (int)tmp_time, tmp_i++); |
125 | + if (rc < 0 || rc > (int)sizeof(filename_tmp)) { |
126 | + MSG_WARN("Failed to calculate filename.\n"); |
127 | + return; |
128 | + } |
129 | + |
130 | + rc = hash_to_path(filename, &filename_len, hash_result); |
131 | + if (rc < 0) { |
132 | + MSG_WARN("Failed to calculate path. %s\n", dStrerror(errno)); |
133 | + unlink(filename); |
134 | + return; |
135 | + } |
136 | + |
137 | + if (access(filename, F_OK) != 0) { |
138 | + entry_fp = fopen(filename_tmp, "w"); |
139 | + if (entry_fp == NULL) { |
140 | + MSG_WARN("Unable to open file for writing. " |
141 | + "Error: %s. Filename: %s URL: %s\n", |
142 | + dStrerror(errno), filename_tmp, url); |
143 | + return; |
144 | + } |
145 | + |
146 | + if (fwrite(entry->Data->str, (size_t)entry->Data->len, 1, entry_fp) != 1) { |
147 | + MSG_WARN("Failed to write blob file. %s\n", dStrerror(errno)); |
148 | + fclose(entry_fp); |
149 | + unlink(filename_tmp); |
150 | + return; |
151 | + } |
152 | + |
153 | + if (fclose(entry_fp) != 0) { |
154 | + MSG_WARN("Failed to close blob file. %s\n", dStrerror(errno)); |
155 | + unlink(filename_tmp); |
156 | + return; |
157 | + } |
158 | + |
159 | + rc = rename(filename_tmp, filename); |
160 | + if (rc < 0) { |
161 | + MSG_WARN("Failed to rename blob file. %s\n", dStrerror(errno)); |
162 | + unlink(filename_tmp); |
163 | + return; |
164 | + } |
165 | + _MSG("Saved blob %s\n", filename); |
166 | + } |
167 | + |
168 | + /* write it to history file */ |
169 | + |
170 | + rc = snprintf(history_filename, sizeof(history_filename), |
171 | + "%s/.dillo/history.txt", |
172 | + dGethomedir()); |
173 | + if (rc < 0 || rc > (int)sizeof(history_filename)) { |
174 | + MSG_WARN("Failed to calculate history filename.\n"); |
175 | + return; |
176 | + } |
177 | + |
178 | + if (strftime(time_str, sizeof(time_str), "%F %T %z", gmtime(&tmp_time)) == 0) { |
179 | + MSG_WARN("Failed to format timestamp.\n"); |
180 | + return; |
181 | + } |
182 | + |
183 | + history_fp = fopen(history_filename, "a"); |
184 | + if (history_fp == NULL) { |
185 | + MSG_WARN("Failed to open history file.\n"); |
186 | + return; |
187 | + } |
188 | + |
189 | + if (!strncmp(url, "data:", 5)) url_len = 0; |
190 | + |
191 | + history_line_len = snprintf(history_line, sizeof(history_line), |
192 | + "%s\t&%s.sha256\t%.*s\n", |
193 | + time_str, |
194 | + hash_b64, |
195 | + url_len, |
196 | + url); |
197 | + if (history_line_len <= 0 || history_line_len > (int)sizeof(history_line)) { |
198 | + MSG_WARN("Failed to create history entry.\n"); |
199 | + fclose(history_fp); |
200 | + return; |
201 | + } |
202 | + |
203 | + if (fwrite(history_line, history_line_len, 1, history_fp) != 1) { |
204 | + MSG_WARN("Failed to write history entry. %s\n", dStrerror(errno)); |
205 | + fclose(history_fp); |
206 | + return; |
207 | + } |
208 | + fclose(history_fp); |
209 | +} |
210 | + |
211 | static void Cache_finish_msg(CacheEntry_t *entry) |
212 | { |
213 | if (!(entry->Flags & CA_InProgress)) { |
214 | @@ -872,6 +1022,8 @@ static void Cache_finish_msg(CacheEntry_t *entry) |
215 | } |
216 | dStr_fit(entry->Data); /* fit buffer size! */ |
217 | |
218 | + Cache_finish_write(entry); |
219 | + |
220 | if ((entry = Cache_process_queue(entry))) { |
221 | if (entry->Flags & CA_GotHeader) { |
222 | Cache_unref_data(entry); |
223 | @@ -891,6 +1043,7 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, |
224 | const DilloUrl *Url) |
225 | { |
226 | int offset, len; |
227 | + int rc; |
228 | const char *str; |
229 | Dstr *dstr1, *dstr2, *dstr3; |
230 | bool_t done = FALSE; |
231 | @@ -932,6 +1085,10 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size, |
232 | len = dstr2->len; |
233 | } |
234 | dStr_append_l(entry->Data, str, len); |
235 | + rc = mbedtls_sha256_update_ret(&entry->Hash, (unsigned char *)str, len); |
236 | + if (rc < 0) { |
237 | + MSG_WARN("Failed to update SHA-256 calculation.\n"); |
238 | + } |
239 | if (entry->CharsetDecoder && entry->UTF8Data) { |
240 | dstr3 = a_Decode_process(entry->CharsetDecoder, str, len); |
241 | dStr_append_l(entry->UTF8Data, dstr3->str, dstr3->len); |
242 | diff --git a/src/misc.c b/src/misc.c |
243 | index 00589999..dfd85b50 100644 |
244 | --- a/src/misc.c |
245 | +++ b/src/misc.c |
246 | @@ -456,6 +456,40 @@ char *a_Misc_encode_base64(const char *in) |
247 | return out; |
248 | } |
249 | |
250 | +char *a_Misc_encode_base64_2(const char *in, int len) |
251 | +{ |
252 | + static const char *const base64_hex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
253 | + "abcdefghijklmnopqrstuvwxyz" |
254 | + "0123456789+/"; |
255 | + char *out = NULL; |
256 | + int i = 0; |
257 | + |
258 | + if (in == NULL) return NULL; |
259 | + |
260 | + out = (char *)dMalloc((len + 2) / 3 * 4 + 1); |
261 | + |
262 | + for (; len >= 3; len -= 3) { |
263 | + out[i++] = base64_hex[in[0] >> 2]; |
264 | + out[i++] = base64_hex[((in[0]<<4) & 0x30) | (in[1]>>4)]; |
265 | + out[i++] = base64_hex[((in[1]<<2) & 0x3c) | (in[2]>>6)]; |
266 | + out[i++] = base64_hex[in[2] & 0x3f]; |
267 | + in += 3; |
268 | + } |
269 | + |
270 | + if (len > 0) { |
271 | + unsigned char fragment; |
272 | + out[i++] = base64_hex[in[0] >> 2]; |
273 | + fragment = (in[0] << 4) & 0x30; |
274 | + if (len > 1) fragment |= in[1] >> 4; |
275 | + out[i++] = base64_hex[fragment]; |
276 | + out[i++] = (len < 2) ? '=' : base64_hex[(in[1] << 2) & 0x3c]; |
277 | + out[i++] = '='; |
278 | + } |
279 | + out[i] = '\0'; |
280 | + return out; |
281 | +} |
282 | + |
283 | + |
284 | /* |
285 | * Load a local file into a dStr. |
286 | * Return value: dStr on success, NULL on error. |
287 | diff --git a/src/misc.h b/src/misc.h |
288 | index 75f0f78a..340dd45e 100644 |
289 | --- a/src/misc.h |
290 | +++ b/src/misc.h |
291 | @@ -19,6 +19,7 @@ int a_Misc_content_type_cmp(const char* ct1, const char *ct2); |
292 | int a_Misc_parse_geometry(char *geom, int *x, int *y, int *w, int *h); |
293 | int a_Misc_parse_search_url(char *source, char **label, char **urlstr); |
294 | char *a_Misc_encode_base64(const char *in); |
295 | +char *a_Misc_encode_base64_2(const char *in, int len); |
296 | Dstr *a_Misc_file2dstr(const char *filename); |
297 | |
298 | #ifdef __cplusplus |
299 |
Built with git-ssb-web