From 6ab14a20690a499ad32e3f2ad448d64d4e6b65fc Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Thu, 6 Aug 2020 14:40:17 +0200 Subject: -fix various bugs --- src/namestore/namestore_api.c | 2 + src/reclaim/gnunet-service-reclaim.c | 4 +- src/reclaim/oidc_helper.c | 33 ++--- src/reclaim/plugin_rest_openid_connect.c | 8 +- src/reclaim/plugin_rest_reclaim.c | 3 + src/reclaim/reclaim_api.c | 2 + src/rest/gnunet-rest-server.c | 241 ++++++++++++++++++++++++++----- 7 files changed, 233 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index 2a085cf04..f383f8b4a 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -373,6 +373,8 @@ handle_record_store_response (void *cls, emsg = _ ("Namestore failed to store record\n"); else emsg = NULL; + if (NULL == qe) + return; if (NULL != qe->cont) qe->cont (qe->cont_cls, res, emsg); free_qe (qe); diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index d4d44c3fc..0cd8c10a5 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -850,8 +850,8 @@ consume_result_cb (void *cls, struct ConsumeTicketResultMessage *crm; struct GNUNET_MQ_Envelope *env; char *data_tmp; - size_t attrs_len; - size_t attests_len; + size_t attrs_len = 0; + size_t attests_len = 0; if (GNUNET_OK != success) { diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index cb99a749d..9b5938c43 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -162,8 +162,6 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_AttestationListEntry *ale; char *subject; - char *aggr_names_str; - char *aggr_sources_str; char *source_name; char *attr_val_str; char *attest_val_str; @@ -171,7 +169,7 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, json_t *aggr_names; json_t *aggr_sources; json_t *aggr_sources_jwt; - json_t *addr_claim; + json_t *addr_claim = NULL; int num_attestations = 0; for (le = attrs->list_head; NULL != le; le = le->next) { @@ -194,8 +192,6 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, // sub REQUIRED public key identity, not exceed 255 ASCII length json_object_set_new (body, "sub", json_string (subject)); attest_val_str = NULL; - aggr_names_str = NULL; - aggr_sources_str = NULL; source_name = NULL; int i = 0; for (ale = attests->list_head; NULL != ale; ale = ale->next) @@ -237,8 +233,6 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, if (NULL == addr_claim) { addr_claim = json_object (); - json_object_set_new (body, "address", - addr_claim); } json_object_set_new (addr_claim, le->attribute->name, json_string (attr_val_str)); @@ -273,21 +267,17 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, GNUNET_free (source_name); } } + if (NULL != addr_claim) + json_object_set_new (body, "address", addr_claim); if (NULL != attest_val_str) GNUNET_free (attest_val_str); if (0 != i) { - aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT); - aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0) - | JSON_COMPACT); - json_object_set_new (body, "_claim_names", json_string (aggr_names_str)); - json_object_set_new (body, "_claim_sources", json_string ( - aggr_sources_str)); + json_object_set_new (body, "_claim_names", aggr_names); + json_object_set_new (body, "_claim_sources", aggr_sources); } - json_decref (aggr_names); - json_decref (aggr_sources); return body; } @@ -611,7 +601,6 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, GNUNET_STRINGS_base64url_decode (code, strlen (code), (void **) &code_payload); if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) + sizeof(struct OIDC_Parameters) + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) { @@ -624,8 +613,6 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, plaintext_len = code_payload_len; plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); ptr = (char *) &purpose[1]; - plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); - plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); plaintext = ptr; ptr += plaintext_len; @@ -683,8 +670,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, if (0 != GNUNET_memcmp (audience, &ticket->audience)) { GNUNET_free (code_payload); - if (NULL != nonce_str) - GNUNET_free (nonce_str); + if (NULL != *nonce_str) + GNUNET_free (*nonce_str); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Audience in ticket does not match client!\n"); return GNUNET_SYSERR; @@ -696,8 +683,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, &ticket->identity)) { GNUNET_free (code_payload); - if (NULL != nonce_str) - GNUNET_free (nonce_str); + if (NULL != *nonce_str) + GNUNET_free (*nonce_str); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); return GNUNET_SYSERR; } @@ -768,7 +755,7 @@ OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) * Parse an access token */ int -OIDC_access_token_parse (const char*token, +OIDC_access_token_parse (const char *token, struct GNUNET_RECLAIM_Ticket **ticket) { if (sizeof (struct GNUNET_RECLAIM_Ticket) != diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index b294ba166..06e1b0061 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -631,6 +631,8 @@ do_userinfo_error (void *cls) struct MHD_Response *resp; char *error; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error: %s\n", handle->edesc); GNUNET_asprintf (&error, "error=\"%s\", error_description=\"%s\"", handle->emsg, @@ -2129,12 +2131,13 @@ consume_ticket (void *cls, char *result_str; handle->idp_op = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attr: %s\n", attr->name); if (NULL == identity) { result_str = OIDC_generate_userinfo (&handle->ticket.identity, handle->attr_userinfo_list, handle->attests_list); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Userinfo: %s\n", result_str); resp = GNUNET_REST_create_response (result_str); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result_str); @@ -2198,6 +2201,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const struct EgoEntry *aud_ego; const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n"); GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, strlen (OIDC_AUTHORIZATION_HEADER_KEY), &cache_key); @@ -2263,7 +2267,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_free (authorization); return; } - + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n"); privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); handle->attr_userinfo_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index eb442bc3b..c2d14825e 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -331,6 +331,7 @@ finished_cont (void *cls, int32_t success, const char *emsg) resp = GNUNET_REST_create_response (emsg); MHD_add_response_header (resp, "Content-Type", "application/json"); + MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); if (GNUNET_OK != success) { GNUNET_SCHEDULER_add_now (&do_error, handle); @@ -348,6 +349,7 @@ delete_finished_cb (void *cls, int32_t success, const char *emsg) struct MHD_Response *resp; resp = GNUNET_REST_create_response (emsg); + MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); if (GNUNET_OK != success) { GNUNET_SCHEDULER_add_now (&do_error, handle); @@ -373,6 +375,7 @@ return_response (void *cls) result_str = json_dumps (handle->resp_object, 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); resp = GNUNET_REST_create_response (result_str); + MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result_str); cleanup_handle (handle); diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index ff549fa71..d73241a6f 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -1572,6 +1572,8 @@ GNUNET_RECLAIM_ticket_consume ( ctm->ticket = *ticket; if (NULL != h->mq) GNUNET_MQ_send_copy (h->mq, op->env); + else + reconnect(h); return op; } diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 44d4f345e..436b5b205 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c @@ -184,6 +184,42 @@ struct MhdConnectionHandle int state; }; +/** + * Accepted requests + */ +struct AcceptedRequest +{ + /** + * DLL + */ + struct AcceptedRequest *next; + + /** + * DLL + */ + struct AcceptedRequest *prev; + + /** + * Socket + */ + struct GNUNET_NETWORK_Handle *sock; + + /** + * Connection + */ + struct MhdConnectionHandle *con_handle; +}; + +/** + * AcceptedRequest list head + */ +static struct AcceptedRequest *req_list_head; + +/** + * AcceptedRequest list tail + */ +static struct AcceptedRequest *req_list_tail; + /* ************************* Global helpers ********************* */ @@ -238,7 +274,6 @@ cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value) return GNUNET_YES; } - static void cleanup_handle (struct MhdConnectionHandle *handle) { @@ -268,6 +303,19 @@ cleanup_handle (struct MhdConnectionHandle *handle) GNUNET_free (handle); } +static void +cleanup_ar (struct AcceptedRequest *ar) +{ + if (NULL != ar->con_handle) + { + cleanup_handle (ar->con_handle); + } + GNUNET_NETWORK_socket_free_memory_only_ (ar->sock); + GNUNET_CONTAINER_DLL_remove (req_list_head, + req_list_tail, + ar); + GNUNET_free (ar); +} static int header_iterator (void *cls, @@ -404,22 +452,29 @@ create_response (void *cls, void **con_cls) { char *origin; + struct AcceptedRequest *ar; struct GNUNET_HashCode key; struct MhdConnectionHandle *con_handle; struct GNUNET_REST_RequestHandle *rest_conndata_handle; struct PluginListEntry *ple; - con_handle = *con_cls; + ar = *con_cls; + if (NULL == ar) + { + GNUNET_break (0); + return MHD_NO; + } - if (NULL == *con_cls) + if (NULL == ar->con_handle) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); con_handle = GNUNET_new (struct MhdConnectionHandle); con_handle->con = con; con_handle->state = GN_REST_STATE_INIT; - *con_cls = con_handle; + ar->con_handle = con_handle; return MHD_YES; } + con_handle = ar->con_handle; if (GN_REST_STATE_INIT == con_handle->state) { rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); @@ -535,7 +590,7 @@ create_response (void *cls, MHD_RESULT ret = MHD_queue_response (con, con_handle->status, con_handle->response); - cleanup_handle (con_handle); + //cleanup_handle (con_handle); return ret; } } @@ -543,27 +598,6 @@ create_response (void *cls, /* ******************** MHD HTTP setup and event loop ******************** */ -/** - * Function called when MHD decides that we are done with a connection. - * - * @param cls NULL - * @param connection connection handle - * @param con_cls value as set by the last call to - * the MHD_AccessHandlerCallback, should be our handle - * @param toe reason for request termination (ignored) - */ -static void -mhd_completed_cb (void *cls, - struct MHD_Connection *connection, - void **con_cls, - enum MHD_RequestTerminationCode toe) -{ - if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "MHD encountered error handling request: %d\n", - toe); -} - /** * Kill the MHD daemon. @@ -671,6 +705,135 @@ schedule_httpd () GNUNET_NETWORK_fdset_destroy (wws); } +/** + * Function called when MHD first processes an incoming connection. + * Gives us the respective URI information. + * + * We use this to associate the `struct MHD_Connection` with our + * internal `struct AcceptedRequest` data structure (by checking + * for matching sockets). + * + * @param cls the HTTP server handle (a `struct MhdHttpList`) + * @param url the URL that is being requested + * @param connection MHD connection object for the request + * @return the `struct Socks5Request` that this @a connection is for + */ +static void * +mhd_log_callback (void *cls, + const char *url, + struct MHD_Connection *connection) +{ + struct AcceptedRequest *ar; + const union MHD_ConnectionInfo *ci; + + ci = MHD_get_connection_info (connection, + MHD_CONNECTION_INFO_SOCKET_CONTEXT); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url); + if (NULL == ci) + { + GNUNET_break (0); + return NULL; + } + ar = ci->socket_context; + return ar; +} + + + +/** + * Function called when MHD decides that we are done with a connection. + * + * @param cls NULL + * @param connection connection handle + * @param con_cls value as set by the last call to + * the MHD_AccessHandlerCallback, should be our handle + * @param toe reason for request termination (ignored) + */ +static void +mhd_completed_cb (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + struct AcceptedRequest *ar = *con_cls; + if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "MHD encountered error handling request: %d\n", + toe); + if (NULL == ar) + return; + if (NULL != ar->con_handle) + { + cleanup_handle (ar->con_handle); + ar->con_handle = NULL; + } + schedule_httpd (); + *con_cls = NULL; +} + +/** + * Function called when MHD connection is opened or closed. + * + * @param cls NULL + * @param connection connection handle + * @param con_cls value as set by the last call to + * the MHD_AccessHandlerCallback, should be our `struct Socks5Request *` + * @param toe connection notification type + */ +static void +mhd_connection_cb (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_ConnectionNotificationCode cnc) +{ + struct AcceptedRequest *ar; + const union MHD_ConnectionInfo *ci; + int sock; + + switch (cnc) + { + case MHD_CONNECTION_NOTIFY_STARTED: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n"); + ci = MHD_get_connection_info (connection, + MHD_CONNECTION_INFO_CONNECTION_FD); + if (NULL == ci) + { + GNUNET_break (0); + return; + } + sock = ci->connect_fd; + for (ar = req_list_head; NULL != ar; ar = ar->next) + { + if (GNUNET_NETWORK_get_fd (ar->sock) == sock) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Context set...\n"); + *con_cls = ar; + break; + } + } + break; + + case MHD_CONNECTION_NOTIFY_CLOSED: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connection closed... cleaning up\n"); + ar = *con_cls; + if (NULL == ar) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Connection stale!\n"); + return; + } + cleanup_ar (ar); + *con_cls = NULL; + break; + + default: + GNUNET_break (0); + } +} + + /** * Task run whenever HTTP server operations are pending. @@ -696,7 +859,7 @@ static void do_accept (void *cls) { struct GNUNET_NETWORK_Handle *lsock = cls; - struct GNUNET_NETWORK_Handle *s; + struct AcceptedRequest *ar; int fd; const struct sockaddr *addr; socklen_t len; @@ -718,24 +881,30 @@ do_accept (void *cls) } else GNUNET_assert (0); - s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); - if (NULL == s) + ar = GNUNET_new (struct AcceptedRequest); + ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); + if (NULL == ar->sock) { + GNUNET_free (ar); GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an inbound connection, waiting for data\n"); - fd = GNUNET_NETWORK_get_fd (s); - addr = GNUNET_NETWORK_get_addr (s); - len = GNUNET_NETWORK_get_addrlen (s); + fd = GNUNET_NETWORK_get_fd (ar->sock); + addr = GNUNET_NETWORK_get_addr (ar->sock); + len = GNUNET_NETWORK_get_addrlen (ar->sock); + GNUNET_CONTAINER_DLL_insert (req_list_head, + req_list_tail, + ar); if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) { + GNUNET_NETWORK_socket_close (ar->sock); + GNUNET_free (ar); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Failed to pass client to MHD\n")); return; } - GNUNET_free (s); schedule_httpd (); } @@ -1032,6 +1201,12 @@ run (void *cls, NULL, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, + MHD_OPTION_NOTIFY_CONNECTION, + &mhd_connection_cb, + NULL, + MHD_OPTION_URI_LOG_CALLBACK, + mhd_log_callback, + NULL, MHD_OPTION_NOTIFY_COMPLETED, &mhd_completed_cb, NULL, -- cgit v1.2.3