gnunet_json_lib.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file gnunet_json_lib.h
  18. * @brief functions to parse JSON objects into GNUnet objects
  19. * @author Florian Dold
  20. * @author Benedikt Mueller
  21. * @author Christian Grothoff
  22. */
  23. #ifndef GNUNET_JSON_LIB_H
  24. #define GNUNET_JSON_LIB_H
  25. #include "gnunet_util_lib.h"
  26. #include <jansson.h>
  27. #include <microhttpd.h>
  28. /* ****************** Generic parser interface ******************* */
  29. /**
  30. * @brief Entry in parser specification for #GNUNET_JSON_parse().
  31. */
  32. struct GNUNET_JSON_Specification;
  33. /**
  34. * Function called to parse JSON argument.
  35. *
  36. * @param cls closure
  37. * @param root JSON to parse
  38. * @param spec our specification entry with further details
  39. * @return #GNUNET_SYSERR on error,
  40. * #GNUNET_OK on success
  41. */
  42. typedef int
  43. (*GNUNET_JSON_Parser) (void *cls,
  44. json_t *root,
  45. struct GNUNET_JSON_Specification *spec);
  46. /**
  47. * Function called to clean up data from earlier parsing.
  48. *
  49. * @param cls closure
  50. * @param spec our specification entry with data to clean.
  51. */
  52. typedef void
  53. (*GNUNET_JSON_Cleaner) (void *cls,
  54. struct GNUNET_JSON_Specification *spec);
  55. /**
  56. * @brief Entry in parser specification for #GNUNET_JSON_parse().
  57. */
  58. struct GNUNET_JSON_Specification
  59. {
  60. /**
  61. * Function for how to parse this type of entry.
  62. */
  63. GNUNET_JSON_Parser parser;
  64. /**
  65. * Function for how to clean up this type of entry.
  66. */
  67. GNUNET_JSON_Cleaner cleaner;
  68. /**
  69. * Closure for @e parser and @e cleaner.
  70. */
  71. void *cls;
  72. /**
  73. * Name of the field to parse, use NULL to get the JSON
  74. * of the main object instead of the JSON of an individual field.
  75. */
  76. const char *field;
  77. /**
  78. * Pointer, details specific to the @e parser.
  79. */
  80. void *ptr;
  81. /**
  82. * Number of bytes available in @e ptr.
  83. */
  84. size_t ptr_size;
  85. /**
  86. * Where should we store the final size of @e ptr.
  87. */
  88. size_t *size_ptr;
  89. /**
  90. * Set to #GNUNET_YES if this component is optional.
  91. */
  92. int is_optional;
  93. };
  94. /**
  95. * Navigate and parse data in a JSON tree. Tries to parse the @a root
  96. * to find all of the values given in the @a spec. If one of the
  97. * entries in @a spec cannot be found or parsed, the name of the JSON
  98. * field is returned in @a error_json_name, and the offset of the
  99. * entry in @a spec is returned in @a error_line.
  100. *
  101. * @param root the JSON node to start the navigation at.
  102. * @param spec parse specification array
  103. * @param[out] error_json_name which JSON field was problematic
  104. * @param[out] which index into @a spec did we encounter an error
  105. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  106. */
  107. enum GNUNET_GenericReturnValue
  108. GNUNET_JSON_parse (const json_t *root,
  109. struct GNUNET_JSON_Specification *spec,
  110. const char **error_json_name,
  111. unsigned int *error_line);
  112. /**
  113. * Frees all elements allocated during a #GNUNET_JSON_parse()
  114. * operation.
  115. *
  116. * @param spec specification of the parse operation
  117. */
  118. void
  119. GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec);
  120. /* ****************** Canonical parser specifications ******************* */
  121. /**
  122. * End of a parser specification.
  123. */
  124. struct GNUNET_JSON_Specification
  125. GNUNET_JSON_spec_end (void);
  126. /**
  127. * Set the "optional" flag for a parser specification entry.
  128. *
  129. * @param spec specification to modify
  130. * @return spec copy of @a spec with optional bit set
  131. */
  132. struct GNUNET_JSON_Specification
  133. GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec);
  134. /**
  135. * Variable size object (in network byte order, encoded using Crockford
  136. * Base32hex encoding).
  137. *
  138. * @param name name of the JSON field
  139. * @param[out] obj pointer where to write the data, must have @a size bytes
  140. * @param size number of bytes expected in @a obj
  141. */
  142. struct GNUNET_JSON_Specification
  143. GNUNET_JSON_spec_fixed (const char *name,
  144. void *obj,
  145. size_t size);
  146. /**
  147. * Fixed size object (in network byte order, encoded using Crockford
  148. * Base32hex encoding).
  149. *
  150. * @param name name of the JSON field
  151. * @param obj pointer where to write the data (type of `*obj` will determine size)
  152. */
  153. #define GNUNET_JSON_spec_fixed_auto(name, obj) \
  154. GNUNET_JSON_spec_fixed (name, obj, sizeof(*obj))
  155. /**
  156. * Variable size object (in network byte order, encoded using
  157. * Crockford Base32hex encoding).
  158. *
  159. * @param name name of the JSON field
  160. * @param[out] obj pointer where to write the data, will be allocated
  161. * @param[out] size where to store the number of bytes allocated for @a obj
  162. */
  163. struct GNUNET_JSON_Specification
  164. GNUNET_JSON_spec_varsize (const char *name,
  165. void **obj,
  166. size_t *size);
  167. /**
  168. * The expected field stores a string.
  169. *
  170. * @param name name of the JSON field
  171. * @param strptr where to store a pointer to the field
  172. */
  173. struct GNUNET_JSON_Specification
  174. GNUNET_JSON_spec_string (const char *name,
  175. const char **strptr);
  176. /**
  177. * JSON object.
  178. *
  179. * @param name name of the JSON field
  180. * @param[out] jsonp where to store the JSON found under @a name
  181. */
  182. struct GNUNET_JSON_Specification
  183. GNUNET_JSON_spec_json (const char *name,
  184. json_t **jsonp);
  185. /**
  186. * boolean.
  187. *
  188. * @param name name of the JSON field
  189. * @param[out] b where to store the boolean found under @a name
  190. */
  191. struct GNUNET_JSON_Specification
  192. GNUNET_JSON_spec_bool (const char *name,
  193. bool *b);
  194. /**
  195. * 8-bit integer.
  196. *
  197. * @param name name of the JSON field
  198. * @param[out] u8 where to store the integer found under @a name
  199. */
  200. struct GNUNET_JSON_Specification
  201. GNUNET_JSON_spec_uint8 (const char *name,
  202. uint8_t *u8);
  203. /**
  204. * 16-bit integer.
  205. *
  206. * @param name name of the JSON field
  207. * @param[out] u16 where to store the integer found under @a name
  208. */
  209. struct GNUNET_JSON_Specification
  210. GNUNET_JSON_spec_uint16 (const char *name,
  211. uint16_t *u16);
  212. /**
  213. * 32-bit integer.
  214. *
  215. * @param name name of the JSON field
  216. * @param[out] u32 where to store the integer found under @a name
  217. */
  218. struct GNUNET_JSON_Specification
  219. GNUNET_JSON_spec_uint32 (const char *name,
  220. uint32_t *u32);
  221. /**
  222. * 64-bit integer.
  223. *
  224. * @param name name of the JSON field
  225. * @param[out] u64 where to store the integer found under @a name
  226. */
  227. struct GNUNET_JSON_Specification
  228. GNUNET_JSON_spec_uint64 (const char *name,
  229. uint64_t *u64);
  230. /**
  231. * 64-bit signed integer.
  232. *
  233. * @param name name of the JSON field
  234. * @param[out] i64 where to store the integer found under @a name
  235. */
  236. struct GNUNET_JSON_Specification
  237. GNUNET_JSON_spec_int64 (const char *name,
  238. int64_t *i64);
  239. /**
  240. * Boolean (true mapped to #GNUNET_YES, false mapped to #GNUNET_NO).
  241. *
  242. * @param name name of the JSON field
  243. * @param[out] boolean where to store the boolean found under @a name
  244. */
  245. struct GNUNET_JSON_Specification
  246. GNUNET_JSON_spec_boolean (const char *name,
  247. int *boolean);
  248. /* ************ GNUnet-specific parser specifications ******************* */
  249. /**
  250. * Absolute time.
  251. *
  252. * @param name name of the JSON field
  253. * @param[out] at where to store the absolute time found under @a name
  254. */
  255. struct GNUNET_JSON_Specification
  256. GNUNET_JSON_spec_absolute_time (const char *name,
  257. struct GNUNET_TIME_Absolute *at);
  258. /**
  259. * Absolute time in network byte order.
  260. *
  261. * @param name name of the JSON field
  262. * @param[out] at where to store the absolute time found under @a name
  263. */
  264. struct GNUNET_JSON_Specification
  265. GNUNET_JSON_spec_absolute_time_nbo (const char *name,
  266. struct GNUNET_TIME_AbsoluteNBO *at);
  267. /**
  268. * Relative time.
  269. *
  270. * @param name name of the JSON field
  271. * @param[out] rt where to store the relative time found under @a name
  272. */
  273. struct GNUNET_JSON_Specification
  274. GNUNET_JSON_spec_relative_time (const char *name,
  275. struct GNUNET_TIME_Relative *rt);
  276. /**
  277. * Specification for parsing an RSA public key.
  278. *
  279. * @param name name of the JSON field
  280. * @param pk where to store the RSA key found under @a name
  281. */
  282. struct GNUNET_JSON_Specification
  283. GNUNET_JSON_spec_rsa_public_key (const char *name,
  284. struct GNUNET_CRYPTO_RsaPublicKey **pk);
  285. /**
  286. * Specification for parsing an RSA signature.
  287. *
  288. * @param name name of the JSON field
  289. * @param sig where to store the RSA signature found under @a name
  290. */
  291. struct GNUNET_JSON_Specification
  292. GNUNET_JSON_spec_rsa_signature (const char *name,
  293. struct GNUNET_CRYPTO_RsaSignature **sig);
  294. /* ****************** Generic generator interface ******************* */
  295. /**
  296. * Convert binary data to a JSON string with the base32crockford
  297. * encoding.
  298. *
  299. * @param data binary data
  300. * @param size size of @a data in bytes
  301. * @return json string that encodes @a data
  302. */
  303. json_t *
  304. GNUNET_JSON_from_data (const void *data, size_t size);
  305. /**
  306. * Convert binary data to a JSON string with the base32crockford
  307. * encoding.
  308. *
  309. * @param ptr binary data, sizeof (*ptr) must yield correct size
  310. * @return json string that encodes @a data
  311. */
  312. #define GNUNET_JSON_from_data_auto(ptr) \
  313. GNUNET_JSON_from_data (ptr, sizeof(*ptr))
  314. /**
  315. * Convert absolute timestamp to a json string.
  316. *
  317. * @param stamp the time stamp
  318. * @return a json string with the timestamp in @a stamp
  319. */
  320. json_t *
  321. GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp);
  322. /**
  323. * Convert absolute timestamp to a json string.
  324. *
  325. * @param stamp the time stamp
  326. * @return a json string with the timestamp in @a stamp
  327. */
  328. json_t *
  329. GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp);
  330. /**
  331. * Convert relative timestamp to a json string.
  332. *
  333. * @param stamp the time stamp
  334. * @return a json string with the timestamp in @a stamp
  335. */
  336. json_t *
  337. GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp);
  338. /**
  339. * Convert RSA public key to JSON.
  340. *
  341. * @param pk public key to convert
  342. * @return corresponding JSON encoding
  343. */
  344. json_t *
  345. GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk);
  346. /**
  347. * Convert RSA signature to JSON.
  348. *
  349. * @param sig signature to convert
  350. * @return corresponding JSON encoding
  351. */
  352. json_t *
  353. GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig);
  354. /* ******************* Helpers for MHD upload handling ******************* */
  355. /**
  356. * Return codes from #GNUNET_JSON_post_parser().
  357. */
  358. enum GNUNET_JSON_PostResult
  359. {
  360. /**
  361. * Parsing successful, JSON result is in `*json`.
  362. */
  363. GNUNET_JSON_PR_SUCCESS,
  364. /**
  365. * Parsing continues, call again soon!
  366. */
  367. GNUNET_JSON_PR_CONTINUE,
  368. /**
  369. * Sorry, memory allocation (malloc()) failed.
  370. */
  371. GNUNET_JSON_PR_OUT_OF_MEMORY,
  372. /**
  373. * Request size exceeded `buffer_max` argument.
  374. */
  375. GNUNET_JSON_PR_REQUEST_TOO_LARGE,
  376. /**
  377. * JSON parsing failed. This was not a JSON upload.
  378. */
  379. GNUNET_JSON_PR_JSON_INVALID
  380. };
  381. /**
  382. * Process a POST request containing a JSON object. This function
  383. * realizes an MHD POST processor that will (incrementally) process
  384. * JSON data uploaded to the HTTP server. It will store the required
  385. * state in the @a con_cls, which must be cleaned up using
  386. * #GNUNET_JSON_post_parser_callback().
  387. *
  388. * @param buffer_max maximum allowed size for the buffer
  389. * @param connection MHD connection handle (for meta data about the upload)
  390. * @param con_cls the closure (will point to a `struct Buffer *`)
  391. * @param upload_data the POST data
  392. * @param upload_data_size number of bytes in @a upload_data
  393. * @param json the JSON object for a completed request
  394. * @return result code indicating the status of the operation
  395. */
  396. enum GNUNET_JSON_PostResult
  397. GNUNET_JSON_post_parser (size_t buffer_max,
  398. struct MHD_Connection *connection,
  399. void **con_cls,
  400. const char *upload_data,
  401. size_t *upload_data_size,
  402. json_t **json);
  403. /**
  404. * Function called whenever we are done with a request
  405. * to clean up our state.
  406. *
  407. * @param con_cls value as it was left by
  408. * #GNUNET_JSON_post_parser(), to be cleaned up
  409. */
  410. void
  411. GNUNET_JSON_post_parser_cleanup (void *con_cls);
  412. /* ****************** GETOPT JSON helper ******************* */
  413. /**
  414. * Allow user to specify a JSON input value.
  415. *
  416. * @param shortName short name of the option
  417. * @param name long name of the option
  418. * @param argumentHelp help text for the option argument
  419. * @param description long help text for the option
  420. * @param[out] val set to the JSON specified at the command line
  421. */
  422. struct GNUNET_GETOPT_CommandLineOption
  423. GNUNET_JSON_getopt (char shortName,
  424. const char *name,
  425. const char *argumentHelp,
  426. const char *description,
  427. json_t **json);
  428. #endif
  429. /* end of gnunet_json_lib.h */