storage_read.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. #include "platform.h"
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "crypto.h"
  7. #include "netpacket.h"
  8. #include "netproto.h"
  9. #include "storage_internal.h"
  10. #include "sysendian.h"
  11. #include "tsnetwork.h"
  12. #include "warnp.h"
  13. #include "storage.h"
  14. #include "storage_read_cache.h"
  15. struct storage_read_internal {
  16. NETPACKET_CONNECTION * NPC;
  17. struct storage_read_cache * cache;
  18. uint64_t machinenum;
  19. };
  20. struct read_file_internal {
  21. int done;
  22. int status;
  23. uint8_t * buf;
  24. size_t buflen;
  25. };
  26. struct read_file_cookie {
  27. int (* callback)(void *, int, uint8_t *, size_t);
  28. void * cookie;
  29. struct storage_read_internal * S;
  30. uint64_t machinenum;
  31. uint8_t class;
  32. uint8_t name[32];
  33. uint32_t size;
  34. uint8_t * buf;
  35. size_t buflen;
  36. };
  37. static sendpacket_callback callback_read_file_send;
  38. static handlepacket_callback callback_read_file_response;
  39. static int callback_read_file(void *, int, uint8_t *, size_t);
  40. /**
  41. * storage_read_init(machinenum):
  42. * Prepare for read operations. Note that since reads are non-transactional,
  43. * this could be a no-op aside from storing the machine number.
  44. */
  45. STORAGE_R *
  46. storage_read_init(uint64_t machinenum)
  47. {
  48. struct storage_read_internal * S;
  49. /* Allocate memory. */
  50. if ((S = malloc(sizeof(struct storage_read_internal))) == NULL)
  51. goto err0;
  52. /* Create the cache. */
  53. if ((S->cache = storage_read_cache_init()) == NULL)
  54. goto err1;
  55. /* Open netpacket connection. */
  56. if ((S->NPC = netpacket_open(USERAGENT)) == NULL)
  57. goto err2;
  58. /* Store machine number. */
  59. S->machinenum = machinenum;
  60. /* Success! */
  61. return (S);
  62. err2:
  63. storage_read_cache_free(S->cache);
  64. err1:
  65. free(S);
  66. err0:
  67. /* Failure! */
  68. return (NULL);
  69. }
  70. /**
  71. * storage_read_add_name_cache(S, class, name):
  72. * Add the file ${name} from class ${class} into the cache for the read cookie
  73. * ${S} returned from storage_read_init. The data will not be fetched yet;
  74. * but any future fetch will look in the cache first and will store the block
  75. * in the cache if it needs to be fetched.
  76. */
  77. int
  78. storage_read_add_name_cache(STORAGE_R * S, char class, const uint8_t name[32])
  79. {
  80. /* Pass request to the cache. */
  81. return (storage_read_cache_add_name(S->cache, class, name));
  82. }
  83. /**
  84. * storage_read_set_cache_limit(S, size):
  85. * Set a limit of ${size} bytes on the cache associated with read cookie ${S}.
  86. */
  87. void
  88. storage_read_set_cache_limit(STORAGE_R * S, size_t size)
  89. {
  90. /* Pass request to the cache. */
  91. storage_read_cache_set_limit(S->cache, size);
  92. }
  93. /**
  94. * storage_read_file(S, buf, buflen, class, name):
  95. * Read the file ${name} from class ${class} using the read cookie ${S}
  96. * returned from storage_read_init into the buffer ${buf} of length ${buflen}.
  97. * Return 0 on success, 1 if the file does not exist; 2 if the file is not
  98. * ${buflen} bytes long or is corrupt; or -1 on error.
  99. */
  100. int
  101. storage_read_file(STORAGE_R * S, uint8_t * buf, size_t buflen,
  102. char class, const uint8_t name[32])
  103. {
  104. struct read_file_internal C;
  105. uint8_t * cached_buf;
  106. size_t cached_buflen;
  107. /* Can we serve this from our cache? */
  108. storage_read_cache_find(S->cache, class, name, &cached_buf,
  109. &cached_buflen);
  110. if (cached_buf != NULL) {
  111. if (buflen != cached_buflen) {
  112. /* Bad length. */
  113. C.status = 2;
  114. goto done;
  115. } else {
  116. /* Good length, copy data out. */
  117. C.status = 0;
  118. memcpy(buf, cached_buf, buflen);
  119. goto done;
  120. }
  121. }
  122. /* Initialize structure. */
  123. C.buf = buf;
  124. C.buflen = buflen;
  125. C.done = 0;
  126. /* Issue the request and spin until completion. */
  127. if (storage_read_file_callback(S, C.buf, C.buflen, class, name,
  128. callback_read_file, &C))
  129. goto err0;
  130. if (network_spin(&C.done))
  131. goto err0;
  132. done:
  133. /* Return status code from server. */
  134. return (C.status);
  135. err0:
  136. /* Failure! */
  137. return (-1);
  138. }
  139. /**
  140. * storage_read_file_alloc(S, buf, buflen, class, name):
  141. * Allocate a buffer and read the file ${name} from class ${class} using the
  142. * read cookie ${S} into it; set ${buf} to point at the buffer, and
  143. * ${buflen} to the length of the buffer. Return 0, 1, 2, or -1 as per
  144. * storage_read_file.
  145. */
  146. int
  147. storage_read_file_alloc(STORAGE_R * S, uint8_t ** buf,
  148. size_t * buflen, char class, const uint8_t name[32])
  149. {
  150. struct read_file_internal C;
  151. uint8_t * cached_buf;
  152. size_t cached_buflen;
  153. /* Can we serve this from our cache? */
  154. storage_read_cache_find(S->cache, class, name, &cached_buf,
  155. &cached_buflen);
  156. if (cached_buf != NULL) {
  157. /* Allocate a buffer and copy data out. */
  158. if ((*buf = malloc(cached_buflen)) == NULL)
  159. goto err0;
  160. memcpy(*buf, cached_buf, cached_buflen);
  161. *buflen = cached_buflen;
  162. /* Data is good. */
  163. C.status = 0;
  164. goto done;
  165. }
  166. /* Initialize structure. */
  167. C.buf = NULL;
  168. C.buflen = 0;
  169. C.done = 0;
  170. /* Issue the request and spin until completion. */
  171. if (storage_read_file_callback(S, C.buf, C.buflen, class, name,
  172. callback_read_file, &C))
  173. goto err0;
  174. if (network_spin(&C.done))
  175. goto err0;
  176. /* Store buffer and length if appropriate. */
  177. if (C.status == 0) {
  178. *buf = C.buf;
  179. *buflen = C.buflen;
  180. }
  181. done:
  182. /* Return status code. */
  183. return (C.status);
  184. err0:
  185. /* Failure! */
  186. return (-1);
  187. }
  188. /**
  189. * storage_read_file_callback(S, buf, buflen, class, name, callback, cookie):
  190. * Read the file ${name} from class ${class} using the read cookie ${S}
  191. * returned from storage_read_init. If ${buf} is non-NULL, then read the
  192. * file (which should be ${buflen} bytes in length) into ${buf}; otherwise
  193. * malloc a buffer. Invoke ${callback}(${cookie}, status, b, blen) when
  194. * complete, where ${status} is 0, 1, 2, or -1 as per storage_read_file,
  195. * ${b} is the buffer into which the data was read (which will be ${buf} if
  196. * that value was non-NULL) and ${blen} is the length of the file.
  197. */
  198. int
  199. storage_read_file_callback(STORAGE_R * S, uint8_t * buf, size_t buflen,
  200. char class, const uint8_t name[32],
  201. int callback(void *, int, uint8_t *, size_t), void * cookie)
  202. {
  203. struct read_file_cookie * C;
  204. /* Sanity-check file size if a buffer was provided. */
  205. if ((buf != NULL) && (buflen > 262144 - STORAGE_FILE_OVERHEAD)) {
  206. warn0("Programmer error: File too large");
  207. goto err0;
  208. }
  209. /* Bake a cookie. */
  210. if ((C = malloc(sizeof(struct read_file_cookie))) == NULL)
  211. goto err0;
  212. C->callback = callback;
  213. C->cookie = cookie;
  214. C->S = S;
  215. C->machinenum = S->machinenum;
  216. C->class = (uint8_t)class;
  217. memcpy(C->name, name, 32);
  218. /* Do we have a buffer? */
  219. if (buf != NULL) {
  220. C->buf = buf;
  221. C->buflen = buflen;
  222. C->size = (uint32_t)(buflen + STORAGE_FILE_OVERHEAD);
  223. } else {
  224. C->buf = NULL;
  225. C->buflen = 0;
  226. C->size = (uint32_t)(-1);
  227. }
  228. /* Ask the netpacket layer to send a request and get a response. */
  229. if (netpacket_op(S->NPC, callback_read_file_send, C))
  230. goto err0;
  231. /* Success! */
  232. return (0);
  233. err0:
  234. /* Failure! */
  235. return (-1);
  236. }
  237. static int
  238. callback_read_file_send(void * cookie, NETPACKET_CONNECTION * NPC)
  239. {
  240. struct read_file_cookie * C = cookie;
  241. /* Ask the server to read the file. */
  242. return (netpacket_read_file(NPC, C->machinenum, C->class,
  243. C->name, C->size, callback_read_file_response));
  244. }
  245. static int
  246. callback_read_file_response(void * cookie, NETPACKET_CONNECTION * NPC,
  247. int status, uint8_t packettype, const uint8_t * packetbuf,
  248. size_t packetlen)
  249. {
  250. struct read_file_cookie * C = cookie;
  251. uint32_t filelen;
  252. int sc;
  253. int rc;
  254. (void)NPC; /* UNUSED */
  255. /* Handle errors. */
  256. if (status != NETWORK_STATUS_OK) {
  257. netproto_printerr(status);
  258. goto err1;
  259. }
  260. /* Make sure we received the right type of packet. */
  261. if (packettype != NETPACKET_READ_FILE_RESPONSE)
  262. goto err2;
  263. /* Verify packet hmac. */
  264. switch (netpacket_hmac_verify(packettype, NULL,
  265. packetbuf, packetlen - 32, CRYPTO_KEY_AUTH_GET)) {
  266. case 1:
  267. goto err2;
  268. case -1:
  269. goto err1;
  270. }
  271. /* Make sure that the packet corresponds to the right file. */
  272. if ((packetbuf[1] != C->class) ||
  273. (memcmp(&packetbuf[2], C->name, 32)))
  274. goto err2;
  275. /* Extract status code and file length returned by server. */
  276. sc = packetbuf[0];
  277. filelen = be32dec(&packetbuf[34]);
  278. /* Verify packet integrity. */
  279. switch (sc) {
  280. case 0:
  281. if (packetlen != filelen + 70)
  282. goto err2;
  283. if (C->size != (uint32_t)(-1)) {
  284. if (filelen != C->size)
  285. goto err2;
  286. } else {
  287. if ((filelen < STORAGE_FILE_OVERHEAD) ||
  288. (filelen > 262144))
  289. goto err2;
  290. }
  291. break;
  292. case 1:
  293. case 3:
  294. if ((packetlen != 70) || (filelen != 0))
  295. goto err2;
  296. break;
  297. case 2:
  298. if (packetlen != 70)
  299. goto err2;
  300. break;
  301. default:
  302. goto err2;
  303. }
  304. /* Decrypt file data if appropriate. */
  305. if (sc == 0) {
  306. /* Allocate a buffer if necessary. */
  307. if (C->size == (uint32_t)(-1)) {
  308. C->buflen = filelen - STORAGE_FILE_OVERHEAD;
  309. if ((C->buf = malloc(C->buflen)) == NULL)
  310. goto err1;
  311. }
  312. switch (crypto_file_dec(&packetbuf[38], C->buflen, C->buf)) {
  313. case 0:
  314. /* Should we cache this data? */
  315. storage_read_cache_add_data(C->S->cache,
  316. (char)C->class, C->name, C->buf, C->buflen);
  317. break;
  318. case 1:
  319. /* File is corrupt. */
  320. sc = 2;
  321. if (C->size == (uint32_t)(-1)) {
  322. free(C->buf);
  323. C->buf = NULL;
  324. }
  325. break;
  326. case -1:
  327. if (C->size == (uint32_t)(-1))
  328. free(C->buf);
  329. goto err1;
  330. }
  331. }
  332. /*
  333. * If the user's tarsnap account balance is negative, print a warning
  334. * message and then pass back a generic error status code.
  335. */
  336. if (sc == 3) {
  337. warn0("Cannot read data from tarsnap server: "
  338. "Account balance is not positive.");
  339. warn0("Please add more money to your tarsnap account");
  340. sc = -1;
  341. }
  342. /* Perform the callback. */
  343. rc = (C->callback)(C->cookie, sc, C->buf, C->buflen);
  344. /* Free the cookie. */
  345. free(C);
  346. /* Return result from callback. */
  347. return (rc);
  348. err2:
  349. netproto_printerr(NETPROTO_STATUS_PROTERR);
  350. err1:
  351. free(C);
  352. /* Failure! */
  353. return (-1);
  354. }
  355. /* Callback for storage_read_file and storage_read_file_alloc. */
  356. static int
  357. callback_read_file(void * cookie, int sc, uint8_t * buf, size_t buflen)
  358. {
  359. struct read_file_internal * C = cookie;
  360. /* Record parameters. */
  361. C->status = sc;
  362. C->buf = buf;
  363. C->buflen = buflen;
  364. /* We're done. */
  365. C->done = 1;
  366. /* Success! */
  367. return (0);
  368. }
  369. /**
  370. * storage_read_free(S):
  371. * Close the read cookie ${S} and free any allocated memory.
  372. */
  373. void
  374. storage_read_free(STORAGE_R * S)
  375. {
  376. /* Behave consistently with free(NULL). */
  377. if (S == NULL)
  378. return;
  379. /* Close netpacket connection. */
  380. netpacket_close(S->NPC);
  381. /* Free cache. */
  382. storage_read_cache_free(S->cache);
  383. /* Free memory. */
  384. free(S);
  385. }