From e44686f08df9c58a90efcaa7322511fce5267bde Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sat, 1 Aug 2020 16:22:38 +0200 Subject: fix: reclaim urlenc / revert accidental change --- src/reclaim/plugin_rest_openid_connect.c | 71 ++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 36ae937c1..4383f16ab 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -28,6 +28,8 @@ #include #include +#include "gnunet_buffer_lib.h" +#include "gnunet_strings_lib.h" #include "gnunet_gns_service.h" #include "gnunet_gnsrecord_lib.h" #include "gnunet_identity_service.h" @@ -855,6 +857,7 @@ login_redirect (void *cls) char *login_base_url; char *new_redirect; struct MHD_Response *resp; + struct GNUNET_Buffer buf = { 0 }; struct RequestHandle *handle = cls; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, @@ -862,27 +865,53 @@ login_redirect (void *cls) "address", &login_base_url)) { - GNUNET_asprintf (&new_redirect, - "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", - login_base_url, - OIDC_RESPONSE_TYPE_KEY, - handle->oidc->response_type, - OIDC_CLIENT_ID_KEY, - handle->oidc->client_id, - OIDC_REDIRECT_URI_KEY, - handle->oidc->redirect_uri, - OIDC_SCOPE_KEY, - handle->oidc->scope, - OIDC_STATE_KEY, - (NULL != handle->oidc->state) ? handle->oidc->state : "", - OIDC_CODE_CHALLENGE_KEY, - (NULL != handle->oidc->code_challenge) ? - handle->oidc->code_challenge : "", - OIDC_NONCE_KEY, - (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", - OIDC_CLAIMS_KEY, - (NULL != handle->oidc->claims) ? handle->oidc->claims : - ""); + GNUNET_buffer_write (&buf, login_base_url, 1); + GNUNET_buffer_write_fstr (&buf, + "?%s=%s", + OIDC_RESPONSE_TYPE_KEY, + handle->oidc->response_type); + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_CLIENT_ID_KEY, + handle->oidc->client_id); + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_REDIRECT_URI_KEY, + handle->oidc->redirect_uri); + + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_SCOPE_KEY, + handle->oidc->scope); + if (NULL != handle->oidc->state) + { + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_STATE_KEY, + handle->oidc->state); + } + if (NULL != handle->oidc->code_challenge) + { + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_CODE_CHALLENGE_KEY, + handle->oidc->code_challenge); + } + if (NULL != handle->oidc->nonce) + { + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_NONCE_KEY, + handle->oidc->nonce); + } + if (NULL != handle->oidc->claims) + { + GNUNET_buffer_write_fstr (&buf, + "&%s=%s", + OIDC_CLAIMS_KEY, + handle->oidc->claims); + } + new_redirect = GNUNET_buffer_reap_str (&buf); resp = GNUNET_REST_create_response (""); MHD_add_response_header (resp, "Location", new_redirect); GNUNET_free (login_base_url); -- cgit v1.2.3 From 98e33e784dac20d69ba73696a5d39516fa8405c8 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sat, 1 Aug 2020 19:11:13 +0200 Subject: -fix redirect creation --- contrib/Makefile.inc | 6 -- po/POTFILES.in | 98 ++++++++++++++++---------------- src/reclaim/plugin_rest_openid_connect.c | 2 +- 3 files changed, 50 insertions(+), 56 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/contrib/Makefile.inc b/contrib/Makefile.inc index a563ef4a1..35c2d42a8 100644 --- a/contrib/Makefile.inc +++ b/contrib/Makefile.inc @@ -3,12 +3,6 @@ # itself. BUILDCOMMON_SHLIB_FILES = \ - build-common/sh/bin.sh/python.sh \ - build-common/sh/lib.sh/existence.sh \ - build-common/sh/lib.sh/existence_python.sh \ - build-common/sh/lib.sh/msg.sh \ - build-common/sh/lib.sh/progname.sh \ - build-common/sh/lib.sh/version_gnunet.sh \ build-common/LICENSE BUILDCOMMON_CONF_FILES = \ diff --git a/po/POTFILES.in b/po/POTFILES.in index 9ad5b4862..1f5cc81c3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -10,13 +10,21 @@ src/arm/arm_monitor_api.c src/arm/gnunet-arm.c src/arm/gnunet-service-arm.c src/arm/mockup-service.c +src/ats-tests/ats-testing-experiment.c +src/ats-tests/ats-testing-log.c +src/ats-tests/ats-testing-preferences.c +src/ats-tests/ats-testing-traffic.c +src/ats-tests/ats-testing.c +src/ats-tests/gnunet-ats-sim.c +src/ats-tests/gnunet-solver-eval.c +src/ats-tool/gnunet-ats.c src/ats/ats_api_connectivity.c src/ats/ats_api_performance.c src/ats/ats_api_scanner.c src/ats/ats_api_scheduling.c src/ats/gnunet-ats-solver-eval.c -src/ats/gnunet-service-ats_addresses.c src/ats/gnunet-service-ats.c +src/ats/gnunet-service-ats_addresses.c src/ats/gnunet-service-ats_connectivity.c src/ats/gnunet-service-ats_normalization.c src/ats/gnunet-service-ats_performance.c @@ -25,14 +33,6 @@ src/ats/gnunet-service-ats_preferences.c src/ats/gnunet-service-ats_reservations.c src/ats/gnunet-service-ats_scheduling.c src/ats/plugin_ats_proportional.c -src/ats-tests/ats-testing.c -src/ats-tests/ats-testing-experiment.c -src/ats-tests/ats-testing-log.c -src/ats-tests/ats-testing-preferences.c -src/ats-tests/ats-testing-traffic.c -src/ats-tests/gnunet-ats-sim.c -src/ats-tests/gnunet-solver-eval.c -src/ats-tool/gnunet-ats.c src/auction/gnunet-auction-create.c src/auction/gnunet-auction-info.c src/auction/gnunet-auction-join.c @@ -50,8 +50,8 @@ src/cadet/cadet_api_list_peers.c src/cadet/cadet_api_list_tunnels.c src/cadet/cadet_test_lib.c src/cadet/desirability_table.c -src/cadet/gnunet-cadet.c src/cadet/gnunet-cadet-profiler.c +src/cadet/gnunet-cadet.c src/cadet/gnunet-service-cadet.c src/cadet/gnunet-service-cadet_channel.c src/cadet/gnunet-service-cadet_connection.c @@ -67,15 +67,15 @@ src/consensus/gnunet-service-consensus.c src/consensus/plugin_block_consensus.c src/conversation/conversation_api.c src/conversation/conversation_api_call.c -src/conversation/gnunet-conversation.c src/conversation/gnunet-conversation-test.c -src/conversation/gnunet_gst.c -src/conversation/gnunet_gst_test.c -src/conversation/gnunet-helper-audio-playback.c +src/conversation/gnunet-conversation.c src/conversation/gnunet-helper-audio-playback-gst.c -src/conversation/gnunet-helper-audio-record.c +src/conversation/gnunet-helper-audio-playback.c src/conversation/gnunet-helper-audio-record-gst.c +src/conversation/gnunet-helper-audio-record.c src/conversation/gnunet-service-conversation.c +src/conversation/gnunet_gst.c +src/conversation/gnunet_gst_test.c src/conversation/microphone.c src/conversation/plugin_gnsrecord_conversation.c src/conversation/speaker.c @@ -105,7 +105,6 @@ src/dht/dht_api.c src/dht/dht_test_lib.c src/dht/gnunet-dht-get.c src/dht/gnunet-dht-monitor.c -src/dht/gnunet_dht_profiler.c src/dht/gnunet-dht-put.c src/dht/gnunet-service-dht.c src/dht/gnunet-service-dht_clients.c @@ -114,6 +113,7 @@ src/dht/gnunet-service-dht_hello.c src/dht/gnunet-service-dht_neighbours.c src/dht/gnunet-service-dht_nse.c src/dht/gnunet-service-dht_routing.c +src/dht/gnunet_dht_profiler.c src/dht/plugin_block_dht.c src/dns/dns_api.c src/dns/gnunet-dns-monitor.c @@ -148,8 +148,8 @@ src/fs/gnunet-auto-share.c src/fs/gnunet-daemon-fsprofiler.c src/fs/gnunet-directory.c src/fs/gnunet-download.c -src/fs/gnunet-fs.c src/fs/gnunet-fs-profiler.c +src/fs/gnunet-fs.c src/fs/gnunet-helper-fs-publish.c src/fs/gnunet-publish.c src/fs/gnunet-search.c @@ -169,9 +169,9 @@ src/gns/gns_tld_api.c src/gns/gnunet-bcd.c src/gns/gnunet-dns2gns.c src/gns/gnunet-gns-benchmark.c -src/gns/gnunet-gns.c src/gns/gnunet-gns-import.c src/gns/gnunet-gns-proxy.c +src/gns/gnunet-gns.c src/gns/gnunet-service-gns.c src/gns/gnunet-service-gns_interceptor.c src/gns/gnunet-service-gns_resolver.c @@ -188,8 +188,8 @@ src/gnsrecord/gnunet-gnsrecord-tvg.c src/gnsrecord/plugin_gnsrecord_dns.c src/hello/address.c src/hello/gnunet-hello.c -src/hello/hello.c src/hello/hello-ng.c +src/hello/hello.c src/hostlist/gnunet-daemon-hostlist.c src/hostlist/gnunet-daemon-hostlist_client.c src/hostlist/gnunet-daemon-hostlist_server.c @@ -214,8 +214,8 @@ src/namecache/namecache_api.c src/namecache/plugin_namecache_flat.c src/namecache/plugin_namecache_postgres.c src/namecache/plugin_namecache_sqlite.c -src/namestore/gnunet-namestore.c src/namestore/gnunet-namestore-fcfsd.c +src/namestore/gnunet-namestore.c src/namestore/gnunet-service-namestore.c src/namestore/gnunet-zoneimport.c src/namestore/namestore_api.c @@ -241,17 +241,17 @@ src/nat/gnunet-service-nat_mini.c src/nat/gnunet-service-nat_stun.c src/nat/nat_api.c src/nat/nat_api_stun.c -src/nse/gnunet-nse.c src/nse/gnunet-nse-profiler.c +src/nse/gnunet-nse.c src/nse/gnunet-service-nse.c src/nse/nse_api.c src/nt/nt.c -src/peerinfo/gnunet-service-peerinfo.c -src/peerinfo/peerinfo_api.c -src/peerinfo/peerinfo_api_notify.c src/peerinfo-tool/gnunet-peerinfo.c src/peerinfo-tool/gnunet-peerinfo_plugins.c src/peerinfo-tool/plugin_rest_peerinfo.c +src/peerinfo/gnunet-service-peerinfo.c +src/peerinfo/peerinfo_api.c +src/peerinfo/peerinfo_api_notify.c src/peerstore/gnunet-peerstore.c src/peerstore/gnunet-service-peerstore.c src/peerstore/peerstore_api.c @@ -297,27 +297,27 @@ src/rest/gnunet-rest-server.c src/rest/plugin_rest_config.c src/rest/plugin_rest_copying.c src/rest/rest.c -src/revocation/gnunet-revocation.c src/revocation/gnunet-revocation-tvg.c +src/revocation/gnunet-revocation.c src/revocation/gnunet-service-revocation.c src/revocation/plugin_block_revocation.c src/revocation/revocation_api.c -src/rps/gnunet-rps.c src/rps/gnunet-rps-profiler.c +src/rps/gnunet-rps.c src/rps/gnunet-service-rps.c src/rps/gnunet-service-rps_custommap.c src/rps/gnunet-service-rps_sampler.c src/rps/gnunet-service-rps_sampler_elem.c src/rps/gnunet-service-rps_view.c -src/rps/rps_api.c src/rps/rps-sampler_client.c src/rps/rps-sampler_common.c src/rps/rps-test_util.c +src/rps/rps_api.c src/scalarproduct/gnunet-scalarproduct.c -src/scalarproduct/gnunet-service-scalarproduct_alice.c -src/scalarproduct/gnunet-service-scalarproduct_bob.c src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +src/scalarproduct/gnunet-service-scalarproduct_alice.c +src/scalarproduct/gnunet-service-scalarproduct_bob.c src/scalarproduct/scalarproduct_api.c src/secretsharing/gnunet-secretsharing-profiler.c src/secretsharing/gnunet-service-secretsharing.c @@ -343,15 +343,16 @@ src/statistics/gnunet-statistics.c src/statistics/statistics_api.c src/template/gnunet-service-template.c src/template/gnunet-template.c +src/testbed-logger/gnunet-service-testbed-logger.c +src/testbed-logger/testbed_logger_api.c src/testbed/generate-underlay-topology.c src/testbed/gnunet-daemon-latency-logger.c src/testbed/gnunet-daemon-testbed-blacklist.c src/testbed/gnunet-daemon-testbed-underlay.c src/testbed/gnunet-helper-testbed.c -src/testbed/gnunet_mpi_test.c src/testbed/gnunet-service-test-barriers.c -src/testbed/gnunet-service-testbed_barriers.c src/testbed/gnunet-service-testbed.c +src/testbed/gnunet-service-testbed_barriers.c src/testbed/gnunet-service-testbed_cache.c src/testbed/gnunet-service-testbed_connectionpool.c src/testbed/gnunet-service-testbed_cpustatus.c @@ -359,20 +360,19 @@ src/testbed/gnunet-service-testbed_links.c src/testbed/gnunet-service-testbed_meminfo.c src/testbed/gnunet-service-testbed_oc.c src/testbed/gnunet-service-testbed_peers.c -src/testbed/gnunet_testbed_mpi_spawn.c src/testbed/gnunet-testbed-profiler.c -src/testbed-logger/gnunet-service-testbed-logger.c -src/testbed-logger/testbed_logger_api.c -src/testbed/testbed_api_barriers.c +src/testbed/gnunet_mpi_test.c +src/testbed/gnunet_testbed_mpi_spawn.c src/testbed/testbed_api.c +src/testbed/testbed_api_barriers.c src/testbed/testbed_api_hosts.c src/testbed/testbed_api_operations.c src/testbed/testbed_api_peers.c src/testbed/testbed_api_sd.c src/testbed/testbed_api_services.c src/testbed/testbed_api_statistics.c -src/testbed/testbed_api_testbed.c src/testbed/testbed_api_test.c +src/testbed/testbed_api_testbed.c src/testbed/testbed_api_topology.c src/testbed/testbed_api_underlay.c src/testing/gnunet-testing.c @@ -384,34 +384,40 @@ src/transport/gnunet-communicator-tcp.c src/transport/gnunet-communicator-udp.c src/transport/gnunet-communicator-unix.c src/transport/gnunet-helper-transport-bluetooth.c -src/transport/gnunet-helper-transport-wlan.c src/transport/gnunet-helper-transport-wlan-dummy.c +src/transport/gnunet-helper-transport-wlan.c src/transport/gnunet-service-tng.c -src/transport/gnunet-service-transport_ats.c src/transport/gnunet-service-transport.c +src/transport/gnunet-service-transport_ats.c src/transport/gnunet-service-transport_hello.c src/transport/gnunet-service-transport_manipulation.c src/transport/gnunet-service-transport_neighbours.c src/transport/gnunet-service-transport_plugins.c src/transport/gnunet-service-transport_validation.c -src/transport/gnunet-transport.c src/transport/gnunet-transport-profiler.c src/transport/gnunet-transport-wlan-receiver.c src/transport/gnunet-transport-wlan-sender.c +src/transport/gnunet-transport.c src/transport/plugin_transport_http_client.c src/transport/plugin_transport_http_common.c src/transport/plugin_transport_http_server.c src/transport/plugin_transport_smtp.c src/transport/plugin_transport_tcp.c src/transport/plugin_transport_template.c -src/transport/plugin_transport_udp_broadcasting.c src/transport/plugin_transport_udp.c +src/transport/plugin_transport_udp_broadcasting.c src/transport/plugin_transport_unix.c src/transport/plugin_transport_wlan.c src/transport/tcp_connection_legacy.c src/transport/tcp_server_legacy.c src/transport/tcp_server_mst_legacy.c src/transport/tcp_service_legacy.c +src/transport/transport-testing-filenames.c +src/transport/transport-testing-loggers.c +src/transport/transport-testing-main.c +src/transport/transport-testing-send.c +src/transport/transport-testing.c +src/transport/transport-testing2.c src/transport/transport_api2_application.c src/transport/transport_api2_communication.c src/transport/transport_api2_core.c @@ -424,12 +430,6 @@ src/transport/transport_api_manipulation.c src/transport/transport_api_monitor_peers.c src/transport/transport_api_monitor_plugins.c src/transport/transport_api_offer_hello.c -src/transport/transport-testing2.c -src/transport/transport-testing.c -src/transport/transport-testing-filenames.c -src/transport/transport-testing-loggers.c -src/transport/transport-testing-main.c -src/transport/transport-testing-send.c src/util/bandwidth.c src/util/benchmark.c src/util/bio.c @@ -444,8 +444,8 @@ src/util/consttime_memcmp.c src/util/container_bloomfilter.c src/util/container_heap.c src/util/container_meta_data.c -src/util/container_multihashmap32.c src/util/container_multihashmap.c +src/util/container_multihashmap32.c src/util/container_multipeermap.c src/util/container_multishortmap.c src/util/container_multiuuidmap.c @@ -469,8 +469,8 @@ src/util/dnsparser.c src/util/dnsstub.c src/util/getopt.c src/util/getopt_helpers.c -src/util/gnunet-config.c src/util/gnunet-config-diff.c +src/util/gnunet-config.c src/util/gnunet-crypto-tvg.c src/util/gnunet-ecc.c src/util/gnunet-qr.c @@ -507,8 +507,8 @@ src/vpn/gnunet-helper-vpn.c src/vpn/gnunet-service-vpn.c src/vpn/gnunet-vpn.c src/vpn/vpn_api.c -src/zonemaster/gnunet-service-zonemaster.c src/zonemaster/gnunet-service-zonemaster-monitor.c +src/zonemaster/gnunet-service-zonemaster.c src/fs/fs_api.h src/testbed/testbed_api.h src/testbed/testbed_api_operations.h diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 4383f16ab..69bbb7af7 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -865,7 +865,7 @@ login_redirect (void *cls) "address", &login_base_url)) { - GNUNET_buffer_write (&buf, login_base_url, 1); + GNUNET_buffer_write_str (&buf, login_base_url); GNUNET_buffer_write_fstr (&buf, "?%s=%s", OIDC_RESPONSE_TYPE_KEY, -- cgit v1.2.3 From c0b4041cbd9d27ce919e861ca05a74843648d7d0 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sun, 2 Aug 2020 08:38:56 +0200 Subject: - actually urlencode parameters in reclaim OIDC --- src/reclaim/plugin_rest_openid_connect.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 69bbb7af7..faa6e8351 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -856,6 +856,7 @@ login_redirect (void *cls) { char *login_base_url; char *new_redirect; + char *tmp; struct MHD_Response *resp; struct GNUNET_Buffer buf = { 0 }; struct RequestHandle *handle = cls; @@ -874,21 +875,32 @@ login_redirect (void *cls) "&%s=%s", OIDC_CLIENT_ID_KEY, handle->oidc->client_id); + GNUNET_STRINGS_urlencode (handle->oidc->redirect_uri, + strlen (handle->oidc->redirect_uri), + &tmp); GNUNET_buffer_write_fstr (&buf, "&%s=%s", OIDC_REDIRECT_URI_KEY, - handle->oidc->redirect_uri); - + tmp); + GNUNET_free (tmp); + GNUNET_STRINGS_urlencode (handle->oidc->scope, + strlen (handle->oidc->scope), + &tmp); GNUNET_buffer_write_fstr (&buf, "&%s=%s", OIDC_SCOPE_KEY, - handle->oidc->scope); + tmp); + GNUNET_free (tmp); if (NULL != handle->oidc->state) { + GNUNET_STRINGS_urlencode (handle->oidc->state, + strlen (handle->oidc->state), + &tmp); GNUNET_buffer_write_fstr (&buf, "&%s=%s", OIDC_STATE_KEY, handle->oidc->state); + GNUNET_free (tmp); } if (NULL != handle->oidc->code_challenge) { @@ -906,10 +918,14 @@ login_redirect (void *cls) } if (NULL != handle->oidc->claims) { + GNUNET_STRINGS_urlencode (handle->oidc->claims, + strlen (handle->oidc->claims), + &tmp); GNUNET_buffer_write_fstr (&buf, "&%s=%s", OIDC_CLAIMS_KEY, - handle->oidc->claims); + tmp); + GNUNET_free (tmp); } new_redirect = GNUNET_buffer_reap_str (&buf); resp = GNUNET_REST_create_response (""); -- cgit v1.2.3 From 25f37e8b2b5a13dec4aaf669ffe221ac34009609 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sun, 2 Aug 2020 16:54:59 +0200 Subject: - fix urldecode params --- src/reclaim/plugin_rest_openid_connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index faa6e8351..74fb71135 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -1503,7 +1503,7 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key) GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); if (NULL == value) return NULL; - return GNUNET_strdup (value); + return GNUNET_STRINGS_urldecode (value); } -- cgit v1.2.3 From d8c3df26a577ebbe623c05c43c00823c6b8312ae Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Sun, 2 Aug 2020 17:01:04 +0200 Subject: - fix urldecode params #2 --- src/reclaim/plugin_rest_openid_connect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 74fb71135..6c71155ef 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -1493,6 +1493,7 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key) { struct GNUNET_HashCode hc; char *value; + char *res; GNUNET_CRYPTO_hash (key, strlen (key), &hc); if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle @@ -1503,7 +1504,8 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key) GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); if (NULL == value) return NULL; - return GNUNET_STRINGS_urldecode (value); + GNUNET_STRINGS_urldecode (value, strlen (value), &res); + return res; } -- cgit v1.2.3 From 8c86c44720790095726fa1597d6bb8a50f322b28 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Mon, 3 Aug 2020 19:37:23 +0200 Subject: reclaim: support client credentials in POST body for token request --- src/reclaim/plugin_rest_openid_connect.c | 120 +++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 36 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 6c71155ef..e54473162 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -999,6 +999,7 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) handle->redirect_prefix, handle->tld, handle->redirect_suffix, + (NULL == strchr(handle->redirect_suffix, '?') ? "?" : "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1006,8 +1007,9 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) else { GNUNET_asprintf (&redirect_uri, - "%s?%s=%s&state=%s", + "%s%s%s=%s&state=%s", handle->oidc->redirect_uri, + (NULL == strchr(handle->oidc->redirect_uri, '?') ? "?" : "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1794,18 +1796,17 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); } - static int -check_authorization (struct RequestHandle *handle, - struct GNUNET_CRYPTO_EcdsaPublicKey *cid) +parse_credentials_basic_auth (struct RequestHandle *handle, + char **client_id, + char **client_secret) { struct GNUNET_HashCode cache_key; char *authorization; char *credentials; char *basic_authorization; - char *client_id; + char *client_id_tmp; char *pass; - char *expected_pass; GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, strlen (OIDC_AUTHORIZATION_HEADER_KEY), @@ -1813,12 +1814,7 @@ check_authorization (struct RequestHandle *handle, if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle ->header_param_map, &cache_key)) - { - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->edesc = GNUNET_strdup ("missing authorization"); - handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; - } authorization = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, &cache_key); @@ -1826,40 +1822,93 @@ check_authorization (struct RequestHandle *handle, // split header in "Basic" and [content] credentials = strtok (authorization, " "); if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) - { - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; - } credentials = strtok (NULL, " "); if (NULL == credentials) - { - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; - } GNUNET_STRINGS_base64_decode (credentials, strlen (credentials), (void **) &basic_authorization); if (NULL == basic_authorization) - { - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; - } - client_id = strtok (basic_authorization, ":"); - if (NULL == client_id) + client_id_tmp = strtok (basic_authorization, ":"); + if (NULL == client_id_tmp) { GNUNET_free (basic_authorization); - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; } pass = strtok (NULL, ":"); if (NULL == pass) { GNUNET_free (basic_authorization); + return GNUNET_SYSERR; + } + *client_id = strdup (client_id_tmp); + *client_secret = strdup (pass); + GNUNET_free (basic_authorization); + return GNUNET_OK; +} + + +static int +parse_credentials_post_body (struct RequestHandle *handle, + char **client_id, + char **client_secret) +{ + struct GNUNET_HashCode cache_key; + char *client_id_tmp; + char *pass; + + GNUNET_CRYPTO_hash ("client_id", + strlen ("client_id"), + &cache_key); + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle + ->url_param_map, + &cache_key)) + return GNUNET_SYSERR; + client_id_tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, + &cache_key); + if (NULL == client_id_tmp) + return GNUNET_SYSERR; + *client_id = strdup (client_id_tmp); + GNUNET_CRYPTO_hash ("client_secret", + strlen ("client_secret"), + &cache_key); + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle + ->url_param_map, + &cache_key)) + return GNUNET_SYSERR; + pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, + &cache_key); + if (NULL == pass) + return GNUNET_SYSERR; + *client_secret = strdup (pass); + return GNUNET_OK; +} + + +static int +check_authorization (struct RequestHandle *handle, + struct GNUNET_CRYPTO_EcdsaPublicKey *cid) +{ + char *expected_pass; + char *received_cid; + char *received_cpw; + + if (GNUNET_OK == parse_credentials_basic_auth (handle, + &received_cid, + &received_cpw)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received client credentials in HTTP AuthZ header\n"); + } else if (GNUNET_OK == parse_credentials_post_body (handle, + &received_cid, + &received_cpw)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received client credentials in POST body\n"); + } else { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; @@ -1871,9 +1920,8 @@ check_authorization (struct RequestHandle *handle, "OIDC_CLIENT_SECRET", &expected_pass)) { - if (0 != strcmp (expected_pass, pass)) + if (0 != strcmp (expected_pass, received_cpw)) { - GNUNET_free (basic_authorization); GNUNET_free (expected_pass); handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); handle->response_code = MHD_HTTP_UNAUTHORIZED; @@ -1883,33 +1931,33 @@ check_authorization (struct RequestHandle *handle, } else { - GNUNET_free (basic_authorization); handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); handle->edesc = GNUNET_strdup ("gnunet configuration failed"); handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; return GNUNET_SYSERR; } - // check client_id for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) { - if (0 == strcmp (handle->ego_entry->keystring, client_id)) + if (0 == strcmp (handle->ego_entry->keystring, received_cid)) break; } if (NULL == handle->ego_entry) { - GNUNET_free (basic_authorization); + GNUNET_free (received_cpw); + GNUNET_free (received_cid); handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; } - GNUNET_STRINGS_string_to_data (client_id, - strlen (client_id), + GNUNET_STRINGS_string_to_data (received_cid, + strlen (received_cid), cid, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); - GNUNET_free (basic_authorization); + GNUNET_free (received_cpw); + GNUNET_free (received_cid); return GNUNET_OK; } -- cgit v1.2.3 From ba2050750fcb0b5c7919fda98bca4f7c13a36d14 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Mon, 3 Aug 2020 21:43:21 +0200 Subject: -fix userinfo sub claim --- src/reclaim/plugin_rest_openid_connect.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index e54473162..3db881244 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -2279,7 +2279,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, char *authorization_type; char *authorization_access_token; struct GNUNET_RECLAIM_Ticket *ticket; - const struct EgoEntry *ego_entry; + const struct EgoEntry *aud_ego; + const struct EgoEntry *iss_ego; const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, @@ -2340,8 +2341,9 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, ticket = GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key); GNUNET_assert (NULL != ticket); - ego_entry = find_ego (handle, &ticket->audience); - if (NULL == ego_entry) + aud_ego = find_ego (handle, &ticket->audience); + iss_ego = find_ego (handle, &ticket->identity); + if ((NULL == aud_ego) || (NULL == iss_ego)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); handle->edesc = GNUNET_strdup ("The access token expired"); @@ -2355,8 +2357,9 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, handle->oidc->response = json_object (); json_object_set_new (handle->oidc->response, "sub", - json_string (ego_entry->keystring)); - privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + json_string (iss_ego->keystring)); + privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); + handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, privkey, ticket, -- cgit v1.2.3 From 080519e980d8f8a3b138c733f837417bdb1b6757 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 4 Aug 2020 10:09:45 +0200 Subject: reclaim: do not store access token instead piggyback ticket --- src/reclaim/oidc_helper.c | 25 +++++++++++---- src/reclaim/oidc_helper.h | 9 ++++-- src/reclaim/plugin_rest_openid_connect.c | 52 +++----------------------------- 3 files changed, 31 insertions(+), 55 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index ad2839200..b48738cc4 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -757,15 +757,28 @@ OIDC_build_token_response (const char *access_token, * Generate a new access token */ char * -OIDC_access_token_new () +OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket) { char *access_token; - uint64_t random_number; - random_number = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); - GNUNET_STRINGS_base64_encode (&random_number, - sizeof(uint64_t), + GNUNET_STRINGS_base64_encode (ticket, + sizeof(*ticket), &access_token); return access_token; } + + +/** + * Parse an access token + */ +int +OIDC_access_token_parse (const char*token, + struct GNUNET_RECLAIM_Ticket **ticket) +{ + if (sizeof (struct GNUNET_RECLAIM_Ticket) != + GNUNET_STRINGS_base64_decode (token, + strlen (token), + (void**) ticket)) + return GNUNET_SYSERR; + return GNUNET_OK; +} diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index 2c533357e..e84087fc3 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -117,7 +117,12 @@ OIDC_build_token_response (const char *access_token, * Generate a new access token */ char* -OIDC_access_token_new (); - +OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); +/** + * Parse an access token + */ +int +OIDC_access_token_parse (const char* token, + struct GNUNET_RECLAIM_Ticket **ticket); #endif diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 3db881244..eb602a08f 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -238,12 +238,6 @@ static char *OIDC_ignored_parameter_array[] = { "display", */ struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map; -/** - * Hash map that links the issued access token to the corresponding ticket and - * ego - */ -struct GNUNET_CONTAINER_MultiHashMap *OIDC_access_token_map; - /** * The configuration handle */ @@ -1980,26 +1974,6 @@ find_ego (struct RequestHandle *handle, } -static void -persist_access_token (const struct RequestHandle *handle, - const char *access_token, - const struct GNUNET_RECLAIM_Ticket *ticket) -{ - struct GNUNET_HashCode hc; - struct GNUNET_RECLAIM_Ticket *ticketbuf; - - GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc); - ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket); - *ticketbuf = *ticket; - GNUNET_assert (GNUNET_SYSERR != - GNUNET_CONTAINER_multihashmap_put ( - OIDC_access_token_map, - &hc, - ticketbuf, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); -} - - /** * Responds to token url-encoded POST request * @@ -2148,13 +2122,12 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, &expiration_time, (NULL != nonce) ? nonce : NULL, jwt_secret); - access_token = OIDC_access_token_new (); + access_token = OIDC_access_token_new (&ticket); OIDC_build_token_response (access_token, id_token, &expiration_time, &json_response); - persist_access_token (handle, access_token, &ticket); resp = GNUNET_REST_create_response (json_response); MHD_add_response_header (resp, "Cache-Control", "no-store"); MHD_add_response_header (resp, "Pragma", "no-cache"); @@ -2324,22 +2297,17 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, return; } - GNUNET_CRYPTO_hash (authorization_access_token, - strlen (authorization_access_token), - &cache_key); - if (GNUNET_NO == - GNUNET_CONTAINER_multihashmap_contains (OIDC_access_token_map, - &cache_key)) + if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token, + &ticket)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); - handle->edesc = GNUNET_strdup ("The access token expired"); + handle->edesc = GNUNET_strdup ("The access token is invalid"); handle->response_code = MHD_HTTP_UNAUTHORIZED; GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); GNUNET_free (authorization); return; + } - ticket = - GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key); GNUNET_assert (NULL != ticket); aud_ego = find_ego (handle, &ticket->audience); iss_ego = find_ego (handle, &ticket->identity); @@ -2523,9 +2491,6 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (NULL == OIDC_cookie_jar_map) OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); - if (NULL == OIDC_access_token_map) - OIDC_access_token_map = - GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; handle->proc_cls = proc_cls; @@ -2606,13 +2571,6 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map); - hashmap_it = - GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_access_token_map); - while (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, - value)) - GNUNET_free (value); - GNUNET_CONTAINER_multihashmap_destroy (OIDC_access_token_map); GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); GNUNET_free (allow_methods); GNUNET_free (api); -- cgit v1.2.3 From 815ded19f106990a37bbacec83546b1b897491f6 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 4 Aug 2020 19:40:23 +0200 Subject: rest: fix #6462 --- src/gns/plugin_rest_gns.c | 65 +++---- src/identity/plugin_rest_identity.c | 290 ++++++++++++++---------------- src/include/gnunet_rest_plugin.h | 8 +- src/namestore/plugin_rest_namestore.c | 242 ++++++++++++------------- src/peerinfo-tool/plugin_rest_peerinfo.c | 66 +++---- src/reclaim/plugin_rest_openid_connect.c | 241 ++++++++++++------------- src/reclaim/plugin_rest_reclaim.c | 293 ++++++++++++++++--------------- src/rest/gnunet-rest-server.c | 120 +++++++------ src/rest/plugin_rest_config.c | 7 +- src/rest/plugin_rest_copying.c | 32 +--- 10 files changed, 645 insertions(+), 719 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c index 37313c529..a3006ce23 100644 --- a/src/gns/plugin_rest_gns.c +++ b/src/gns/plugin_rest_gns.c @@ -62,6 +62,11 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Connection to GNS + */ +static struct GNUNET_GNS_Handle *gns; + /** * @brief struct returned by the initialization function of the plugin */ @@ -75,11 +80,6 @@ struct Plugin */ struct RequestHandle { - /** - * Connection to GNS - */ - struct GNUNET_GNS_Handle *gns; - /** * Active GNS lookup */ @@ -153,12 +153,6 @@ cleanup_handle (void *cls) GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup); handle->gns_lookup = NULL; } - if (NULL != handle->gns) - { - GNUNET_GNS_disconnect (handle->gns); - handle->gns = NULL; - } - if (NULL != handle->timeout_task) { GNUNET_SCHEDULER_cancel (handle->timeout_task); @@ -318,7 +312,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle, handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; } - handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns, + handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns, handle->name, handle->record_type, GNUNET_GNS_LO_DEFAULT, @@ -351,29 +345,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * Function processing the REST call * @@ -385,12 +356,17 @@ init_cont (struct RequestHandle *handle) * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->response_code = 0; handle->timeout = @@ -402,14 +378,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->gns = GNUNET_GNS_connect (cfg); - init_cont (handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -441,6 +420,7 @@ libgnunet_plugin_rest_gns_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + gns = GNUNET_GNS_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n")); return api; @@ -460,6 +440,9 @@ libgnunet_plugin_rest_gns_done (void *cls) struct Plugin *plugin = api->cls; plugin->cfg = NULL; + if (NULL != gns) + GNUNET_GNS_disconnect (gns); + GNUNET_free (allow_methods); GNUNET_free (api); diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c index 02e42d03f..6859396d6 100644 --- a/src/identity/plugin_rest_identity.c +++ b/src/identity/plugin_rest_identity.c @@ -126,6 +126,26 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + /** * @brief struct returned by the initialization function of the plugin */ @@ -185,27 +205,6 @@ struct RequestHandle */ size_t data_size; - - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * IDENTITY Operation */ @@ -260,8 +259,6 @@ static void cleanup_handle (void *cls) { struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) @@ -276,17 +273,6 @@ cleanup_handle (void *cls) GNUNET_free (handle->emsg); if (NULL != handle->name) GNUNET_free (handle->name); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } GNUNET_free (handle); } @@ -338,7 +324,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) if (NULL != pubkey) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (pubkey, ego_entry->keystring)) @@ -348,7 +334,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name) } if (NULL != name) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (name, ego_entry->identifier)) @@ -438,7 +424,7 @@ ego_get_subsystem (struct GNUNET_REST_RequestHandle *con_handle, // requested default identity of subsystem GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem); - handle->op = GNUNET_IDENTITY_get (handle->identity_handle, + handle->op = GNUNET_IDENTITY_get (identity_handle, subsystem, &ego_get_for_subsystem, handle); @@ -476,7 +462,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle, json_root = json_array (); // Return ego/egos - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { json_ego = json_object (); @@ -766,7 +752,7 @@ ego_edit (struct RequestHandle *handle, struct EgoEntry *ego_entry) json_decref (data_js); return; } - handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, + handle->op = GNUNET_IDENTITY_rename (identity_handle, ego_entry->identifier, newname, &do_finished, @@ -956,7 +942,7 @@ ego_edit_subsystem (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_set (handle->identity_handle, + handle->op = GNUNET_IDENTITY_set (identity_handle, newsubsys, ego_entry->ego, &do_finished, @@ -1047,7 +1033,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, return; } GNUNET_STRINGS_utf8_tolower (egoname, egoname); - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 == strcasecmp (egoname, ego_entry->identifier)) @@ -1073,7 +1059,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, pk_ptr = NULL; json_decref (data_js); handle->response_code = MHD_HTTP_CREATED; - handle->op = GNUNET_IDENTITY_create (handle->identity_handle, + handle->op = GNUNET_IDENTITY_create (identity_handle, handle->name, pk_ptr, &do_finished_create, @@ -1118,7 +1104,7 @@ ego_delete_pubkey (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, + handle->op = GNUNET_IDENTITY_delete (identity_handle, ego_entry->identifier, &do_finished, handle); @@ -1162,7 +1148,7 @@ ego_delete_name (struct GNUNET_REST_RequestHandle *con_handle, } handle->response_code = MHD_HTTP_NO_CONTENT; - handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, + handle->op = GNUNET_IDENTITY_delete (identity_handle, ego_entry->identifier, &do_finished, handle); @@ -1193,144 +1179,78 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_get_pubkey }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, - &ego_get_subsystem }, - { MHD_HTTP_METHOD_PUT, - GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_edit_pubkey }, - { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, - { MHD_HTTP_METHOD_PUT, - GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, - &ego_edit_subsystem }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_IDENTITY_PUBKEY, - &ego_delete_pubkey }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_IDENTITY_NAME, - &ego_delete_name }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - -/** - * If listing is enabled, prints information about the egos. - * - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param identifier identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ static void -init_egos (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *identifier) +list_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); - return; } - // Check if ego exists - for (ego_entry = handle->ego_head; NULL != ego_entry;) + /* Ego renamed or added */ + if (identifier != NULL) { - struct EgoEntry *tmp = ego_entry; - ego_entry = ego_entry->next; - if (ego != tmp->ego) - continue; - // Deleted - if (NULL == identifier) + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - tmp); - GNUNET_free (tmp->keystring); - GNUNET_free (tmp->identifier); - GNUNET_free (tmp); + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } } - else + if (NULL == ego_entry) { - // Renamed - GNUNET_free (tmp->identifier); - tmp->identifier = GNUNET_strdup (identifier); + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); return; } - // New ego - ego_entry = GNUNET_new (struct EgoEntry); - GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); - ego_entry->ego = ego; - GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, - ego_entry); } @@ -1346,12 +1266,38 @@ init_egos (void *cls, * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_get_pubkey }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, + &ego_get_subsystem }, + { MHD_HTTP_METHOD_PUT, + GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_edit_pubkey }, + { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name }, + { MHD_HTTP_METHOD_PUT, + GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM, + &ego_edit_subsystem }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_IDENTITY_PUBKEY, + &ego_delete_pubkey }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_IDENTITY_NAME, + &ego_delete_name }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, + GNUNET_REST_HANDLER_END }; + handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; @@ -1365,13 +1311,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1403,6 +1353,7 @@ libgnunet_plugin_rest_identity_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n")); return api; @@ -1420,8 +1371,21 @@ libgnunet_plugin_rest_identity_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); GNUNET_free (api); diff --git a/src/include/gnunet_rest_plugin.h b/src/include/gnunet_rest_plugin.h index 770ba66f2..96454f66b 100644 --- a/src/include/gnunet_rest_plugin.h +++ b/src/include/gnunet_rest_plugin.h @@ -69,10 +69,12 @@ struct GNUNET_REST_Plugin * @param data_size the length of the data * @param proc the callback for result * @param proc_cls closure for callback + * @return GNUNET_YES if the request was processed */ - void (*process_request) (struct GNUNET_REST_RequestHandle *handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls); + enum GNUNET_GenericReturnValue (*process_request)( + struct GNUNET_REST_RequestHandle *handle, + GNUNET_REST_ResultProcessor proc, + void *proc_cls); }; diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index f1cbfb38b..c993518ea 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c @@ -84,6 +84,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to NAMESTORE + */ +static struct GNUNET_NAMESTORE_Handle *ns_handle; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + /** * @brief struct returned by the initialization function of the plugin */ @@ -170,15 +195,6 @@ struct RequestHandle */ json_t *resp_object; - /** - * The processing state - */ - int state; - - /** - * Handle to NAMESTORE - */ - struct GNUNET_NAMESTORE_Handle *ns_handle; /** * Handle to NAMESTORE it @@ -195,26 +211,11 @@ struct RequestHandle */ struct EgoEntry *ego_entry; - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - /** * IDENTITY Operation */ struct GNUNET_IDENTITY_Operation *op; - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * Rest connection */ @@ -264,8 +265,6 @@ static void cleanup_handle (void *cls) { struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) @@ -294,21 +293,6 @@ cleanup_handle (void *cls) GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); if (NULL != handle->ns_qe) GNUNET_NAMESTORE_cancel (handle->ns_qe); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - if (NULL != handle->ns_handle) - { - GNUNET_NAMESTORE_disconnect (handle->ns_handle); - } - - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } if (NULL != handle->resp_object) { @@ -368,7 +352,7 @@ get_egoentry_namestore (struct RequestHandle *handle, char *name) if (NULL == name) return NULL; tmp = strtok (copy, "/"); - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (0 != strcasecmp (tmp, ego_entry->identifier)) @@ -647,7 +631,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, if (1 >= strlen (labelname)) { handle->list_it = - GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, + GNUNET_NAMESTORE_zone_iteration_start (ns_handle, handle->zone_pkey, &namestore_iteration_error, handle, @@ -664,7 +648,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, return; } handle->record_name = GNUNET_strdup (labelname + 1); - handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, handle->zone_pkey, handle->record_name, &ns_lookup_error_cb, @@ -699,7 +683,7 @@ ns_lookup_cb (void *cls, } for (j = 0; j < handle->rd_count; j++) rd_new[i + j] = handle->rd[j]; - handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, handle->zone_pkey, handle->record_name, i + j, @@ -791,7 +775,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle *con_handle, return; } handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, handle->zone_pkey, handle->record_name, &ns_lookup_error_cb, @@ -892,7 +876,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, } handle->record_name = GNUNET_strdup (labelname + 1); - handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, + handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, handle->zone_pkey, handle->record_name, 0, @@ -932,90 +916,79 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add }, - { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update }, - { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - -/** - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param name identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ static void -id_connect_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) +list_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; - GNUNET_asprintf (&ego_entry->identifier, "%s", name); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } + /* Ego renamed or added */ + if (identifier != NULL) + { + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } + } + if (NULL == ego_entry) + { + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); + } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + return; + } + } @@ -1030,12 +1003,20 @@ id_connect_cb (void *cls, * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add }, + { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update }, + { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; @@ -1048,14 +1029,18 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } - handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); - handle->identity_handle = - GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle); handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1087,6 +1072,8 @@ libgnunet_plugin_rest_namestore_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + ns_handle = GNUNET_NAMESTORE_connect (cfg); + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n")); return api; @@ -1104,8 +1091,23 @@ libgnunet_plugin_rest_namestore_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + if (NULL != ns_handle) + GNUNET_NAMESTORE_disconnect (ns_handle); + + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); GNUNET_free (api); diff --git a/src/peerinfo-tool/plugin_rest_peerinfo.c b/src/peerinfo-tool/plugin_rest_peerinfo.c index 1ab6d6f75..1d7461b1a 100644 --- a/src/peerinfo-tool/plugin_rest_peerinfo.c +++ b/src/peerinfo-tool/plugin_rest_peerinfo.c @@ -70,7 +70,12 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; /** * HTTP methods allows for this plugin */ -static char*allow_methods; +static char *allow_methods; + +/** + * Handle to PEERINFO + */ +static struct GNUNET_PEERINFO_Handle *peerinfo_handle; /** * @brief struct returned by the initialization function of the plugin @@ -204,10 +209,6 @@ struct RequestHandle */ struct GNUNET_PEERINFO_IteratorContext *list_it; - /** - * Handle to PEERINFO - */ - struct GNUNET_PEERINFO_Handle *peerinfo_handle; /** * Rest connection @@ -294,10 +295,10 @@ cleanup_handle (void *cls) GNUNET_PEERINFO_iterate_cancel (handle->list_it); handle->list_it = NULL; } - if (NULL != handle->peerinfo_handle) + if (NULL != peerinfo_handle) { - GNUNET_PEERINFO_disconnect (handle->peerinfo_handle); - handle->peerinfo_handle = NULL; + GNUNET_PEERINFO_disconnect (peerinfo_handle); + peerinfo_handle = NULL; } GNUNET_free (handle); @@ -664,7 +665,7 @@ peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle, // specific_peer = GNUNET_PEER_resolve2(peer_id); } - handle->list_it = GNUNET_PEERINFO_iterate (handle->peerinfo_handle, + handle->list_it = GNUNET_PEERINFO_iterate (peerinfo_handle, include_friend_only, specific_peer, &peerinfo_list_iteration, @@ -698,32 +699,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = { - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * Function processing the REST call * @@ -735,12 +710,18 @@ init_cont (struct RequestHandle *handle) * @param proc_cls closure for callback function * @return GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = { + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont }, + GNUNET_REST_HANDLER_END + }; handle->response_code = 0; handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, @@ -753,14 +734,20 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->peerinfo_handle = GNUNET_PEERINFO_connect (cfg); - init_cont (handle); + if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, + handlers, + &err, + handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -792,6 +779,7 @@ libgnunet_plugin_rest_peerinfo_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); + peerinfo_handle = GNUNET_PEERINFO_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Peerinfo REST API initialized\n")); diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index eb602a08f..64782fb72 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -248,6 +248,36 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + +/** + * GNS handle + */ +static struct GNUNET_GNS_Handle *gns_handle; + +/** + * Identity Provider + */ +static struct GNUNET_RECLAIM_Handle *idp; + /** * @brief struct returned by the initialization function of the plugin */ @@ -361,15 +391,6 @@ struct EgoEntry struct RequestHandle { - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; /** * Selected ego @@ -386,40 +407,15 @@ struct RequestHandle */ struct OIDC_Variables *oidc; - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - - /** - * Rest connection - */ - struct GNUNET_REST_RequestHandle *rest_handle; - - /** - * GNS handle - */ - struct GNUNET_GNS_Handle *gns_handle; - /** * GNS lookup op */ struct GNUNET_GNS_LookupRequest *gns_op; /** - * Handle to NAMESTORE - */ - struct GNUNET_NAMESTORE_Handle *namestore_handle; - - /** - * Iterator for NAMESTORE + * Rest connection */ - struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; + struct GNUNET_REST_RequestHandle *rest_handle; /** * Attribute claim list for id_token @@ -442,10 +438,6 @@ struct RequestHandle */ struct GNUNET_IDENTITY_Operation *op; - /** - * Identity Provider - */ - struct GNUNET_RECLAIM_Handle *idp; /** * Idp Operation @@ -529,6 +521,7 @@ struct RequestHandle int response_code; }; + /** * Cleanup lookup handle * @param handle Handle to clean up @@ -536,13 +529,10 @@ struct RequestHandle static void cleanup_handle (struct RequestHandle *handle) { - struct EgoEntry *ego_entry; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->timeout_task) GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); if (NULL != handle->attr_it) GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); if (NULL != handle->attest_it) @@ -551,8 +541,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); if (NULL != handle->idp_op) GNUNET_RECLAIM_cancel (handle->idp_op); - if (NULL != handle->idp) - GNUNET_RECLAIM_disconnect (handle->idp); GNUNET_free (handle->url); GNUNET_free (handle->tld); GNUNET_free (handle->redirect_prefix); @@ -561,11 +549,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_free (handle->edesc); if (NULL != handle->gns_op) GNUNET_GNS_lookup_cancel (handle->gns_op); - if (NULL != handle->gns_handle) - GNUNET_GNS_disconnect (handle->gns_handle); - - if (NULL != handle->namestore_handle) - GNUNET_NAMESTORE_disconnect (handle->namestore_handle); if (NULL != handle->oidc) { GNUNET_free (handle->oidc->client_id); @@ -585,15 +568,6 @@ cleanup_handle (struct RequestHandle *handle) if (NULL!=handle->attests_list) GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); - while (NULL != (ego_entry = handle->ego_head)) - { - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, - ego_entry); - GNUNET_free (ego_entry->identifier); - GNUNET_free (ego_entry->keystring); - GNUNET_free (ego_entry); - } GNUNET_free (handle); } @@ -993,7 +967,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) handle->redirect_prefix, handle->tld, handle->redirect_suffix, - (NULL == strchr(handle->redirect_suffix, '?') ? "?" : "&"), + (NULL == strchr (handle->redirect_suffix, '?') ? "?" : + "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1003,7 +978,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) GNUNET_asprintf (&redirect_uri, "%s%s%s=%s&state=%s", handle->oidc->redirect_uri, - (NULL == strchr(handle->oidc->redirect_uri, '?') ? "?" : "&"), + (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" : + "&"), handle->oidc->response_type, code_string, handle->oidc->state); @@ -1082,7 +1058,7 @@ oidc_attest_collect_finished_cb (void *cls) handle->attest_it = NULL; merged_list = attribute_list_merge (handle->attr_idtoken_list, handle->attr_userinfo_list); - handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp, &handle->priv_key, &handle->oidc->client_pkey, merged_list, @@ -1149,7 +1125,7 @@ oidc_attr_collect_finished_cb (void *cls) } handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList); handle->attest_it = - GNUNET_RECLAIM_get_attestations_start (handle->idp, + GNUNET_RECLAIM_get_attestations_start (idp, &handle->priv_key, &oidc_iteration_error, handle, @@ -1315,7 +1291,7 @@ code_redirect (void *cls) return; } // iterate over egos and compare their public key - for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; + for (handle->ego_entry = ego_head; NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); @@ -1323,13 +1299,12 @@ code_redirect (void *cls) { handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->attr_idtoken_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); handle->attr_userinfo_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); handle->attr_it = - GNUNET_RECLAIM_get_attributes_start (handle->idp, + GNUNET_RECLAIM_get_attributes_start (idp, &handle->priv_key, &oidc_iteration_error, handle, @@ -1474,7 +1449,7 @@ client_redirect (void *cls) /* Lookup client redirect uri to verify request */ handle->gns_op = - GNUNET_GNS_lookup (handle->gns_handle, + GNUNET_GNS_lookup (gns_handle, GNUNET_GNS_EMPTY_LABEL_AT, &handle->oidc->client_pkey, GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, @@ -1700,14 +1675,14 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, // If we know this identity, translated the corresponding TLD // TODO: We might want to have a reverse lookup functionality for TLDs? - for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) + for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) { priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) { handle->tld = GNUNET_strdup (tmp_ego->identifier); - handle->ego_entry = handle->ego_tail; + handle->ego_entry = ego_tail; } } handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); @@ -1790,6 +1765,7 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); } + static int parse_credentials_basic_auth (struct RequestHandle *handle, char **client_id, @@ -1847,8 +1823,8 @@ parse_credentials_basic_auth (struct RequestHandle *handle, static int parse_credentials_post_body (struct RequestHandle *handle, - char **client_id, - char **client_secret) + char **client_id, + char **client_secret) { struct GNUNET_HashCode cache_key; char *client_id_tmp; @@ -1861,8 +1837,9 @@ parse_credentials_post_body (struct RequestHandle *handle, ->url_param_map, &cache_key)) return GNUNET_SYSERR; - client_id_tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, - &cache_key); + client_id_tmp = GNUNET_CONTAINER_multihashmap_get ( + handle->rest_handle->url_param_map, + &cache_key); if (NULL == client_id_tmp) return GNUNET_SYSERR; *client_id = strdup (client_id_tmp); @@ -1896,13 +1873,16 @@ check_authorization (struct RequestHandle *handle, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client credentials in HTTP AuthZ header\n"); - } else if (GNUNET_OK == parse_credentials_post_body (handle, - &received_cid, - &received_cpw)) + } + else if (GNUNET_OK == parse_credentials_post_body (handle, + &received_cid, + &received_cpw)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client credentials in POST body\n"); - } else { + } + else + { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); handle->response_code = MHD_HTTP_UNAUTHORIZED; return GNUNET_SYSERR; @@ -1931,7 +1911,7 @@ check_authorization (struct RequestHandle *handle, return GNUNET_SYSERR; } // check client_id - for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; + for (handle->ego_entry = ego_head; NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) { if (0 == strcmp (handle->ego_entry->keystring, received_cid)) @@ -1963,7 +1943,7 @@ find_ego (struct RequestHandle *handle, struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); @@ -2321,14 +2301,13 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, return; } - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->oidc->response = json_object (); json_object_set_new (handle->oidc->response, "sub", json_string (iss_ego->keystring)); privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); - handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, privkey, ticket, consume_ticket, @@ -2337,36 +2316,6 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_AUTHORIZE, - &authorize_endpoint }, // url-encoded - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, - { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, - { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * If listing is enabled, prints information about the egos. * @@ -2406,18 +2355,16 @@ list_ego (void *cls, void **ctx, const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } GNUNET_assert (NULL != ego); - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); @@ -2425,15 +2372,15 @@ list_ego (void *cls, ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); return; } /* Ego renamed or added */ if (identifier != NULL) { - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (ego_entry->ego == ego) @@ -2452,15 +2399,15 @@ list_ego (void *cls, ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } } else { /* Delete */ - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { if (ego_entry->ego == ego) @@ -2469,8 +2416,8 @@ list_ego (void *cls, if (NULL == ego_entry) return; /* Not found */ - GNUNET_CONTAINER_DLL_remove (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, ego_entry); GNUNET_free (ego_entry->identifier); GNUNET_free (ego_entry->keystring); @@ -2480,12 +2427,23 @@ list_ego (void *cls, } -static void +static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, // url-encoded + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, + { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, + GNUNET_REST_HANDLER_END }; handle->oidc = GNUNET_new (struct OIDC_Variables); if (NULL == OIDC_cookie_jar_map) @@ -2495,19 +2453,17 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; handle->proc_cls = proc_cls; handle->proc = proc; - handle->state = ID_REST_STATE_INIT; handle->rest_handle = rest_handle; - handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); - handle->gns_handle = GNUNET_GNS_connect (cfg); - handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + return GNUNET_NO; + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -2532,6 +2488,11 @@ libgnunet_plugin_rest_openid_connect_init (void *cls) api->cls = &plugin; api->name = GNUNET_REST_API_NS_OIDC; api->process_request = &rest_identity_process_request; + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); + gns_handle = GNUNET_GNS_connect (cfg); + idp = GNUNET_RECLAIM_connect (cfg); + + state = ID_REST_STATE_INIT; GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s", MHD_HTTP_METHOD_GET, @@ -2557,6 +2518,7 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; plugin->cfg = NULL; @@ -2573,6 +2535,21 @@ libgnunet_plugin_rest_openid_connect_done (void *cls) GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); GNUNET_free (allow_methods); + if (NULL != gns_handle) + GNUNET_GNS_disconnect (gns_handle); + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + if (NULL != idp) + GNUNET_RECLAIM_disconnect (idp); + while (NULL != (ego_entry = ego_head)) + { + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + } GNUNET_free (api); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "OpenID Connect REST plugin is finished\n"); diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index 10ee2f801..eb442bc3b 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -87,6 +87,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg; */ static char *allow_methods; +/** + * Ego list + */ +static struct EgoEntry *ego_head; + +/** + * Ego list + */ +static struct EgoEntry *ego_tail; + +/** + * The processing state + */ +static int state; + +/** + * Handle to Identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity_handle; + +/** + * Identity Provider + */ +static struct GNUNET_RECLAIM_Handle *idp; + /** * @brief struct returned by the initialization function of the plugin */ @@ -129,15 +154,6 @@ struct EgoEntry struct RequestHandle { - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; /** * Selected ego @@ -149,16 +165,6 @@ struct RequestHandle */ struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - /** * Rest connection */ @@ -174,11 +180,6 @@ struct RequestHandle */ struct GNUNET_IDENTITY_Operation *op; - /** - * Identity Provider - */ - struct GNUNET_RECLAIM_Handle *idp; - /** * Idp Operation */ @@ -194,7 +195,6 @@ struct RequestHandle */ struct GNUNET_RECLAIM_AttestationIterator *attest_it; - /** * Ticket iterator */ @@ -251,51 +251,31 @@ struct RequestHandle * @param handle Handle to clean up */ static void -cleanup_handle (struct RequestHandle *handle) +cleanup_handle (void *cls) { - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; + struct RequestHandle *handle = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->resp_object) json_decref (handle->resp_object); if (NULL != handle->timeout_task) GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); if (NULL != handle->attr_it) GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); if (NULL != handle->attest_it) GNUNET_RECLAIM_get_attestations_stop (handle->attest_it); if (NULL != handle->ticket_it) GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); - if (NULL != handle->idp) - GNUNET_RECLAIM_disconnect (handle->idp); if (NULL != handle->url) GNUNET_free (handle->url); if (NULL != handle->emsg) GNUNET_free (handle->emsg); if (NULL != handle->attr_list) GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); - for (ego_entry = handle->ego_head; NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } GNUNET_free (handle); } -static void -cleanup_handle_delayed (void *cls) -{ - cleanup_handle (cls); -} - - /** * Task run on error, sends error message. Cleans up everything. * @@ -316,7 +296,7 @@ do_error (void *cls) resp = GNUNET_REST_create_response (json_error); MHD_add_response_header (resp, "Content-Type", "application/json"); handle->proc (handle->proc_cls, resp, handle->response_code); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); GNUNET_free (json_error); } @@ -339,9 +319,7 @@ do_timeout (void *cls) static void collect_error_cb (void *cls) { - struct RequestHandle *handle = cls; - - do_error (handle); + do_error (cls); } @@ -359,7 +337,7 @@ finished_cont (void *cls, int32_t success, const char *emsg) return; } handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); } @@ -376,7 +354,7 @@ delete_finished_cb (void *cls, int32_t success, const char *emsg) return; } handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); } @@ -485,7 +463,7 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, identity = handle->url + strlen ( GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -523,9 +501,8 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, */ if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) GNUNET_RECLAIM_id_generate (&attribute->id); - handle->idp = GNUNET_RECLAIM_connect (cfg); exp = GNUNET_TIME_UNIT_HOURS; - handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attestation_store (idp, identity_priv, attribute, &exp, @@ -644,7 +621,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, identity = handle->url + strlen ( GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -659,8 +636,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp, + handle->attest_it = GNUNET_RECLAIM_get_attestations_start (idp, priv_key, &collect_error_cb, handle, @@ -713,7 +689,7 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -727,11 +703,10 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation)); GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); attr.name = ""; - handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attestation_delete (idp, priv_key, &attr, &delete_finished_cb, @@ -768,7 +743,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -782,9 +757,8 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); handle->ticket_it = - GNUNET_RECLAIM_ticket_iteration_start (handle->idp, + GNUNET_RECLAIM_ticket_iteration_start (idp, priv_key, &collect_error_cb, handle, @@ -823,7 +797,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -862,9 +836,8 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, */ if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) GNUNET_RECLAIM_id_generate (&attribute->id); - handle->idp = GNUNET_RECLAIM_connect (cfg); exp = GNUNET_TIME_UNIT_HOURS; - handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attribute_store (idp, identity_priv, attribute, &exp, @@ -1012,7 +985,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -1027,8 +1000,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp, + handle->attr_it = GNUNET_RECLAIM_get_attributes_start (idp, priv_key, &collect_error_cb, handle, @@ -1078,7 +1050,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) if (0 == strcmp (identity, ego_entry->identifier)) break; @@ -1092,11 +1064,10 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute)); GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); attr.name = ""; - handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp, + handle->idp_op = GNUNET_RECLAIM_attribute_delete (idp, priv_key, &attr, &delete_finished_cb, @@ -1152,7 +1123,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); @@ -1169,8 +1140,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_revoke (idp, identity_priv, ticket, &finished_cont, @@ -1256,7 +1226,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, json_decref (data_json); return; } - for (ego_entry = handle->ego_head; NULL != ego_entry; + for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) { GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); @@ -1273,8 +1243,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, } identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); handle->resp_object = json_object (); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, + handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, identity_priv, ticket, &consume_cont, @@ -1307,55 +1276,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, } -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = - { { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &list_attribute_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &add_attribute_cont }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, - &delete_attribute_cont }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &list_attestation_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &add_attestation_cont }, - { MHD_HTTP_METHOD_DELETE, - GNUNET_REST_API_NS_RECLAIM_ATTESTATION, - &delete_attestation_cont }, - { MHD_HTTP_METHOD_GET, - GNUNET_REST_API_NS_IDENTITY_TICKETS, - &list_tickets_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_IDENTITY_REVOKE, - &revoke_ticket_cont }, - { MHD_HTTP_METHOD_POST, - GNUNET_REST_API_NS_IDENTITY_CONSUME, - &consume_ticket_cont }, - { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, - GNUNET_REST_HANDLER_END }; - - if (GNUNET_NO == - GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - - /** * If listing is enabled, prints information about the egos. * @@ -1395,52 +1315,126 @@ list_ego (void *cls, void **ctx, const char *identifier) { - struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_CRYPTO_EcdsaPublicKey pk; - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); + state = ID_REST_STATE_POST_INIT; return; } - if (ID_REST_STATE_INIT == handle->state) + if (ID_REST_STATE_INIT == state) { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, - handle->ego_tail, + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, ego_entry); } + /* Ego renamed or added */ + if (identifier != NULL) + { + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + { + /* Rename */ + GNUNET_free (ego_entry->identifier); + ego_entry->identifier = GNUNET_strdup (identifier); + break; + } + } + if (NULL == ego_entry) + { + /* Add */ + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail (ego_head, + ego_tail, + ego_entry); + } + } + else + { + /* Delete */ + for (ego_entry = ego_head; NULL != ego_entry; + ego_entry = ego_entry->next) + { + if (ego_entry->ego == ego) + break; + } + if (NULL == ego_entry) + return; /* Not found */ + + GNUNET_CONTAINER_DLL_remove (ego_head, + ego_tail, + ego_entry); + GNUNET_free (ego_entry->identifier); + GNUNET_free (ego_entry->keystring); + GNUNET_free (ego_entry); + return; + } + } -static void +static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) { struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = + { { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &delete_attribute_cont }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &list_attestation_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &add_attestation_cont }, + { MHD_HTTP_METHOD_DELETE, + GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &delete_attestation_cont }, + { MHD_HTTP_METHOD_GET, + GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont }, + { MHD_HTTP_METHOD_POST, + GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont }, + GNUNET_REST_HANDLER_END + }; handle->response_code = 0; handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; handle->proc_cls = proc_cls; handle->proc = proc; - handle->state = ID_REST_STATE_INIT; + state = ID_REST_STATE_INIT; handle->rest_handle = rest_handle; handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url) - 1] == '/') handle->url[strlen (handle->url) - 1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); + if (GNUNET_NO == + GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) + { + cleanup_handle (handle); + return GNUNET_NO; + } + handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); + return GNUNET_YES; } @@ -1472,7 +1466,8 @@ libgnunet_plugin_rest_reclaim_init (void *cls) MHD_HTTP_METHOD_PUT, MHD_HTTP_METHOD_DELETE, MHD_HTTP_METHOD_OPTIONS); - + identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); + idp = GNUNET_RECLAIM_connect (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity Provider REST API initialized\n")); return api; @@ -1490,8 +1485,22 @@ libgnunet_plugin_rest_reclaim_done (void *cls) { struct GNUNET_REST_Plugin *api = cls; struct Plugin *plugin = api->cls; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; plugin->cfg = NULL; + if (NULL != idp) + GNUNET_RECLAIM_disconnect (idp); + if (NULL != identity_handle) + GNUNET_IDENTITY_disconnect (identity_handle); + for (ego_entry = ego_head; NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } GNUNET_free (allow_methods); GNUNET_free (api); diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 519a27515..44d4f345e 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c @@ -114,11 +114,6 @@ static struct MHD_Response *failure_response; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Map of loaded plugins. - */ -static struct GNUNET_CONTAINER_MultiHashMap *plugin_map; - /** * Echo request Origin in CORS */ @@ -139,6 +134,38 @@ static char *allow_headers; */ static char *allow_credentials; +/** + * Plugin list head + */ +static struct PluginListEntry *plugins_head; + +/** + * Plugin list tail + */ +static struct PluginListEntry *plugins_tail; + +/** + * A plugin list entry + */ +struct PluginListEntry +{ + /* DLL */ + struct PluginListEntry *next; + + /* DLL */ + struct PluginListEntry *prev; + + /** + * libname (to cleanup) + */ + char *libname; + + /** + * The plugin + */ + struct GNUNET_REST_Plugin *plugin; +}; + /** * MHD Connection handle */ @@ -148,8 +175,6 @@ struct MhdConnectionHandle struct MHD_Response *response; - struct GNUNET_REST_Plugin *plugin; - struct GNUNET_REST_RequestHandle *data_handle; struct MHD_PostProcessor *pp; @@ -322,15 +347,15 @@ post_data_iter (void *cls, GNUNET_CRYPTO_hash (key, strlen (key), &hkey); val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map, - &hkey); + &hkey); if (NULL == val) { val = GNUNET_malloc (65536); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( - handle->url_param_map, - &hkey, - val, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + handle->url_param_map, + &hkey, + val, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not add url param '%s'\n", @@ -378,39 +403,21 @@ create_response (void *cls, size_t *upload_data_size, void **con_cls) { - char *plugin_name; char *origin; struct GNUNET_HashCode key; struct MhdConnectionHandle *con_handle; struct GNUNET_REST_RequestHandle *rest_conndata_handle; + struct PluginListEntry *ple; con_handle = *con_cls; if (NULL == *con_cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); - char tmp_url[strlen (url) + 1]; - strcpy (tmp_url, url); con_handle = GNUNET_new (struct MhdConnectionHandle); con_handle->con = con; con_handle->state = GN_REST_STATE_INIT; *con_cls = con_handle; - - plugin_name = strtok (tmp_url, "/"); - - if (NULL != plugin_name) - { - GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key); - - con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, &key); - } - if (NULL == con_handle->plugin) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n"); - GNUNET_free (con_handle); - return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); - } - return MHD_YES; } if (GN_REST_STATE_INIT == con_handle->state) @@ -445,9 +452,18 @@ create_response (void *cls, MHD_destroy_post_processor (con_handle->pp); con_handle->state = GN_REST_STATE_PROCESSING; - con_handle->plugin->process_request (rest_conndata_handle, - &plugin_callback, - con_handle); + for (ple = plugins_head; NULL != ple; ple = ple->next) + { + if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle, + &plugin_callback, + con_handle)) + break; /* Request handled */ + } + if (NULL == ple) + { + /** Request not handled **/ + MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response); + } *upload_data_size = 0; run_mhd_now (); return MHD_YES; @@ -732,6 +748,18 @@ do_accept (void *cls) static void do_shutdown (void *cls) { + struct PluginListEntry *ple; + + while (NULL != plugins_head) + { + ple = plugins_head; + GNUNET_CONTAINER_DLL_remove (plugins_head, + plugins_tail, + ple); + GNUNET_PLUGIN_unload (ple->libname, NULL); + GNUNET_free (ple->libname); + GNUNET_free (ple); + } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); kill_httpd (); GNUNET_free (allow_credentials); @@ -820,7 +848,7 @@ static void load_plugin (void *cls, const char *libname, void *lib_ret) { struct GNUNET_REST_Plugin *plugin = lib_ret; - struct GNUNET_HashCode key; + struct PluginListEntry *ple; if (NULL == lib_ret) { @@ -831,18 +859,12 @@ load_plugin (void *cls, const char *libname, void *lib_ret) } GNUNET_assert (1 < strlen (plugin->name)); GNUNET_assert ('/' == *plugin->name); - GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key); - if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( - plugin_map, - &key, - plugin, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Could not load add plugin `%s'\n", - libname); - return; - } + ple = GNUNET_new (struct PluginListEntry); + ple->libname = GNUNET_strdup (libname); + ple->plugin = plugin; + GNUNET_CONTAINER_DLL_insert (plugins_head, + plugins_tail, + ple); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); } @@ -864,8 +886,8 @@ run (void *cls, char *addr_str; cfg = c; - plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); - + plugins_head = NULL; + plugins_tail = NULL; /* Get port to bind to */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) diff --git a/src/rest/plugin_rest_config.c b/src/rest/plugin_rest_config.c index 43dea1b9f..d9ae57acd 100644 --- a/src/rest/plugin_rest_config.c +++ b/src/rest/plugin_rest_config.c @@ -347,7 +347,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, * @param proc_cls closure for @a proc * @return #GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) @@ -371,9 +371,10 @@ rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); + cleanup_handle (handle); + return GNUNET_NO; } + return GNUNET_YES; } diff --git a/src/rest/plugin_rest_copying.c b/src/rest/plugin_rest_copying.c index e601e505e..1649da3bb 100644 --- a/src/rest/plugin_rest_copying.c +++ b/src/rest/plugin_rest_copying.c @@ -81,24 +81,6 @@ cleanup_handle (struct RequestHandle *handle) } -/** - * Task run on shutdown. Cleans up everything. - * - * @param cls unused - * @param tc scheduler context - */ -static void -do_error (void *cls) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, handle->response_code); - cleanup_handle (handle); -} - - /** * Handle rest request * @@ -155,7 +137,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, * @param proc_cls closure for @a proc * @return #GNUNET_OK if request accepted */ -static void +static enum GNUNET_GenericReturnValue rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls) @@ -172,14 +154,10 @@ rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, handle->proc = proc; handle->rest_handle = conndata_handle; - if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } + return GNUNET_REST_handle_request (conndata_handle, + handlers, + &err, + handle); } -- cgit v1.2.3 From ade9b5e5248a97438ecb979f3be353f565a27ba1 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 4 Aug 2020 21:08:22 +0200 Subject: reclaim: fix #6463 --- src/reclaim/plugin_rest_openid_connect.c | 90 ++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 64782fb72..39eb9701a 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -41,11 +41,17 @@ #include "gnunet_signatures.h" #include "microhttpd.h" #include "oidc_helper.h" + /** * REST root namespace */ #define GNUNET_REST_API_NS_OIDC "/openid" +/** + * OIDC config + */ +#define GNUNET_REST_API_NS_OIDC_CONFIG "/.well-known/openid-configuration" + /** * Authorize endpoint */ @@ -2427,6 +2433,88 @@ list_ego (void *cls, } +static void +oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, + const char *url, + void *cls) +{ + json_t *oidc_config; + json_t *auth_methods; + json_t *sig_algs; + json_t *scopes; + json_t *response_types; + json_t *sub_types; + json_t *claim_types; + char *oidc_config_str; + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + oidc_config = json_object (); + // FIXME get from config? + json_object_set_new (oidc_config, + "issuer", json_string ("https://api.reclaim")); + json_object_set_new (oidc_config, + "authorization_endpoint", + json_string ("https://api.reclaim/openid/authorize")); + json_object_set_new (oidc_config, + "token_endpoint", + json_string ("http://localhost:7776/openid/token")); + auth_methods = json_array (); + json_array_append_new (auth_methods, + json_string ("client_secret_basic")); + json_array_append_new (auth_methods, + json_string ("client_secret_post")); + json_object_set_new (oidc_config, + "token_endpoint_auth_methods_supported", + auth_methods); + sig_algs = json_array (); + json_array_append_new (sig_algs, + json_string ("HS512")); + json_object_set_new (oidc_config, + "id_token_signing_alg_values_supported", + sig_algs); + json_object_set_new (oidc_config, + "userinfo_endpoint", + json_string ("http://localhost:7776/openid/userinfo")); + scopes = json_array (); + json_array_append_new (scopes, + json_string ("openid")); + json_array_append_new (scopes, + json_string ("profile")); + json_object_set_new (oidc_config, + "scopes_supported", + scopes); + response_types = json_array (); + json_array_append_new (response_types, + json_string ("code")); + json_object_set_new (oidc_config, + "response_types_supported", + response_types); + sub_types = json_array (); + json_array_append_new (sub_types, + json_string ("public")); /* no pairwise suppport */ + json_object_set_new (oidc_config, + "subject_types_supported", + sub_types); + claim_types = json_array (); + json_array_append_new (claim_types, + json_string ("normal")); + json_array_append_new (claim_types, + json_string ("aggregated")); + json_object_set_new (oidc_config, + "claim_types_supported", + claim_types); + json_object_set_new (oidc_config, + "claims_parameter_supported", + json_boolean (1)); + oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1)); + resp = GNUNET_REST_create_response (oidc_config_str); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (oidc_config_str); + cleanup_handle (handle); +} + + static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, @@ -2442,6 +2530,8 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint }, { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, + { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG, + &oidc_config_endpoint }, { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, GNUNET_REST_HANDLER_END }; -- cgit v1.2.3 From 6e764f4abd8a3f14f03a5a167af7d5cb703fd1d5 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Wed, 5 Aug 2020 11:35:05 +0200 Subject: reclaim: Make SPAs work with public clients. No longer encrypt code. --- src/reclaim/oidc_helper.c | 185 +++++++------------------------ src/reclaim/oidc_helper.h | 2 +- src/reclaim/plugin_rest_openid_connect.c | 58 +++++++++- 3 files changed, 93 insertions(+), 152 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index b48738cc4..4da387564 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -47,9 +47,9 @@ struct OIDC_Parameters struct GNUNET_RECLAIM_Ticket ticket; /** - * The nonce + * The nonce length */ - uint32_t nonce GNUNET_PACKED; + uint32_t nonce_len GNUNET_PACKED; /** * The length of the PKCE code_challenge @@ -326,89 +326,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, } -static void -derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, - struct GNUNET_HashCode *key_material) -{ - static const char ctx_key[] = "reclaim-aes-ctx-key"; - static const char ctx_iv[] = "reclaim-aes-ctx-iv"; - - GNUNET_CRYPTO_kdf (key, - sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), - ctx_key, - strlen (ctx_key), - key_material, - sizeof(struct GNUNET_HashCode), - NULL); - GNUNET_CRYPTO_kdf (iv, - sizeof( - struct GNUNET_CRYPTO_SymmetricInitializationVector), - ctx_iv, - strlen (ctx_iv), - key_material, - sizeof(struct GNUNET_HashCode), - NULL); -} - - -static void -calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, - const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub) -{ - struct GNUNET_HashCode key_material; - - GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material); - derive_aes_key (key, iv, &key_material); -} - - -static void -calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key, - struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, - const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, - const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv) -{ - struct GNUNET_HashCode key_material; - - GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material); - derive_aes_key (key, iv, &key_material); -} - - -static void -decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, - const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub, - const char *ct, - size_t ct_len, - char *buf) -{ - struct GNUNET_CRYPTO_SymmetricSessionKey key; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - - calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub); - GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf)); -} - - -static void -encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, - const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv, - const char *payload, - size_t payload_len, - char *buf) -{ - struct GNUNET_CRYPTO_SymmetricSessionKey key; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - - calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv); - GNUNET_break ( - GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf)); -} - - /** * Builds an OIDC authorization code including * a reclaim ticket and nonce @@ -439,34 +356,21 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, size_t attr_list_len = 0; size_t attests_list_len = 0; size_t code_challenge_len = 0; - uint32_t nonce; - uint32_t nonce_tmp; + uint32_t nonce_len = 0; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - struct GNUNET_CRYPTO_EcdhePrivateKey ecdh_priv; - struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub; /** PLAINTEXT **/ // Assign ticket memset (¶ms, 0, sizeof(params)); params.ticket = *ticket; // Assign nonce - nonce = 0; payload_len = sizeof(struct OIDC_Parameters); if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) { - if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) - { - GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str); - return NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got nonce: %u from %s\n", - nonce, - nonce_str); + nonce_len = strlen (nonce_str); + payload_len += nonce_len; } - nonce_tmp = htonl (nonce); - params.nonce = nonce_tmp; + params.nonce_len = htonl (nonce_len); // Assign code challenge if (NULL != code_challenge) code_challenge_len = strlen (code_challenge); @@ -506,6 +410,11 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, memcpy (tmp, code_challenge, code_challenge_len); tmp += code_challenge_len; } + if (0 < nonce_len) + { + memcpy (tmp, nonce_str, nonce_len); + tmp += nonce_len; + } if (0 < attr_list_len) GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); if (0 < attests_list_len) @@ -513,36 +422,24 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, /** END **/ - /** ENCRYPT **/ // Get length code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) + payload_len + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Length of data to encode: %lu\n", code_payload_len); - // Generate ECDH key - GNUNET_CRYPTO_ecdhe_key_create (&ecdh_priv); - GNUNET_CRYPTO_ecdhe_key_get_public (&ecdh_priv, &ecdh_pub); // Initialize code payload code_payload = GNUNET_malloc (code_payload_len); GNUNET_assert (NULL != code_payload); purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(ecdh_pub) + payload_len); + + payload_len); purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); // Store pubkey buf_ptr = (char *) &purpose[1]; - memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); - buf_ptr += sizeof(ecdh_pub); - // Encrypt plaintext and store - encrypt_payload (&ticket->audience, - &ecdh_priv, - payload, - payload_len, - buf_ptr); + memcpy (buf_ptr, payload, payload_len); GNUNET_free (payload); buf_ptr += payload_len; // Sign and store signature @@ -570,14 +467,16 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * * @param audience the expected audience of the code * @param code the string representation of the code - * @param code_verfier PKCE code verifier + * @param code_verfier PKCE code verifier. Optional, must be provided + * if used in request. * @param ticket where to store the ticket * @param attrs the attributes in the code - * @param nonce where to store the nonce + * @param attests the attestations in the code (if any) + * @param nonce_str where to store the nonce (if contained) * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int -OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, +OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, @@ -595,14 +494,12 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, char *code_verifier_hash; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; struct GNUNET_CRYPTO_EcdsaSignature *signature; - struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; - struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub; uint32_t code_challenge_len; uint32_t attrs_ser_len; uint32_t attests_ser_len; size_t plaintext_len; size_t code_payload_len; - uint32_t nonce = 0; + uint32_t nonce_len = 0; struct OIDC_Parameters *params; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); @@ -624,16 +521,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, plaintext_len = code_payload_len; plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); ptr = (char *) &purpose[1]; - // Public ECDH key - ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr; - ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey); - // Decrypt ciphertext plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); - plaintext = GNUNET_malloc (plaintext_len); - decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext); - // ptr = plaintext; + plaintext = ptr; ptr += plaintext_len; signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; params = (struct OIDC_Parameters *) plaintext; @@ -658,11 +549,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, // encode code verifier GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, &expected_code_challenge); - code_challenge = (char *) ¶ms[1]; + code_challenge = ((char *) ¶ms[1]); GNUNET_free (code_verifier_hash); - if ((strlen (expected_code_challenge) != code_challenge_len) || - (0 != - strncmp (expected_code_challenge, code_challenge, code_challenge_len))) + if (0 != + strncmp (expected_code_challenge, code_challenge, code_challenge_len)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier! Expected: %s, Got: %.*s\n", @@ -675,17 +565,23 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, } GNUNET_free (expected_code_challenge); } + nonce_len = ntohl (params->nonce_len); + if (0 != nonce_len) + { + *nonce_str = GNUNET_strndup (code_challenge + code_challenge_len, + nonce_len); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %s\n", *nonce_str); + } + // Ticket memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); - // Nonce - nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce); - // Signature - GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); - if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) + // Signature + //GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); + if (0 != GNUNET_memcmp (audience, &ticket->audience)) { GNUNET_free (code_payload); - GNUNET_free (plaintext); + 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; @@ -697,12 +593,13 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, &ticket->identity)) { GNUNET_free (code_payload); - GNUNET_free (plaintext); + if (NULL != nonce_str) + GNUNET_free (nonce_str); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); return GNUNET_SYSERR; } // Attributes - attrs_ser = ((char *) ¶ms[1]) + code_challenge_len; + attrs_ser = ((char *) ¶ms[1]) + code_challenge_len + nonce_len; attrs_ser_len = ntohl (params->attr_list_len); *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); attests_ser = ((char*) attrs_ser) + attrs_ser_len; @@ -710,11 +607,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, attests_ser_len); - *nonce_str = NULL; - if (nonce != 0) - GNUNET_asprintf (nonce_str, "%u", nonce); GNUNET_free (code_payload); - GNUNET_free (plaintext); return GNUNET_OK; } diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index e84087fc3..e71a7ad1c 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -90,7 +90,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int -OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, +OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 39eb9701a..238cffb85 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -525,6 +525,11 @@ struct RequestHandle * Reponse code */ int response_code; + + /** + * Public client + */ + int public_client; }; @@ -1872,6 +1877,7 @@ check_authorization (struct RequestHandle *handle, char *expected_pass; char *received_cid; char *received_cpw; + char *pkce_cv; if (GNUNET_OK == parse_credentials_basic_auth (handle, &received_cid, @@ -1889,9 +1895,24 @@ check_authorization (struct RequestHandle *handle, } else { - handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); - handle->response_code = MHD_HTTP_UNAUTHORIZED; - return GNUNET_SYSERR; + /** Allow public clients with PKCE **/ + pkce_cv = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); + if (NULL == pkce_cv) + { + handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); + handle->response_code = MHD_HTTP_UNAUTHORIZED; + return GNUNET_SYSERR; + } + handle->public_client = GNUNET_YES; + GNUNET_free (pkce_cv); + received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); + GNUNET_STRINGS_string_to_data (received_cid, + strlen (received_cid), + cid, + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_free (received_cid); + return GNUNET_OK; + } // check client password @@ -2063,7 +2084,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } // decode code - if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, + if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket, &cl, &al, &nonce)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); @@ -2452,7 +2473,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, oidc_config = json_object (); // FIXME get from config? json_object_set_new (oidc_config, - "issuer", json_string ("https://api.reclaim")); + "issuer", json_string ("http://localhost:7776")); json_object_set_new (oidc_config, "authorization_endpoint", json_string ("https://api.reclaim/openid/authorize")); @@ -2514,6 +2535,31 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, cleanup_handle (handle); } +/** + * Respond to OPTIONS request + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ +static void +oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, + const char *url, + void *cls) +{ + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + // For now, independent of path return all options + resp = GNUNET_REST_create_response (NULL); + MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); + MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*"); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + cleanup_handle (handle); + return; +} + + static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, @@ -2532,6 +2578,8 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint }, { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG, &oidc_config_endpoint }, + { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG, + &oidc_config_cors }, { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont }, GNUNET_REST_HANDLER_END }; -- cgit v1.2.3 From 1d4f5263ae72c12a42ec166ec8b1769620baaeda Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Thu, 6 Aug 2020 08:45:40 +0200 Subject: reclaim: Refactoring and more standards compliance with respect to scopes --- src/reclaim/oidc_helper.c | 313 ++++++++++++++++++++++++------- src/reclaim/oidc_helper.h | 30 ++- src/reclaim/plugin_rest_openid_connect.c | 198 +++++++------------ 3 files changed, 341 insertions(+), 200 deletions(-) (limited to 'src/reclaim/plugin_rest_openid_connect.c') diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index 4da387564..cb99a749d 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -69,6 +69,51 @@ struct OIDC_Parameters GNUNET_NETWORK_STRUCT_END +/** + * Standard claims represented by the "profile" scope in OIDC + */ +static char OIDC_profile_claims[14][32] = { + "name", "family_name", "given_name", "middle_name", "nickname", + "preferred_username", "profile", "picture", "website", "gender", "birthdate", + "zoneinfo", "locale", "updated_at" +}; + +/** + * Standard claims represented by the "email" scope in OIDC + */ +static char OIDC_email_claims[2][16] = { + "email", "email_verified" +}; + +/** + * Standard claims represented by the "phone" scope in OIDC + */ +static char OIDC_phone_claims[2][32] = { + "phone_number", "phone_number_verified" +}; + +/** + * Standard claims represented by the "address" scope in OIDC + */ +static char OIDC_address_claims[5][32] = { + "street_address", "locality", "region", "postal_code", "country" +}; + +static enum GNUNET_GenericReturnValue +is_claim_in_address_scope (const char *claim) +{ + int i; + for (i = 0; i < 5; i++) + { + if (0 == strcmp (claim, OIDC_address_claims[i])) + { + return GNUNET_YES; + } + } + return GNUNET_NO; +} + + static char * create_jwt_header (void) { @@ -109,49 +154,24 @@ fix_base64 (char *str) replace_char (str, '/', '_'); } - -/** - * Create a JWT from attributes - * - * @param aud_key the public of the audience - * @param sub_key the public key of the subject - * @param attrs the attribute list - * @param expiration_time the validity of the token - * @param secret_key the key used to sign the JWT - * @return a new base64-encoded JWT string. - */ -char * -OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - struct GNUNET_RECLAIM_AttributeList *attrs, - struct GNUNET_RECLAIM_AttestationList *attests, - const struct GNUNET_TIME_Relative *expiration_time, - const char *nonce, - const char *secret_key) +static json_t* +generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests) { struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_AttestationListEntry *ale; - struct GNUNET_HashCode signature; - struct GNUNET_TIME_Absolute exp_time; - struct GNUNET_TIME_Absolute time_now; - char *audience; char *subject; - char *header; - char *body_str; char *aggr_names_str; char *aggr_sources_str; char *source_name; - char *result; - char *header_base64; - char *body_base64; - char *signature_target; - char *signature_base64; char *attr_val_str; char *attest_val_str; json_t *body; json_t *aggr_names; json_t *aggr_sources; json_t *aggr_sources_jwt; + json_t *addr_claim; int num_attestations = 0; for (le = attrs->list_head; NULL != le; le = le->next) { @@ -159,22 +179,10 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, num_attestations++; } - // iat REQUIRED time now - time_now = GNUNET_TIME_absolute_get (); - // exp REQUIRED time expired from config - exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); - // auth_time only if max_age - // nonce only if nonce - // OPTIONAL acr,amr,azp subject = GNUNET_STRINGS_data_to_string_alloc (sub_key, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); - audience = - GNUNET_STRINGS_data_to_string_alloc (aud_key, - sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); - header = create_jwt_header (); body = json_object (); aggr_names = json_object (); aggr_sources = json_object (); @@ -185,23 +193,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); // sub REQUIRED public key identity, not exceed 255 ASCII length json_object_set_new (body, "sub", json_string (subject)); - // aud REQUIRED public key client_id must be there - json_object_set_new (body, "aud", json_string (audience)); - // iat - json_object_set_new (body, - "iat", - json_integer (time_now.abs_value_us / (1000 * 1000))); - // exp - json_object_set_new (body, - "exp", - json_integer (exp_time.abs_value_us / (1000 * 1000))); - // nbf - json_object_set_new (body, - "nbf", - json_integer (time_now.abs_value_us / (1000 * 1000))); - // nonce - if (NULL != nonce) - json_object_set_new (body, "nonce", json_string (nonce)); attest_val_str = NULL; aggr_names_str = NULL; aggr_sources_str = NULL; @@ -236,8 +227,28 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type, le->attribute->data, le->attribute->data_size); - json_object_set_new (body, le->attribute->name, - json_string (attr_val_str)); + /** + * There is this wierd quirk that the individual address claim(s) must be + * inside a JSON object of the "address" claim. + * FIXME: Possibly include formatted claim here + */ + if (GNUNET_YES == is_claim_in_address_scope (le->attribute->name)) + { + 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)); + + } + else + { + json_object_set_new (body, le->attribute->name, + json_string (attr_val_str)); + } GNUNET_free (attr_val_str); } else @@ -277,6 +288,102 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, json_decref (aggr_names); json_decref (aggr_sources); + return body; +} + +/** + * Generate userinfo JSON as string + * + * @param sub_key the subject (user) + * @param attrs user attribute list + * @param attests user attribute attestation list (may be empty) + * @return Userinfo JSON + */ +char * +OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests) +{ + char *body_str; + json_t* body = generate_userinfo_json (sub_key, + attrs, + attests); + body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); + json_decref (body); + return body_str; +} + + +/** + * Create a JWT from attributes + * + * @param aud_key the public of the audience + * @param sub_key the public key of the subject + * @param attrs the attribute list + * @param expiration_time the validity of the token + * @param secret_key the key used to sign the JWT + * @return a new base64-encoded JWT string. + */ +char * +OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests, + const struct GNUNET_TIME_Relative *expiration_time, + const char *nonce, + const char *secret_key) +{ + struct GNUNET_HashCode signature; + struct GNUNET_TIME_Absolute exp_time; + struct GNUNET_TIME_Absolute time_now; + char *audience; + char *subject; + char *header; + char *body_str; + char *result; + char *header_base64; + char *body_base64; + char *signature_target; + char *signature_base64; + json_t *body; + + body = generate_userinfo_json (sub_key, + attrs, + attests); + // iat REQUIRED time now + time_now = GNUNET_TIME_absolute_get (); + // exp REQUIRED time expired from config + exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time); + // auth_time only if max_age + // nonce only if nonce + // OPTIONAL acr,amr,azp + subject = + GNUNET_STRINGS_data_to_string_alloc (sub_key, + sizeof(struct + GNUNET_CRYPTO_EcdsaPublicKey)); + audience = + GNUNET_STRINGS_data_to_string_alloc (aud_key, + sizeof(struct + GNUNET_CRYPTO_EcdsaPublicKey)); + header = create_jwt_header (); + + // aud REQUIRED public key client_id must be there + json_object_set_new (body, "aud", json_string (audience)); + // iat + json_object_set_new (body, + "iat", + json_integer (time_now.abs_value_us / (1000 * 1000))); + // exp + json_object_set_new (body, + "exp", + json_integer (exp_time.abs_value_us / (1000 * 1000))); + // nbf + json_object_set_new (body, + "nbf", + json_integer (time_now.abs_value_us / (1000 * 1000))); + // nonce + if (NULL != nonce) + json_object_set_new (body, "nonce", json_string (nonce)); body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); json_decref (body); @@ -315,10 +422,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, GNUNET_free (signature_target); GNUNET_free (header); GNUNET_free (body_str); - if (NULL != aggr_sources_str) - GNUNET_free (aggr_sources_str); - if (NULL != aggr_names_str) - GNUNET_free (aggr_names_str); GNUNET_free (signature_base64); GNUNET_free (body_base64); GNUNET_free (header_base64); @@ -552,7 +655,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, code_challenge = ((char *) ¶ms[1]); GNUNET_free (code_verifier_hash); if (0 != - strncmp (expected_code_challenge, code_challenge, code_challenge_len)) + strncmp (expected_code_challenge, code_challenge, code_challenge_len)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid code verifier! Expected: %s, Got: %.*s\n", @@ -575,8 +678,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, // Ticket memcpy (ticket, ¶ms->ticket, sizeof(params->ticket)); - // Signature - //GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); + // Signature + // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); if (0 != GNUNET_memcmp (audience, &ticket->audience)) { GNUNET_free (code_payload); @@ -675,3 +778,77 @@ OIDC_access_token_parse (const char*token, return GNUNET_SYSERR; return GNUNET_OK; } + + +/** + * Checks if a claim is implicitly requested through standard + * scope(s) + * + * @param scopes the scopes which have been requested + * @param attr the attribute name to check + * @return GNUNET_YES if attribute is implcitly requested + */ +enum GNUNET_GenericReturnValue +OIDC_check_scopes_for_claim_request (const char*scopes, + const char*attr) +{ + char *scope_variables; + char *scope_variable; + char delimiter[] = " "; + int i; + + scope_variables = GNUNET_strdup (scopes); + scope_variable = strtok (scope_variables, delimiter); + while (NULL != scope_variable) + { + if (0 == strcmp ("profile", scope_variable)) + { + for (i = 0; i < 14; i++) + { + if (0 == strcmp (attr, OIDC_profile_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("address", scope_variable)) + { + for (i = 0; i < 5; i++) + { + if (0 == strcmp (attr, OIDC_address_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("email", scope_variable)) + { + for (i = 0; i < 2; i++) + { + if (0 == strcmp (attr, OIDC_email_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + } + else if (0 == strcmp ("phone", scope_variable)) + { + for (i = 0; i < 2; i++) + { + if (0 == strcmp (attr, OIDC_phone_claims[i])) + { + GNUNET_free (scope_variables); + return GNUNET_YES; + } + } + + } + scope_variable = strtok (NULL, delimiter); + } + GNUNET_free (scope_variables); + return GNUNET_NO; + +} diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index e71a7ad1c..e713dab62 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -49,7 +49,7 @@ * @return a new base64-encoded JWT string. */ char* -OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, +OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, struct GNUNET_RECLAIM_AttributeList *attrs, struct GNUNET_RECLAIM_AttestationList *attests, @@ -125,4 +125,32 @@ OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket); int OIDC_access_token_parse (const char* token, struct GNUNET_RECLAIM_Ticket **ticket); + + +/** + * Checks if a claim is implicitly requested through standard + * scope(s) + * + * @param scopes the scopes which have been requested + * @param attr the attribute name to check + * @return GNUNET_YES if attribute is implcitly requested + */ +enum GNUNET_GenericReturnValue +OIDC_check_scopes_for_claim_request (const char*scopes, + const char*attr); + + +/** + * Generate userinfo JSON as string + * + * @param sub_key the subject (user) + * @param attrs user attribute list + * @param attests user attribute attestation list (may be empty) + * @return Userinfo JSON + */ +char * +OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + struct GNUNET_RECLAIM_AttributeList *attrs, + struct GNUNET_RECLAIM_AttestationList *attests); + #endif diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 238cffb85..b294ba166 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -357,10 +357,6 @@ struct OIDC_Variables */ char *code_verifier; - /** - * The response JSON - */ - json_t *response; }; /** @@ -569,7 +565,6 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_free (handle->oidc->response_type); GNUNET_free (handle->oidc->scope); GNUNET_free (handle->oidc->state); - json_decref (handle->oidc->response); GNUNET_free (handle->oidc); } if (NULL!=handle->attr_idtoken_list) @@ -690,27 +685,6 @@ do_timeout (void *cls) } -/** - * Return attributes for claim - * - * @param cls the request handle - */ -static void -return_userinfo_response (void *cls) -{ - char *result_str; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - result_str = json_dumps (handle->oidc->response, 0); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - cleanup_handle (handle); -} - - /** * Respond to OPTIONS request * @@ -1153,9 +1127,6 @@ attr_in_claims_request (struct RequestHandle *handle, const char *attr_name, const char *claims_parameter) { - char *scope_variables; - char *scope_variable; - char delimiter[] = " "; int ret = GNUNET_NO; json_t *root; json_error_t error; @@ -1163,19 +1134,12 @@ attr_in_claims_request (struct RequestHandle *handle, const char *key; json_t *value; - scope_variables = GNUNET_strdup (handle->oidc->scope); - scope_variable = strtok (scope_variables, delimiter); - while (NULL != scope_variable) - { - if (0 == strcmp (attr_name, scope_variable)) - break; - scope_variable = strtok (NULL, delimiter); - } - if (NULL != scope_variable) - ret = GNUNET_YES; - GNUNET_free (scope_variables); + /** Check if attribute is requested through standard scope **/ + if (GNUNET_YES == OIDC_check_scopes_for_claim_request (handle->oidc->scope, + attr_name)) + return GNUNET_YES; - /** Try claims parameter if no in scope */ + /** Try claims parameter if not in scope */ if ((NULL != handle->oidc->claims) && (GNUNET_YES != ret)) { @@ -2122,13 +2086,13 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - id_token = OIDC_id_token_new (&ticket.audience, - &ticket.identity, - cl, - al, - &expiration_time, - (NULL != nonce) ? nonce : NULL, - jwt_secret); + id_token = OIDC_generate_id_token (&ticket.audience, + &ticket.identity, + cl, + al, + &expiration_time, + (NULL != nonce) ? nonce : NULL, + jwt_secret); access_token = OIDC_access_token_new (&ticket); OIDC_build_token_response (access_token, id_token, @@ -2159,83 +2123,55 @@ consume_ticket (void *cls, const struct GNUNET_RECLAIM_Attestation *attest) { struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_AttributeListEntry *ale; + struct GNUNET_RECLAIM_AttestationListEntry *atle; + struct MHD_Response *resp; + char *result_str; handle->idp_op = NULL; if (NULL == identity) { - GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); + 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); + resp = GNUNET_REST_create_response (result_str); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (result_str); + cleanup_handle (handle); return; } - if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->attestation)) + ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry); + ale->attribute = GNUNET_RECLAIM_attribute_new (attr->name, + &attr->attestation, + attr->type, + attr->data, + attr->data_size); + ale->attribute->id = attr->id; + ale->attribute->flag = attr->flag; + ale->attribute->attestation = attr->attestation; + GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head, + handle->attr_userinfo_list->list_tail, + ale); + for (atle = handle->attests_list->list_head; NULL != atle; atle = atle->next) + { + if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->attestation->id, + &attest->id)) + continue; + break; /** already in list **/ + } + if (NULL == atle) { - char *tmp_value; - json_t *value; - tmp_value = GNUNET_RECLAIM_attribute_value_to_string (attr->type, - attr->data, - attr->data_size); - value = json_string (tmp_value); - json_object_set_new (handle->oidc->response, attr->name, value); - GNUNET_free (tmp_value); - return; + /** Attestation matches for attribute, add **/ + atle = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry); + atle->attestation = GNUNET_RECLAIM_attestation_new (attest->name, + attest->type, + attest->data, + attest->data_size); + GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head, + handle->attests_list->list_tail, + atle); } - json_t *claim_sources; - json_t *claim_sources_jwt; - json_t *claim_names; - char *attest_val_str; - claim_sources = json_object_get (handle->oidc->response,"_claim_sources"); - claim_names = json_object_get (handle->oidc->response,"_claim_names"); - attest_val_str = - GNUNET_RECLAIM_attestation_value_to_string (attest->type, - attest->data, - attest->data_size); - if ((NULL == claim_sources) && (NULL == claim_names) ) - { - claim_sources = json_object (); - claim_names = json_object (); - } - char *source_name; - int i = 0; - GNUNET_asprintf (&source_name, "src%d", i); - while (NULL != (claim_sources_jwt = json_object_get (claim_sources, - source_name))) - { - if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt, - "JWT")), - attest_val_str)) - { - // Adapt only the claim names - json_object_set_new (claim_names, attr->data, - json_string (source_name)); - json_object_set (handle->oidc->response, - "_claim_names", claim_names); - break; - } - i++; - GNUNET_free (source_name); - GNUNET_asprintf (&source_name, "src%d", i); - } - - // Create new one - if (NULL == claim_sources_jwt) - { - claim_sources_jwt = json_object (); - // Set the JWT for names - json_object_set_new (claim_names, attr->data, - json_string (source_name)); - // Set the JWT for the inner source - json_object_set_new (claim_sources_jwt, "JWT", - json_string (attest_val_str)); - // Set the JWT for the source - json_object_set_new (claim_sources, source_name, claim_sources_jwt); - // Set as claims - json_object_set (handle->oidc->response, "_claim_names", claim_names); - json_object_set (handle->oidc->response, "_claim_sources",claim_sources); - } - - json_decref (claim_sources); - json_decref (claim_names); - json_decref (claim_sources_jwt); - GNUNET_free (attest_val_str); } @@ -2253,14 +2189,13 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, { // TODO expiration time struct RequestHandle *handle = cls; + struct GNUNET_RECLAIM_Ticket *ticket; char delimiter[] = " "; struct GNUNET_HashCode cache_key; char *authorization; char *authorization_type; char *authorization_access_token; - struct GNUNET_RECLAIM_Ticket *ticket; const struct EgoEntry *aud_ego; - const struct EgoEntry *iss_ego; const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, @@ -2316,9 +2251,10 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } GNUNET_assert (NULL != ticket); - aud_ego = find_ego (handle, &ticket->audience); - iss_ego = find_ego (handle, &ticket->identity); - if ((NULL == aud_ego) || (NULL == iss_ego)) + handle->ticket = *ticket; + GNUNET_free (ticket); + aud_ego = find_ego (handle, &handle->ticket.audience); + if (NULL == aud_ego) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); handle->edesc = GNUNET_strdup ("The access token expired"); @@ -2328,16 +2264,16 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, return; } - handle->oidc->response = json_object (); - json_object_set_new (handle->oidc->response, - "sub", - json_string (iss_ego->keystring)); privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego); + handle->attr_userinfo_list = + GNUNET_new (struct GNUNET_RECLAIM_AttributeList); + handle->attests_list = + GNUNET_new (struct GNUNET_RECLAIM_AttestationList); handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, privkey, - ticket, - consume_ticket, + &handle->ticket, + &consume_ticket, handle); GNUNET_free (authorization); } @@ -2535,6 +2471,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, cleanup_handle (handle); } + /** * Respond to OPTIONS request * @@ -2544,8 +2481,8 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, */ static void oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, - const char *url, - void *cls) + const char *url, + void *cls) { struct MHD_Response *resp; struct RequestHandle *handle = cls; @@ -2560,7 +2497,6 @@ oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, } - static enum GNUNET_GenericReturnValue rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, -- cgit v1.2.3 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/reclaim/plugin_rest_openid_connect.c') 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