aboutsummaryrefslogtreecommitdiff
path: root/src/mint/taler-mint-httpd_parsing.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-29 15:45:05 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-29 15:45:05 +0100
commit4a27969e5e439fb0f277dcf9f0461817d83e36b4 (patch)
tree9dbcea3e7bb5723438a1817a9a8c840f55ce92f2 /src/mint/taler-mint-httpd_parsing.c
parenta284561298af60ade27eb18008f29ebf63ac62b7 (diff)
make TALER_MINT_parse_json_data more expressive, add RSA types as well
Diffstat (limited to 'src/mint/taler-mint-httpd_parsing.c')
-rw-r--r--src/mint/taler-mint-httpd_parsing.c643
1 files changed, 409 insertions, 234 deletions
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index 165654193..9c732ce6e 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -261,6 +261,106 @@ TALER_MINT_parse_post_cleanup_callback (void *con_cls)
/**
+ * Extract base32crockford encoded data from request.
+ *
+ * Queues an error response to the connection if the parameter is missing or
+ * invalid.
+ *
+ * @param connection the MHD connection
+ * @param param_name the name of the parameter with the key
+ * @param[out] out_data pointer to store the result
+ * @param out_size expected size of data
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+int
+TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
+ const char *param_name,
+ void *out_data,
+ size_t out_size)
+{
+ const char *str;
+
+ str = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ param_name);
+ if (NULL == str)
+ {
+ return (MHD_NO ==
+ TALER_MINT_reply_arg_missing (connection, param_name))
+ ? GNUNET_SYSERR : GNUNET_NO;
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ out_data,
+ out_size))
+ return (MHD_NO ==
+ TALER_MINT_reply_arg_invalid (connection, param_name))
+ ? GNUNET_SYSERR : GNUNET_NO;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Extraxt variable-size base32crockford encoded data from request.
+ *
+ * Queues an error response to the connection if the parameter is missing
+ * or the encoding is invalid.
+ *
+ * @param connection the MHD connection
+ * @param param_name the name of the parameter with the key
+ * @param[out] out_data pointer to allocate buffer and store the result
+ * @param[out] out_size set to the size of the buffer allocated in @a out_data
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+int
+TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
+ const char *param_name,
+ void **out_data,
+ size_t *out_size)
+{
+ const char *str;
+ size_t slen;
+ size_t olen;
+ void *out;
+
+ str = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ param_name);
+ if (NULL == str)
+ {
+ return (MHD_NO ==
+ TALER_MINT_reply_arg_missing (connection, param_name))
+ ? GNUNET_SYSERR : GNUNET_NO;
+ }
+ slen = strlen (str);
+ olen = (slen * 5) / 8;
+ out = GNUNET_malloc (olen);
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ out,
+ olen))
+ {
+ GNUNET_free (out);
+ *out_size = 0;
+ return (MHD_NO ==
+ TALER_MINT_reply_arg_invalid (connection, param_name))
+ ? GNUNET_SYSERR : GNUNET_NO;
+ }
+ *out_data = out;
+ *out_size = olen;
+ return GNUNET_OK;
+}
+
+
+/**
* Navigate through a JSON tree.
*
* Sends an error response if navigation is impossible (i.e.
@@ -295,165 +395,298 @@ GNUNET_MINT_parse_navigate_json (struct MHD_Connection *connection,
switch (command)
{
- case JNAV_FIELD:
+ case JNAV_FIELD:
+ {
+ const char *fname = va_arg(argp, const char *);
+
+ json_array_append_new (path,
+ json_string (fname));
+ root = json_object_get (root,
+ fname);
+ if (NULL == root)
{
- const char *fname = va_arg(argp, const char *);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:s, s:o}",
+ "error",
+ "missing field in JSON",
+ "field",
+ fname,
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ }
+ break;
- json_array_append_new (path,
- json_string (fname));
- root = json_object_get (root,
- fname);
- if (NULL == root)
- {
- ret = (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:o}",
- "error",
- "missing field in JSON",
- "field",
- fname,
- "path",
- path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
+ case JNAV_INDEX:
+ {
+ int fnum = va_arg(argp, int);
+
+ json_array_append_new (path,
+ json_integer (fnum));
+ root = json_array_get (root,
+ fnum);
+ if (NULL == root)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "missing index in JSON",
+ "path", path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
- break;
- case JNAV_INDEX:
+ }
+ break;
+
+ case JNAV_RET_DATA:
+ {
+ void *where = va_arg (argp, void *);
+ size_t len = va_arg (argp, size_t);
+ const char *str;
+ int res;
+
+ // FIXME: avoidable code duplication here...
+ str = json_string_value (root);
+ if (NULL == str)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "string expected",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ res = GNUNET_STRINGS_string_to_data (str, strlen (str),
+ where, len);
+ if (GNUNET_OK != res)
{
- int fnum = va_arg(argp, int);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "malformed binary data in JSON",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ ret = GNUNET_OK;
+ }
+ break;
- json_array_append_new (path,
- json_integer (fnum));
- root = json_array_get (root,
- fnum);
- if (NULL == root)
- {
- ret = (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:o}",
- "error",
- "missing index in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
+ case JNAV_RET_DATA_VAR:
+ {
+ void **where = va_arg (argp, void **);
+ size_t *len = va_arg (argp, size_t *);
+ const char *str;
+
+ // FIXME: avoidable code duplication here...
+ str = json_string_value (root);
+ if (NULL == str)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_internal_error (connection,
+ "json_string_value() failed"))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
- break;
- case JNAV_RET_DATA:
+ *len = (strlen (str) * 5) / 8;
+ if (NULL != where)
{
- void *where = va_arg (argp, void *);
- size_t len = va_arg (argp, size_t);
- const char *str;
int res;
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:o}",
- "error",
- "string expected",
- "path",
- path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- res = GNUNET_STRINGS_string_to_data (str, strlen (str),
- where, len);
+ *where = GNUNET_malloc (*len);
+ res = GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ *where,
+ *len);
if (GNUNET_OK != res)
{
+ GNUNET_free (*where);
+ *where = NULL;
+ *len = 0;
ret = (MHD_YES ==
TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}",
"error",
"malformed binary data in JSON",
- "path",
- path))
+ "path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
- ret = GNUNET_OK;
}
- break;
- case JNAV_RET_DATA_VAR:
+ ret = GNUNET_OK;
+ }
+ break;
+
+ case JNAV_RET_TYPED_JSON:
+ {
+ int typ = va_arg (argp, int);
+ const json_t **r_json = va_arg (argp, const json_t **);
+
+ if ( (-1 != typ) && (json_typeof (root) != typ))
{
- void **where = va_arg (argp, void **);
- size_t *len = va_arg (argp, size_t *);
- const char *str;
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:i, s:i, s:o}",
+ "error", "wrong JSON field type",
+ "type_expected", typ,
+ "type_actual", json_typeof (root),
+ "path", path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ *r_json = root;
+ ret = GNUNET_OK;
+ }
+ break;
- str = json_string_value (root);
- if (NULL == str)
- {
- ret = (MHD_YES ==
- TALER_MINT_reply_internal_error (connection,
- "json_string_value() failed"))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- *len = (strlen (str) * 5) / 8;
- if (NULL != where)
- {
- int res;
-
- *where = GNUNET_malloc (*len);
- res = GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- *where,
- *len);
- if (GNUNET_OK != res)
- {
- GNUNET_free (*where);
- *where = NULL;
- *len = 0;
- ret = (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:o}",
- "error",
- "malformed binary data in JSON",
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- }
- ret = GNUNET_OK;
+ case JNAV_RET_RSA_PUBLIC_KEY:
+ {
+ void **where = va_arg (argp, void **);
+ size_t len;
+ const char *str;
+ int res;
+ void *buf;
+
+ // FIXME: avoidable code duplication here...
+ str = json_string_value (root);
+ if (NULL == str)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "string expected",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
- break;
- case JNAV_RET_TYPED_JSON:
+ len = (strlen (str) * 5) / 8;
+ buf = GNUNET_malloc (len);
+ res = GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ buf,
+ len);
+ if (GNUNET_OK != res)
{
- int typ = va_arg (argp, int);
- const json_t **r_json = va_arg (argp, const json_t **);
-
- if ( (-1 != typ) && (json_typeof (root) != typ))
- {
- ret = (MHD_YES ==
- TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:i, s:i, s:o}",
- "error", "wrong JSON field type",
- "type_expected", typ,
- "type_actual", json_typeof (root),
- "path", path))
- ? GNUNET_NO : GNUNET_SYSERR;
- break;
- }
- *r_json = root;
- ret = GNUNET_OK;
+ GNUNET_free (buf);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "malformed binary data in JSON",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
+ *where = GNUNET_CRYPTO_rsa_public_key_decode (buf,
+ len);
+ GNUNET_free (buf);
+ if (NULL == *where)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "malformed RSA public key in JSON",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ ret = GNUNET_OK;
break;
- default:
- GNUNET_break (0);
- ret = (MHD_YES ==
- TALER_MINT_reply_internal_error (connection,
- "unhandled value in switch"))
- ? GNUNET_NO : GNUNET_SYSERR;
+ }
+
+ case JNAV_RET_RSA_SIGNATURE:
+ {
+ void **where = va_arg (argp, void **);
+ size_t len;
+ const char *str;
+ int res;
+ void *buf;
+
+ // FIXME: avoidable code duplication here...
+ str = json_string_value (root);
+ if (NULL == str)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "string expected",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ len = (strlen (str) * 5) / 8;
+ buf = GNUNET_malloc (len);
+ res = GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ buf,
+ len);
+ if (GNUNET_OK != res)
+ {
+ GNUNET_free (buf);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "malformed binary data in JSON",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ *where = GNUNET_CRYPTO_rsa_signature_decode (buf,
+ len);
+ GNUNET_free (buf);
+ if (NULL == *where)
+ {
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:o}",
+ "error",
+ "malformed RSA signature in JSON",
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
+ }
+ ret = GNUNET_OK;
break;
+ }
+
+ default:
+ GNUNET_break (0);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_internal_error (connection,
+ "unhandled value in switch"))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
}
va_end (argp);
@@ -531,6 +764,30 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
JNAV_RET_TYPED_JSON,
spec[i].type,
&ptr);
+ *((void**)spec[i].destination) = ptr;
+ break;
+ case JNAV_RET_RSA_PUBLIC_KEY:
+ if (GNUNET_YES != ret)
+ break;
+ ptr = NULL;
+ ret = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ spec[i].field_name,
+ JNAV_RET_RSA_PUBLIC_KEY,
+ &ptr);
+ spec[i].destination = ptr;
+ break;
+ case JNAV_RET_RSA_SIGNATURE:
+ if (GNUNET_YES != ret)
+ break;
+ ptr = NULL;
+ ret = GNUNET_MINT_parse_navigate_json (connection,
+ root,
+ JNAV_FIELD,
+ spec[i].field_name,
+ JNAV_RET_RSA_SIGNATURE,
+ &ptr);
spec[i].destination = ptr;
break;
}
@@ -551,6 +808,7 @@ void
TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec)
{
unsigned int i;
+ void *ptr;
for (i=0; NULL != spec[i].field_name; i++)
{
@@ -573,10 +831,27 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec)
}
break;
case JNAV_RET_TYPED_JSON:
- if (NULL != spec[i].destination)
+ ptr = *(void **) spec[i].destination;
+ if (NULL != ptr)
{
- json_decref (spec[i].destination);
- spec[i].destination = NULL;
+ json_decref (ptr);
+ *(void**) spec[i].destination = NULL;
+ }
+ break;
+ case JNAV_RET_RSA_PUBLIC_KEY:
+ ptr = *(void **) spec[i].destination;
+ if (NULL != ptr)
+ {
+ GNUNET_CRYPTO_rsa_public_key_free (ptr);
+ *(void**) spec[i].destination = NULL;
+ }
+ break;
+ case JNAV_RET_RSA_SIGNATURE:
+ ptr = *(void **) spec[i].destination;
+ if (NULL != ptr)
+ {
+ GNUNET_CRYPTO_rsa_signature_free (ptr);
+ *(void**) spec[i].destination = NULL;
}
break;
}
@@ -656,105 +931,5 @@ TALER_MINT_parse_amount_json (struct MHD_Connection *connection,
}
-/**
- * Extract base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing or
- * invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to store the result
- * @param out_size expected size of data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void *out_data,
- size_t out_size)
-{
- const char *str;
-
- str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- param_name);
- if (NULL == str)
- {
- return (MHD_NO ==
- TALER_MINT_reply_arg_missing (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- out_data,
- out_size))
- return (MHD_NO ==
- TALER_MINT_reply_arg_invalid (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- return GNUNET_OK;
-}
-
-
-/**
- * Extraxt variable-size base32crockford encoded data from request.
- *
- * Queues an error response to the connection if the parameter is missing
- * or the encoding is invalid.
- *
- * @param connection the MHD connection
- * @param param_name the name of the parameter with the key
- * @param[out] out_data pointer to allocate buffer and store the result
- * @param[out] out_size set to the size of the buffer allocated in @a out_data
- * @return
- * #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
- * #GNUNET_SYSERR on internal error (error response could not be sent)
- */
-int
-TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
- const char *param_name,
- void **out_data,
- size_t *out_size)
-{
- const char *str;
- size_t slen;
- size_t olen;
- void *out;
-
- str = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- param_name);
- if (NULL == str)
- {
- return (MHD_NO ==
- TALER_MINT_reply_arg_missing (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- slen = strlen (str);
- olen = (slen * 5) / 8;
- out = GNUNET_malloc (olen);
- if (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (str,
- strlen (str),
- out,
- olen))
- {
- GNUNET_free (out);
- *out_size = 0;
- return (MHD_NO ==
- TALER_MINT_reply_arg_invalid (connection, param_name))
- ? GNUNET_SYSERR : GNUNET_NO;
- }
- *out_data = out;
- *out_size = olen;
- return GNUNET_OK;
-}
-
-
/* end of taler-mint-httpd_parsing.c */