aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2020-08-06 16:25:51 +0200
committert3sserakt <t3ss@posteo.de>2020-08-06 16:25:51 +0200
commit38193fe48a572e475b4f84717ff5b3edbcaf2d2a (patch)
treed6deeb56d81f75ab411d88a03b865f7da7eaaed4
parent33954ae13d4d26cefa45ac86f5e2184b6abd724f (diff)
parent6ab14a20690a499ad32e3f2ad448d64d4e6b65fc (diff)
downloadgnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.tar.gz
gnunet-38193fe48a572e475b4f84717ff5b3edbcaf2d2a.zip
Merge branch 'master' of ssh://gnunet.org/gnunet
-rw-r--r--contrib/Makefile.inc6
-rw-r--r--po/POTFILES.in98
-rw-r--r--src/gns/plugin_rest_gns.c65
-rw-r--r--src/identity/plugin_rest_identity.c290
-rw-r--r--src/include/gnunet_buffer_lib.h6
-rw-r--r--src/include/gnunet_rest_plugin.h8
-rw-r--r--src/include/gnunet_strings_lib.h24
-rw-r--r--src/namestore/namestore_api.c2
-rw-r--r--src/namestore/plugin_rest_namestore.c242
-rw-r--r--src/peerinfo-tool/plugin_rest_peerinfo.c66
-rw-r--r--src/reclaim/gnunet-service-reclaim.c4
-rw-r--r--src/reclaim/oidc_helper.c532
-rw-r--r--src/reclaim/oidc_helper.h39
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c823
-rw-r--r--src/reclaim/plugin_rest_reclaim.c296
-rw-r--r--src/reclaim/reclaim_api.c2
-rw-r--r--src/rest/gnunet-rest-server.c379
-rw-r--r--src/rest/plugin_rest_config.c7
-rw-r--r--src/rest/plugin_rest_copying.c32
-rw-r--r--src/transport/transport-testing2.c9
-rw-r--r--src/util/buffer.c21
-rw-r--r--src/util/strings.c158
-rw-r--r--src/util/test_strings.c14
23 files changed, 1828 insertions, 1295 deletions
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 @@
3# itself. 3# itself.
4 4
5BUILDCOMMON_SHLIB_FILES = \ 5BUILDCOMMON_SHLIB_FILES = \
6 build-common/sh/bin.sh/python.sh \
7 build-common/sh/lib.sh/existence.sh \
8 build-common/sh/lib.sh/existence_python.sh \
9 build-common/sh/lib.sh/msg.sh \
10 build-common/sh/lib.sh/progname.sh \
11 build-common/sh/lib.sh/version_gnunet.sh \
12 build-common/LICENSE 6 build-common/LICENSE
13 7
14BUILDCOMMON_CONF_FILES = \ 8BUILDCOMMON_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
10src/arm/gnunet-arm.c 10src/arm/gnunet-arm.c
11src/arm/gnunet-service-arm.c 11src/arm/gnunet-service-arm.c
12src/arm/mockup-service.c 12src/arm/mockup-service.c
13src/ats-tests/ats-testing-experiment.c
14src/ats-tests/ats-testing-log.c
15src/ats-tests/ats-testing-preferences.c
16src/ats-tests/ats-testing-traffic.c
17src/ats-tests/ats-testing.c
18src/ats-tests/gnunet-ats-sim.c
19src/ats-tests/gnunet-solver-eval.c
20src/ats-tool/gnunet-ats.c
13src/ats/ats_api_connectivity.c 21src/ats/ats_api_connectivity.c
14src/ats/ats_api_performance.c 22src/ats/ats_api_performance.c
15src/ats/ats_api_scanner.c 23src/ats/ats_api_scanner.c
16src/ats/ats_api_scheduling.c 24src/ats/ats_api_scheduling.c
17src/ats/gnunet-ats-solver-eval.c 25src/ats/gnunet-ats-solver-eval.c
18src/ats/gnunet-service-ats_addresses.c
19src/ats/gnunet-service-ats.c 26src/ats/gnunet-service-ats.c
27src/ats/gnunet-service-ats_addresses.c
20src/ats/gnunet-service-ats_connectivity.c 28src/ats/gnunet-service-ats_connectivity.c
21src/ats/gnunet-service-ats_normalization.c 29src/ats/gnunet-service-ats_normalization.c
22src/ats/gnunet-service-ats_performance.c 30src/ats/gnunet-service-ats_performance.c
@@ -25,14 +33,6 @@ src/ats/gnunet-service-ats_preferences.c
25src/ats/gnunet-service-ats_reservations.c 33src/ats/gnunet-service-ats_reservations.c
26src/ats/gnunet-service-ats_scheduling.c 34src/ats/gnunet-service-ats_scheduling.c
27src/ats/plugin_ats_proportional.c 35src/ats/plugin_ats_proportional.c
28src/ats-tests/ats-testing.c
29src/ats-tests/ats-testing-experiment.c
30src/ats-tests/ats-testing-log.c
31src/ats-tests/ats-testing-preferences.c
32src/ats-tests/ats-testing-traffic.c
33src/ats-tests/gnunet-ats-sim.c
34src/ats-tests/gnunet-solver-eval.c
35src/ats-tool/gnunet-ats.c
36src/auction/gnunet-auction-create.c 36src/auction/gnunet-auction-create.c
37src/auction/gnunet-auction-info.c 37src/auction/gnunet-auction-info.c
38src/auction/gnunet-auction-join.c 38src/auction/gnunet-auction-join.c
@@ -50,8 +50,8 @@ src/cadet/cadet_api_list_peers.c
50src/cadet/cadet_api_list_tunnels.c 50src/cadet/cadet_api_list_tunnels.c
51src/cadet/cadet_test_lib.c 51src/cadet/cadet_test_lib.c
52src/cadet/desirability_table.c 52src/cadet/desirability_table.c
53src/cadet/gnunet-cadet.c
54src/cadet/gnunet-cadet-profiler.c 53src/cadet/gnunet-cadet-profiler.c
54src/cadet/gnunet-cadet.c
55src/cadet/gnunet-service-cadet.c 55src/cadet/gnunet-service-cadet.c
56src/cadet/gnunet-service-cadet_channel.c 56src/cadet/gnunet-service-cadet_channel.c
57src/cadet/gnunet-service-cadet_connection.c 57src/cadet/gnunet-service-cadet_connection.c
@@ -67,15 +67,15 @@ src/consensus/gnunet-service-consensus.c
67src/consensus/plugin_block_consensus.c 67src/consensus/plugin_block_consensus.c
68src/conversation/conversation_api.c 68src/conversation/conversation_api.c
69src/conversation/conversation_api_call.c 69src/conversation/conversation_api_call.c
70src/conversation/gnunet-conversation.c
71src/conversation/gnunet-conversation-test.c 70src/conversation/gnunet-conversation-test.c
72src/conversation/gnunet_gst.c 71src/conversation/gnunet-conversation.c
73src/conversation/gnunet_gst_test.c
74src/conversation/gnunet-helper-audio-playback.c
75src/conversation/gnunet-helper-audio-playback-gst.c 72src/conversation/gnunet-helper-audio-playback-gst.c
76src/conversation/gnunet-helper-audio-record.c 73src/conversation/gnunet-helper-audio-playback.c
77src/conversation/gnunet-helper-audio-record-gst.c 74src/conversation/gnunet-helper-audio-record-gst.c
75src/conversation/gnunet-helper-audio-record.c
78src/conversation/gnunet-service-conversation.c 76src/conversation/gnunet-service-conversation.c
77src/conversation/gnunet_gst.c
78src/conversation/gnunet_gst_test.c
79src/conversation/microphone.c 79src/conversation/microphone.c
80src/conversation/plugin_gnsrecord_conversation.c 80src/conversation/plugin_gnsrecord_conversation.c
81src/conversation/speaker.c 81src/conversation/speaker.c
@@ -105,7 +105,6 @@ src/dht/dht_api.c
105src/dht/dht_test_lib.c 105src/dht/dht_test_lib.c
106src/dht/gnunet-dht-get.c 106src/dht/gnunet-dht-get.c
107src/dht/gnunet-dht-monitor.c 107src/dht/gnunet-dht-monitor.c
108src/dht/gnunet_dht_profiler.c
109src/dht/gnunet-dht-put.c 108src/dht/gnunet-dht-put.c
110src/dht/gnunet-service-dht.c 109src/dht/gnunet-service-dht.c
111src/dht/gnunet-service-dht_clients.c 110src/dht/gnunet-service-dht_clients.c
@@ -114,6 +113,7 @@ src/dht/gnunet-service-dht_hello.c
114src/dht/gnunet-service-dht_neighbours.c 113src/dht/gnunet-service-dht_neighbours.c
115src/dht/gnunet-service-dht_nse.c 114src/dht/gnunet-service-dht_nse.c
116src/dht/gnunet-service-dht_routing.c 115src/dht/gnunet-service-dht_routing.c
116src/dht/gnunet_dht_profiler.c
117src/dht/plugin_block_dht.c 117src/dht/plugin_block_dht.c
118src/dns/dns_api.c 118src/dns/dns_api.c
119src/dns/gnunet-dns-monitor.c 119src/dns/gnunet-dns-monitor.c
@@ -148,8 +148,8 @@ src/fs/gnunet-auto-share.c
148src/fs/gnunet-daemon-fsprofiler.c 148src/fs/gnunet-daemon-fsprofiler.c
149src/fs/gnunet-directory.c 149src/fs/gnunet-directory.c
150src/fs/gnunet-download.c 150src/fs/gnunet-download.c
151src/fs/gnunet-fs.c
152src/fs/gnunet-fs-profiler.c 151src/fs/gnunet-fs-profiler.c
152src/fs/gnunet-fs.c
153src/fs/gnunet-helper-fs-publish.c 153src/fs/gnunet-helper-fs-publish.c
154src/fs/gnunet-publish.c 154src/fs/gnunet-publish.c
155src/fs/gnunet-search.c 155src/fs/gnunet-search.c
@@ -169,9 +169,9 @@ src/gns/gns_tld_api.c
169src/gns/gnunet-bcd.c 169src/gns/gnunet-bcd.c
170src/gns/gnunet-dns2gns.c 170src/gns/gnunet-dns2gns.c
171src/gns/gnunet-gns-benchmark.c 171src/gns/gnunet-gns-benchmark.c
172src/gns/gnunet-gns.c
173src/gns/gnunet-gns-import.c 172src/gns/gnunet-gns-import.c
174src/gns/gnunet-gns-proxy.c 173src/gns/gnunet-gns-proxy.c
174src/gns/gnunet-gns.c
175src/gns/gnunet-service-gns.c 175src/gns/gnunet-service-gns.c
176src/gns/gnunet-service-gns_interceptor.c 176src/gns/gnunet-service-gns_interceptor.c
177src/gns/gnunet-service-gns_resolver.c 177src/gns/gnunet-service-gns_resolver.c
@@ -188,8 +188,8 @@ src/gnsrecord/gnunet-gnsrecord-tvg.c
188src/gnsrecord/plugin_gnsrecord_dns.c 188src/gnsrecord/plugin_gnsrecord_dns.c
189src/hello/address.c 189src/hello/address.c
190src/hello/gnunet-hello.c 190src/hello/gnunet-hello.c
191src/hello/hello.c
192src/hello/hello-ng.c 191src/hello/hello-ng.c
192src/hello/hello.c
193src/hostlist/gnunet-daemon-hostlist.c 193src/hostlist/gnunet-daemon-hostlist.c
194src/hostlist/gnunet-daemon-hostlist_client.c 194src/hostlist/gnunet-daemon-hostlist_client.c
195src/hostlist/gnunet-daemon-hostlist_server.c 195src/hostlist/gnunet-daemon-hostlist_server.c
@@ -214,8 +214,8 @@ src/namecache/namecache_api.c
214src/namecache/plugin_namecache_flat.c 214src/namecache/plugin_namecache_flat.c
215src/namecache/plugin_namecache_postgres.c 215src/namecache/plugin_namecache_postgres.c
216src/namecache/plugin_namecache_sqlite.c 216src/namecache/plugin_namecache_sqlite.c
217src/namestore/gnunet-namestore.c
218src/namestore/gnunet-namestore-fcfsd.c 217src/namestore/gnunet-namestore-fcfsd.c
218src/namestore/gnunet-namestore.c
219src/namestore/gnunet-service-namestore.c 219src/namestore/gnunet-service-namestore.c
220src/namestore/gnunet-zoneimport.c 220src/namestore/gnunet-zoneimport.c
221src/namestore/namestore_api.c 221src/namestore/namestore_api.c
@@ -241,17 +241,17 @@ src/nat/gnunet-service-nat_mini.c
241src/nat/gnunet-service-nat_stun.c 241src/nat/gnunet-service-nat_stun.c
242src/nat/nat_api.c 242src/nat/nat_api.c
243src/nat/nat_api_stun.c 243src/nat/nat_api_stun.c
244src/nse/gnunet-nse.c
245src/nse/gnunet-nse-profiler.c 244src/nse/gnunet-nse-profiler.c
245src/nse/gnunet-nse.c
246src/nse/gnunet-service-nse.c 246src/nse/gnunet-service-nse.c
247src/nse/nse_api.c 247src/nse/nse_api.c
248src/nt/nt.c 248src/nt/nt.c
249src/peerinfo/gnunet-service-peerinfo.c
250src/peerinfo/peerinfo_api.c
251src/peerinfo/peerinfo_api_notify.c
252src/peerinfo-tool/gnunet-peerinfo.c 249src/peerinfo-tool/gnunet-peerinfo.c
253src/peerinfo-tool/gnunet-peerinfo_plugins.c 250src/peerinfo-tool/gnunet-peerinfo_plugins.c
254src/peerinfo-tool/plugin_rest_peerinfo.c 251src/peerinfo-tool/plugin_rest_peerinfo.c
252src/peerinfo/gnunet-service-peerinfo.c
253src/peerinfo/peerinfo_api.c
254src/peerinfo/peerinfo_api_notify.c
255src/peerstore/gnunet-peerstore.c 255src/peerstore/gnunet-peerstore.c
256src/peerstore/gnunet-service-peerstore.c 256src/peerstore/gnunet-service-peerstore.c
257src/peerstore/peerstore_api.c 257src/peerstore/peerstore_api.c
@@ -297,27 +297,27 @@ src/rest/gnunet-rest-server.c
297src/rest/plugin_rest_config.c 297src/rest/plugin_rest_config.c
298src/rest/plugin_rest_copying.c 298src/rest/plugin_rest_copying.c
299src/rest/rest.c 299src/rest/rest.c
300src/revocation/gnunet-revocation.c
301src/revocation/gnunet-revocation-tvg.c 300src/revocation/gnunet-revocation-tvg.c
301src/revocation/gnunet-revocation.c
302src/revocation/gnunet-service-revocation.c 302src/revocation/gnunet-service-revocation.c
303src/revocation/plugin_block_revocation.c 303src/revocation/plugin_block_revocation.c
304src/revocation/revocation_api.c 304src/revocation/revocation_api.c
305src/rps/gnunet-rps.c
306src/rps/gnunet-rps-profiler.c 305src/rps/gnunet-rps-profiler.c
306src/rps/gnunet-rps.c
307src/rps/gnunet-service-rps.c 307src/rps/gnunet-service-rps.c
308src/rps/gnunet-service-rps_custommap.c 308src/rps/gnunet-service-rps_custommap.c
309src/rps/gnunet-service-rps_sampler.c 309src/rps/gnunet-service-rps_sampler.c
310src/rps/gnunet-service-rps_sampler_elem.c 310src/rps/gnunet-service-rps_sampler_elem.c
311src/rps/gnunet-service-rps_view.c 311src/rps/gnunet-service-rps_view.c
312src/rps/rps_api.c
313src/rps/rps-sampler_client.c 312src/rps/rps-sampler_client.c
314src/rps/rps-sampler_common.c 313src/rps/rps-sampler_common.c
315src/rps/rps-test_util.c 314src/rps/rps-test_util.c
315src/rps/rps_api.c
316src/scalarproduct/gnunet-scalarproduct.c 316src/scalarproduct/gnunet-scalarproduct.c
317src/scalarproduct/gnunet-service-scalarproduct_alice.c
318src/scalarproduct/gnunet-service-scalarproduct_bob.c
319src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c 317src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
320src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c 318src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
319src/scalarproduct/gnunet-service-scalarproduct_alice.c
320src/scalarproduct/gnunet-service-scalarproduct_bob.c
321src/scalarproduct/scalarproduct_api.c 321src/scalarproduct/scalarproduct_api.c
322src/secretsharing/gnunet-secretsharing-profiler.c 322src/secretsharing/gnunet-secretsharing-profiler.c
323src/secretsharing/gnunet-service-secretsharing.c 323src/secretsharing/gnunet-service-secretsharing.c
@@ -343,15 +343,16 @@ src/statistics/gnunet-statistics.c
343src/statistics/statistics_api.c 343src/statistics/statistics_api.c
344src/template/gnunet-service-template.c 344src/template/gnunet-service-template.c
345src/template/gnunet-template.c 345src/template/gnunet-template.c
346src/testbed-logger/gnunet-service-testbed-logger.c
347src/testbed-logger/testbed_logger_api.c
346src/testbed/generate-underlay-topology.c 348src/testbed/generate-underlay-topology.c
347src/testbed/gnunet-daemon-latency-logger.c 349src/testbed/gnunet-daemon-latency-logger.c
348src/testbed/gnunet-daemon-testbed-blacklist.c 350src/testbed/gnunet-daemon-testbed-blacklist.c
349src/testbed/gnunet-daemon-testbed-underlay.c 351src/testbed/gnunet-daemon-testbed-underlay.c
350src/testbed/gnunet-helper-testbed.c 352src/testbed/gnunet-helper-testbed.c
351src/testbed/gnunet_mpi_test.c
352src/testbed/gnunet-service-test-barriers.c 353src/testbed/gnunet-service-test-barriers.c
353src/testbed/gnunet-service-testbed_barriers.c
354src/testbed/gnunet-service-testbed.c 354src/testbed/gnunet-service-testbed.c
355src/testbed/gnunet-service-testbed_barriers.c
355src/testbed/gnunet-service-testbed_cache.c 356src/testbed/gnunet-service-testbed_cache.c
356src/testbed/gnunet-service-testbed_connectionpool.c 357src/testbed/gnunet-service-testbed_connectionpool.c
357src/testbed/gnunet-service-testbed_cpustatus.c 358src/testbed/gnunet-service-testbed_cpustatus.c
@@ -359,20 +360,19 @@ src/testbed/gnunet-service-testbed_links.c
359src/testbed/gnunet-service-testbed_meminfo.c 360src/testbed/gnunet-service-testbed_meminfo.c
360src/testbed/gnunet-service-testbed_oc.c 361src/testbed/gnunet-service-testbed_oc.c
361src/testbed/gnunet-service-testbed_peers.c 362src/testbed/gnunet-service-testbed_peers.c
362src/testbed/gnunet_testbed_mpi_spawn.c
363src/testbed/gnunet-testbed-profiler.c 363src/testbed/gnunet-testbed-profiler.c
364src/testbed-logger/gnunet-service-testbed-logger.c 364src/testbed/gnunet_mpi_test.c
365src/testbed-logger/testbed_logger_api.c 365src/testbed/gnunet_testbed_mpi_spawn.c
366src/testbed/testbed_api_barriers.c
367src/testbed/testbed_api.c 366src/testbed/testbed_api.c
367src/testbed/testbed_api_barriers.c
368src/testbed/testbed_api_hosts.c 368src/testbed/testbed_api_hosts.c
369src/testbed/testbed_api_operations.c 369src/testbed/testbed_api_operations.c
370src/testbed/testbed_api_peers.c 370src/testbed/testbed_api_peers.c
371src/testbed/testbed_api_sd.c 371src/testbed/testbed_api_sd.c
372src/testbed/testbed_api_services.c 372src/testbed/testbed_api_services.c
373src/testbed/testbed_api_statistics.c 373src/testbed/testbed_api_statistics.c
374src/testbed/testbed_api_testbed.c
375src/testbed/testbed_api_test.c 374src/testbed/testbed_api_test.c
375src/testbed/testbed_api_testbed.c
376src/testbed/testbed_api_topology.c 376src/testbed/testbed_api_topology.c
377src/testbed/testbed_api_underlay.c 377src/testbed/testbed_api_underlay.c
378src/testing/gnunet-testing.c 378src/testing/gnunet-testing.c
@@ -384,34 +384,40 @@ src/transport/gnunet-communicator-tcp.c
384src/transport/gnunet-communicator-udp.c 384src/transport/gnunet-communicator-udp.c
385src/transport/gnunet-communicator-unix.c 385src/transport/gnunet-communicator-unix.c
386src/transport/gnunet-helper-transport-bluetooth.c 386src/transport/gnunet-helper-transport-bluetooth.c
387src/transport/gnunet-helper-transport-wlan.c
388src/transport/gnunet-helper-transport-wlan-dummy.c 387src/transport/gnunet-helper-transport-wlan-dummy.c
388src/transport/gnunet-helper-transport-wlan.c
389src/transport/gnunet-service-tng.c 389src/transport/gnunet-service-tng.c
390src/transport/gnunet-service-transport_ats.c
391src/transport/gnunet-service-transport.c 390src/transport/gnunet-service-transport.c
391src/transport/gnunet-service-transport_ats.c
392src/transport/gnunet-service-transport_hello.c 392src/transport/gnunet-service-transport_hello.c
393src/transport/gnunet-service-transport_manipulation.c 393src/transport/gnunet-service-transport_manipulation.c
394src/transport/gnunet-service-transport_neighbours.c 394src/transport/gnunet-service-transport_neighbours.c
395src/transport/gnunet-service-transport_plugins.c 395src/transport/gnunet-service-transport_plugins.c
396src/transport/gnunet-service-transport_validation.c 396src/transport/gnunet-service-transport_validation.c
397src/transport/gnunet-transport.c
398src/transport/gnunet-transport-profiler.c 397src/transport/gnunet-transport-profiler.c
399src/transport/gnunet-transport-wlan-receiver.c 398src/transport/gnunet-transport-wlan-receiver.c
400src/transport/gnunet-transport-wlan-sender.c 399src/transport/gnunet-transport-wlan-sender.c
400src/transport/gnunet-transport.c
401src/transport/plugin_transport_http_client.c 401src/transport/plugin_transport_http_client.c
402src/transport/plugin_transport_http_common.c 402src/transport/plugin_transport_http_common.c
403src/transport/plugin_transport_http_server.c 403src/transport/plugin_transport_http_server.c
404src/transport/plugin_transport_smtp.c 404src/transport/plugin_transport_smtp.c
405src/transport/plugin_transport_tcp.c 405src/transport/plugin_transport_tcp.c
406src/transport/plugin_transport_template.c 406src/transport/plugin_transport_template.c
407src/transport/plugin_transport_udp_broadcasting.c
408src/transport/plugin_transport_udp.c 407src/transport/plugin_transport_udp.c
408src/transport/plugin_transport_udp_broadcasting.c
409src/transport/plugin_transport_unix.c 409src/transport/plugin_transport_unix.c
410src/transport/plugin_transport_wlan.c 410src/transport/plugin_transport_wlan.c
411src/transport/tcp_connection_legacy.c 411src/transport/tcp_connection_legacy.c
412src/transport/tcp_server_legacy.c 412src/transport/tcp_server_legacy.c
413src/transport/tcp_server_mst_legacy.c 413src/transport/tcp_server_mst_legacy.c
414src/transport/tcp_service_legacy.c 414src/transport/tcp_service_legacy.c
415src/transport/transport-testing-filenames.c
416src/transport/transport-testing-loggers.c
417src/transport/transport-testing-main.c
418src/transport/transport-testing-send.c
419src/transport/transport-testing.c
420src/transport/transport-testing2.c
415src/transport/transport_api2_application.c 421src/transport/transport_api2_application.c
416src/transport/transport_api2_communication.c 422src/transport/transport_api2_communication.c
417src/transport/transport_api2_core.c 423src/transport/transport_api2_core.c
@@ -424,12 +430,6 @@ src/transport/transport_api_manipulation.c
424src/transport/transport_api_monitor_peers.c 430src/transport/transport_api_monitor_peers.c
425src/transport/transport_api_monitor_plugins.c 431src/transport/transport_api_monitor_plugins.c
426src/transport/transport_api_offer_hello.c 432src/transport/transport_api_offer_hello.c
427src/transport/transport-testing2.c
428src/transport/transport-testing.c
429src/transport/transport-testing-filenames.c
430src/transport/transport-testing-loggers.c
431src/transport/transport-testing-main.c
432src/transport/transport-testing-send.c
433src/util/bandwidth.c 433src/util/bandwidth.c
434src/util/benchmark.c 434src/util/benchmark.c
435src/util/bio.c 435src/util/bio.c
@@ -444,8 +444,8 @@ src/util/consttime_memcmp.c
444src/util/container_bloomfilter.c 444src/util/container_bloomfilter.c
445src/util/container_heap.c 445src/util/container_heap.c
446src/util/container_meta_data.c 446src/util/container_meta_data.c
447src/util/container_multihashmap32.c
448src/util/container_multihashmap.c 447src/util/container_multihashmap.c
448src/util/container_multihashmap32.c
449src/util/container_multipeermap.c 449src/util/container_multipeermap.c
450src/util/container_multishortmap.c 450src/util/container_multishortmap.c
451src/util/container_multiuuidmap.c 451src/util/container_multiuuidmap.c
@@ -469,8 +469,8 @@ src/util/dnsparser.c
469src/util/dnsstub.c 469src/util/dnsstub.c
470src/util/getopt.c 470src/util/getopt.c
471src/util/getopt_helpers.c 471src/util/getopt_helpers.c
472src/util/gnunet-config.c
473src/util/gnunet-config-diff.c 472src/util/gnunet-config-diff.c
473src/util/gnunet-config.c
474src/util/gnunet-crypto-tvg.c 474src/util/gnunet-crypto-tvg.c
475src/util/gnunet-ecc.c 475src/util/gnunet-ecc.c
476src/util/gnunet-qr.c 476src/util/gnunet-qr.c
@@ -507,8 +507,8 @@ src/vpn/gnunet-helper-vpn.c
507src/vpn/gnunet-service-vpn.c 507src/vpn/gnunet-service-vpn.c
508src/vpn/gnunet-vpn.c 508src/vpn/gnunet-vpn.c
509src/vpn/vpn_api.c 509src/vpn/vpn_api.c
510src/zonemaster/gnunet-service-zonemaster.c
511src/zonemaster/gnunet-service-zonemaster-monitor.c 510src/zonemaster/gnunet-service-zonemaster-monitor.c
511src/zonemaster/gnunet-service-zonemaster.c
512src/fs/fs_api.h 512src/fs/fs_api.h
513src/testbed/testbed_api.h 513src/testbed/testbed_api.h
514src/testbed/testbed_api_operations.h 514src/testbed/testbed_api_operations.h
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
@@ -63,6 +63,11 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
63static char *allow_methods; 63static char *allow_methods;
64 64
65/** 65/**
66 * Connection to GNS
67 */
68static struct GNUNET_GNS_Handle *gns;
69
70/**
66 * @brief struct returned by the initialization function of the plugin 71 * @brief struct returned by the initialization function of the plugin
67 */ 72 */
68struct Plugin 73struct Plugin
@@ -76,11 +81,6 @@ struct Plugin
76struct RequestHandle 81struct RequestHandle
77{ 82{
78 /** 83 /**
79 * Connection to GNS
80 */
81 struct GNUNET_GNS_Handle *gns;
82
83 /**
84 * Active GNS lookup 84 * Active GNS lookup
85 */ 85 */
86 struct GNUNET_GNS_LookupWithTldRequest *gns_lookup; 86 struct GNUNET_GNS_LookupWithTldRequest *gns_lookup;
@@ -153,12 +153,6 @@ cleanup_handle (void *cls)
153 GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup); 153 GNUNET_GNS_lookup_with_tld_cancel (handle->gns_lookup);
154 handle->gns_lookup = NULL; 154 handle->gns_lookup = NULL;
155 } 155 }
156 if (NULL != handle->gns)
157 {
158 GNUNET_GNS_disconnect (handle->gns);
159 handle->gns = NULL;
160 }
161
162 if (NULL != handle->timeout_task) 156 if (NULL != handle->timeout_task)
163 { 157 {
164 GNUNET_SCHEDULER_cancel (handle->timeout_task); 158 GNUNET_SCHEDULER_cancel (handle->timeout_task);
@@ -318,7 +312,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
318 handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; 312 handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
319 } 313 }
320 314
321 handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns, 315 handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns,
322 handle->name, 316 handle->name,
323 handle->record_type, 317 handle->record_type,
324 GNUNET_GNS_LO_DEFAULT, 318 GNUNET_GNS_LO_DEFAULT,
@@ -352,29 +346,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
352 346
353 347
354/** 348/**
355 * Handle rest request
356 *
357 * @param handle the request handle
358 */
359static void
360init_cont (struct RequestHandle *handle)
361{
362 struct GNUNET_REST_RequestHandlerError err;
363 static const struct GNUNET_REST_RequestHandler handlers[] =
364 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont },
365 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont },
366 GNUNET_REST_HANDLER_END };
367
368 if (GNUNET_NO ==
369 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
370 {
371 handle->response_code = err.error_code;
372 GNUNET_SCHEDULER_add_now (&do_error, handle);
373 }
374}
375
376
377/**
378 * Function processing the REST call 349 * Function processing the REST call
379 * 350 *
380 * @param method HTTP method 351 * @param method HTTP method
@@ -385,12 +356,17 @@ init_cont (struct RequestHandle *handle)
385 * @param proc_cls closure for callback function 356 * @param proc_cls closure for callback function
386 * @return GNUNET_OK if request accepted 357 * @return GNUNET_OK if request accepted
387 */ 358 */
388static void 359static enum GNUNET_GenericReturnValue
389rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 360rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
390 GNUNET_REST_ResultProcessor proc, 361 GNUNET_REST_ResultProcessor proc,
391 void *proc_cls) 362 void *proc_cls)
392{ 363{
393 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 364 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
365 struct GNUNET_REST_RequestHandlerError err;
366 static const struct GNUNET_REST_RequestHandler handlers[] =
367 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont },
368 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont },
369 GNUNET_REST_HANDLER_END };
394 370
395 handle->response_code = 0; 371 handle->response_code = 0;
396 handle->timeout = 372 handle->timeout =
@@ -402,14 +378,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
402 handle->url = GNUNET_strdup (rest_handle->url); 378 handle->url = GNUNET_strdup (rest_handle->url);
403 if (handle->url[strlen (handle->url) - 1] == '/') 379 if (handle->url[strlen (handle->url) - 1] == '/')
404 handle->url[strlen (handle->url) - 1] = '\0'; 380 handle->url[strlen (handle->url) - 1] = '\0';
405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 381 if (GNUNET_NO ==
406 handle->gns = GNUNET_GNS_connect (cfg); 382 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
407 init_cont (handle); 383 {
384 cleanup_handle (handle);
385 return GNUNET_NO;
386 }
387
408 388
409 handle->timeout_task = 389 handle->timeout_task =
410 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); 390 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
411 391 return GNUNET_YES;
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
413} 392}
414 393
415 394
@@ -441,6 +420,7 @@ libgnunet_plugin_rest_gns_init (void *cls)
441 MHD_HTTP_METHOD_PUT, 420 MHD_HTTP_METHOD_PUT,
442 MHD_HTTP_METHOD_DELETE, 421 MHD_HTTP_METHOD_DELETE,
443 MHD_HTTP_METHOD_OPTIONS); 422 MHD_HTTP_METHOD_OPTIONS);
423 gns = GNUNET_GNS_connect (cfg);
444 424
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n")); 425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n"));
446 return api; 426 return api;
@@ -460,6 +440,9 @@ libgnunet_plugin_rest_gns_done (void *cls)
460 struct Plugin *plugin = api->cls; 440 struct Plugin *plugin = api->cls;
461 441
462 plugin->cfg = NULL; 442 plugin->cfg = NULL;
443 if (NULL != gns)
444 GNUNET_GNS_disconnect (gns);
445
463 446
464 GNUNET_free (allow_methods); 447 GNUNET_free (allow_methods);
465 GNUNET_free (api); 448 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
@@ -127,6 +127,26 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
127static char *allow_methods; 127static char *allow_methods;
128 128
129/** 129/**
130 * Ego list
131 */
132static struct EgoEntry *ego_head;
133
134/**
135 * Ego list
136 */
137static struct EgoEntry *ego_tail;
138
139/**
140 * The processing state
141 */
142static int state;
143
144/**
145 * Handle to Identity service.
146 */
147static struct GNUNET_IDENTITY_Handle *identity_handle;
148
149/**
130 * @brief struct returned by the initialization function of the plugin 150 * @brief struct returned by the initialization function of the plugin
131 */ 151 */
132struct Plugin 152struct Plugin
@@ -185,27 +205,6 @@ struct RequestHandle
185 */ 205 */
186 size_t data_size; 206 size_t data_size;
187 207
188
189 /**
190 * Ego list
191 */
192 struct EgoEntry *ego_head;
193
194 /**
195 * Ego list
196 */
197 struct EgoEntry *ego_tail;
198
199 /**
200 * The processing state
201 */
202 int state;
203
204 /**
205 * Handle to Identity service.
206 */
207 struct GNUNET_IDENTITY_Handle *identity_handle;
208
209 /** 208 /**
210 * IDENTITY Operation 209 * IDENTITY Operation
211 */ 210 */
@@ -260,8 +259,6 @@ static void
260cleanup_handle (void *cls) 259cleanup_handle (void *cls)
261{ 260{
262 struct RequestHandle *handle = cls; 261 struct RequestHandle *handle = cls;
263 struct EgoEntry *ego_entry;
264 struct EgoEntry *ego_tmp;
265 262
266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
267 if (NULL != handle->timeout_task) 264 if (NULL != handle->timeout_task)
@@ -276,17 +273,6 @@ cleanup_handle (void *cls)
276 GNUNET_free (handle->emsg); 273 GNUNET_free (handle->emsg);
277 if (NULL != handle->name) 274 if (NULL != handle->name)
278 GNUNET_free (handle->name); 275 GNUNET_free (handle->name);
279 if (NULL != handle->identity_handle)
280 GNUNET_IDENTITY_disconnect (handle->identity_handle);
281
282 for (ego_entry = handle->ego_head; NULL != ego_entry;)
283 {
284 ego_tmp = ego_entry;
285 ego_entry = ego_entry->next;
286 GNUNET_free (ego_tmp->identifier);
287 GNUNET_free (ego_tmp->keystring);
288 GNUNET_free (ego_tmp);
289 }
290 276
291 GNUNET_free (handle); 277 GNUNET_free (handle);
292} 278}
@@ -338,7 +324,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name)
338 324
339 if (NULL != pubkey) 325 if (NULL != pubkey)
340 { 326 {
341 for (ego_entry = handle->ego_head; NULL != ego_entry; 327 for (ego_entry = ego_head; NULL != ego_entry;
342 ego_entry = ego_entry->next) 328 ego_entry = ego_entry->next)
343 { 329 {
344 if (0 != strcasecmp (pubkey, ego_entry->keystring)) 330 if (0 != strcasecmp (pubkey, ego_entry->keystring))
@@ -348,7 +334,7 @@ get_egoentry (struct RequestHandle *handle, char *pubkey, char *name)
348 } 334 }
349 if (NULL != name) 335 if (NULL != name)
350 { 336 {
351 for (ego_entry = handle->ego_head; NULL != ego_entry; 337 for (ego_entry = ego_head; NULL != ego_entry;
352 ego_entry = ego_entry->next) 338 ego_entry = ego_entry->next)
353 { 339 {
354 if (0 != strcasecmp (name, ego_entry->identifier)) 340 if (0 != strcasecmp (name, ego_entry->identifier))
@@ -438,7 +424,7 @@ ego_get_subsystem (struct GNUNET_REST_RequestHandle *con_handle,
438 // requested default identity of subsystem 424 // requested default identity of subsystem
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem); 425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsystem);
440 426
441 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 427 handle->op = GNUNET_IDENTITY_get (identity_handle,
442 subsystem, 428 subsystem,
443 &ego_get_for_subsystem, 429 &ego_get_for_subsystem,
444 handle); 430 handle);
@@ -476,7 +462,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle,
476 462
477 json_root = json_array (); 463 json_root = json_array ();
478 // Return ego/egos 464 // Return ego/egos
479 for (ego_entry = handle->ego_head; NULL != ego_entry; 465 for (ego_entry = ego_head; NULL != ego_entry;
480 ego_entry = ego_entry->next) 466 ego_entry = ego_entry->next)
481 { 467 {
482 json_ego = json_object (); 468 json_ego = json_object ();
@@ -766,7 +752,7 @@ ego_edit (struct RequestHandle *handle, struct EgoEntry *ego_entry)
766 json_decref (data_js); 752 json_decref (data_js);
767 return; 753 return;
768 } 754 }
769 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, 755 handle->op = GNUNET_IDENTITY_rename (identity_handle,
770 ego_entry->identifier, 756 ego_entry->identifier,
771 newname, 757 newname,
772 &do_finished, 758 &do_finished,
@@ -956,7 +942,7 @@ ego_edit_subsystem (struct GNUNET_REST_RequestHandle *con_handle,
956 } 942 }
957 943
958 handle->response_code = MHD_HTTP_NO_CONTENT; 944 handle->response_code = MHD_HTTP_NO_CONTENT;
959 handle->op = GNUNET_IDENTITY_set (handle->identity_handle, 945 handle->op = GNUNET_IDENTITY_set (identity_handle,
960 newsubsys, 946 newsubsys,
961 ego_entry->ego, 947 ego_entry->ego,
962 &do_finished, 948 &do_finished,
@@ -1047,7 +1033,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle,
1047 return; 1033 return;
1048 } 1034 }
1049 GNUNET_STRINGS_utf8_tolower (egoname, egoname); 1035 GNUNET_STRINGS_utf8_tolower (egoname, egoname);
1050 for (ego_entry = handle->ego_head; NULL != ego_entry; 1036 for (ego_entry = ego_head; NULL != ego_entry;
1051 ego_entry = ego_entry->next) 1037 ego_entry = ego_entry->next)
1052 { 1038 {
1053 if (0 == strcasecmp (egoname, ego_entry->identifier)) 1039 if (0 == strcasecmp (egoname, ego_entry->identifier))
@@ -1073,7 +1059,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle,
1073 pk_ptr = NULL; 1059 pk_ptr = NULL;
1074 json_decref (data_js); 1060 json_decref (data_js);
1075 handle->response_code = MHD_HTTP_CREATED; 1061 handle->response_code = MHD_HTTP_CREATED;
1076 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, 1062 handle->op = GNUNET_IDENTITY_create (identity_handle,
1077 handle->name, 1063 handle->name,
1078 pk_ptr, 1064 pk_ptr,
1079 &do_finished_create, 1065 &do_finished_create,
@@ -1118,7 +1104,7 @@ ego_delete_pubkey (struct GNUNET_REST_RequestHandle *con_handle,
1118 } 1104 }
1119 1105
1120 handle->response_code = MHD_HTTP_NO_CONTENT; 1106 handle->response_code = MHD_HTTP_NO_CONTENT;
1121 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, 1107 handle->op = GNUNET_IDENTITY_delete (identity_handle,
1122 ego_entry->identifier, 1108 ego_entry->identifier,
1123 &do_finished, 1109 &do_finished,
1124 handle); 1110 handle);
@@ -1162,7 +1148,7 @@ ego_delete_name (struct GNUNET_REST_RequestHandle *con_handle,
1162 } 1148 }
1163 1149
1164 handle->response_code = MHD_HTTP_NO_CONTENT; 1150 handle->response_code = MHD_HTTP_NO_CONTENT;
1165 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, 1151 handle->op = GNUNET_IDENTITY_delete (identity_handle,
1166 ego_entry->identifier, 1152 ego_entry->identifier,
1167 &do_finished, 1153 &do_finished,
1168 handle); 1154 handle);
@@ -1193,144 +1179,78 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1193} 1179}
1194 1180
1195 1181
1196/**
1197 * Handle rest request
1198 *
1199 * @param handle the request handle
1200 */
1201static void
1202init_cont (struct RequestHandle *handle)
1203{
1204 struct GNUNET_REST_RequestHandlerError err;
1205 static const struct GNUNET_REST_RequestHandler handlers[] =
1206 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all },
1207 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1208 &ego_get_pubkey },
1209 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
1210 { MHD_HTTP_METHOD_GET,
1211 GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
1212 &ego_get_subsystem },
1213 { MHD_HTTP_METHOD_PUT,
1214 GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1215 &ego_edit_pubkey },
1216 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
1217 { MHD_HTTP_METHOD_PUT,
1218 GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
1219 &ego_edit_subsystem },
1220 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
1221 { MHD_HTTP_METHOD_DELETE,
1222 GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1223 &ego_delete_pubkey },
1224 { MHD_HTTP_METHOD_DELETE,
1225 GNUNET_REST_API_NS_IDENTITY_NAME,
1226 &ego_delete_name },
1227 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
1228 GNUNET_REST_HANDLER_END };
1229
1230 if (GNUNET_NO ==
1231 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1232 {
1233 handle->response_code = err.error_code;
1234 GNUNET_SCHEDULER_add_now (&do_error, handle);
1235 }
1236}
1237
1238
1239/**
1240 * If listing is enabled, prints information about the egos.
1241 *
1242 * This function is initially called for all egos and then again
1243 * whenever a ego's identifier changes or if it is deleted. At the
1244 * end of the initial pass over all egos, the function is once called
1245 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
1246 * be invoked in the future or that there was an error.
1247 *
1248 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
1249 * this function is only called ONCE, and 'NULL' being passed in
1250 * 'ego' does indicate an error (i.e. name is taken or no default
1251 * value is known). If 'ego' is non-NULL and if '*ctx'
1252 * is set in those callbacks, the value WILL be passed to a subsequent
1253 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
1254 * that one was not NULL).
1255 *
1256 * When an identity is renamed, this function is called with the
1257 * (known) ego but the NEW identifier.
1258 *
1259 * When an identity is deleted, this function is called with the
1260 * (known) ego and "NULL" for the 'identifier'. In this case,
1261 * the 'ego' is henceforth invalid (and the 'ctx' should also be
1262 * cleaned up).
1263 *
1264 * @param cls closure
1265 * @param ego ego handle
1266 * @param ctx context for application to store data for this ego
1267 * (during the lifetime of this process, initially NULL)
1268 * @param identifier identifier assigned by the user for this ego,
1269 * NULL if the user just deleted the ego and it
1270 * must thus no longer be used
1271 */
1272static void 1182static void
1273init_egos (void *cls, 1183list_ego (void *cls,
1274 struct GNUNET_IDENTITY_Ego *ego, 1184 struct GNUNET_IDENTITY_Ego *ego,
1275 void **ctx, 1185 void **ctx,
1276 const char *identifier) 1186 const char *identifier)
1277{ 1187{
1278 struct RequestHandle *handle = cls;
1279 struct EgoEntry *ego_entry; 1188 struct EgoEntry *ego_entry;
1280 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 1189 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1281 1190
1282 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 1191 if ((NULL == ego) && (ID_REST_STATE_INIT == state))
1283 { 1192 {
1284 handle->state = ID_REST_STATE_POST_INIT; 1193 state = ID_REST_STATE_POST_INIT;
1285 init_cont (handle);
1286 return; 1194 return;
1287 } 1195 }
1288 if (ID_REST_STATE_INIT == handle->state) 1196 if (ID_REST_STATE_INIT == state)
1289 { 1197 {
1290 ego_entry = GNUNET_new (struct EgoEntry); 1198 ego_entry = GNUNET_new (struct EgoEntry);
1291 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 1199 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1292 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 1200 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1293 ego_entry->ego = ego; 1201 ego_entry->ego = ego;
1294 ego_entry->identifier = GNUNET_strdup (identifier); 1202 ego_entry->identifier = GNUNET_strdup (identifier);
1295 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 1203 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1296 handle->ego_tail, 1204 ego_tail,
1297 ego_entry); 1205 ego_entry);
1298 return;
1299 } 1206 }
1300 // Check if ego exists 1207 /* Ego renamed or added */
1301 for (ego_entry = handle->ego_head; NULL != ego_entry;) 1208 if (identifier != NULL)
1302 { 1209 {
1303 struct EgoEntry *tmp = ego_entry; 1210 for (ego_entry = ego_head; NULL != ego_entry;
1304 ego_entry = ego_entry->next; 1211 ego_entry = ego_entry->next)
1305 if (ego != tmp->ego)
1306 continue;
1307 // Deleted
1308 if (NULL == identifier)
1309 { 1212 {
1310 GNUNET_CONTAINER_DLL_remove (handle->ego_head, 1213 if (ego_entry->ego == ego)
1311 handle->ego_tail, 1214 {
1312 tmp); 1215 /* Rename */
1313 GNUNET_free (tmp->keystring); 1216 GNUNET_free (ego_entry->identifier);
1314 GNUNET_free (tmp->identifier); 1217 ego_entry->identifier = GNUNET_strdup (identifier);
1315 GNUNET_free (tmp); 1218 break;
1219 }
1316 } 1220 }
1317 else 1221 if (NULL == ego_entry)
1318 { 1222 {
1319 // Renamed 1223 /* Add */
1320 GNUNET_free (tmp->identifier); 1224 ego_entry = GNUNET_new (struct EgoEntry);
1321 tmp->identifier = GNUNET_strdup (identifier); 1225 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1226 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1227 ego_entry->ego = ego;
1228 ego_entry->identifier = GNUNET_strdup (identifier);
1229 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1230 ego_tail,
1231 ego_entry);
1322 } 1232 }
1233 }
1234 else
1235 {
1236 /* Delete */
1237 for (ego_entry = ego_head; NULL != ego_entry;
1238 ego_entry = ego_entry->next)
1239 {
1240 if (ego_entry->ego == ego)
1241 break;
1242 }
1243 if (NULL == ego_entry)
1244 return; /* Not found */
1245
1246 GNUNET_CONTAINER_DLL_remove (ego_head,
1247 ego_tail,
1248 ego_entry);
1249 GNUNET_free (ego_entry->identifier);
1250 GNUNET_free (ego_entry->keystring);
1251 GNUNET_free (ego_entry);
1323 return; 1252 return;
1324 } 1253 }
1325 // New ego
1326 ego_entry = GNUNET_new (struct EgoEntry);
1327 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1328 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1329 ego_entry->ego = ego;
1330 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
1331 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
1332 handle->ego_tail,
1333 ego_entry);
1334 1254
1335} 1255}
1336 1256
@@ -1346,12 +1266,38 @@ init_egos (void *cls,
1346 * @param proc_cls closure for callback function 1266 * @param proc_cls closure for callback function
1347 * @return GNUNET_OK if request accepted 1267 * @return GNUNET_OK if request accepted
1348 */ 1268 */
1349static void 1269static enum GNUNET_GenericReturnValue
1350rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 1270rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1351 GNUNET_REST_ResultProcessor proc, 1271 GNUNET_REST_ResultProcessor proc,
1352 void *proc_cls) 1272 void *proc_cls)
1353{ 1273{
1354 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 1274 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1275 struct GNUNET_REST_RequestHandlerError err;
1276 static const struct GNUNET_REST_RequestHandler handlers[] =
1277 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get_all },
1278 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1279 &ego_get_pubkey },
1280 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_get_name },
1281 { MHD_HTTP_METHOD_GET,
1282 GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
1283 &ego_get_subsystem },
1284 { MHD_HTTP_METHOD_PUT,
1285 GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1286 &ego_edit_pubkey },
1287 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY_NAME, &ego_edit_name },
1288 { MHD_HTTP_METHOD_PUT,
1289 GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM,
1290 &ego_edit_subsystem },
1291 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
1292 { MHD_HTTP_METHOD_DELETE,
1293 GNUNET_REST_API_NS_IDENTITY_PUBKEY,
1294 &ego_delete_pubkey },
1295 { MHD_HTTP_METHOD_DELETE,
1296 GNUNET_REST_API_NS_IDENTITY_NAME,
1297 &ego_delete_name },
1298 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
1299 GNUNET_REST_HANDLER_END };
1300
1355 1301
1356 handle->response_code = 0; 1302 handle->response_code = 0;
1357 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1303 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1365,13 +1311,17 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1365 if (handle->url[strlen (handle->url) - 1] == '/') 1311 if (handle->url[strlen (handle->url) - 1] == '/')
1366 handle->url[strlen (handle->url) - 1] = '\0'; 1312 handle->url[strlen (handle->url) - 1] = '\0';
1367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 1313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1368 1314 if (GNUNET_NO ==
1369 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle); 1315 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1316 {
1317 cleanup_handle (handle);
1318 return GNUNET_NO;
1319 }
1370 1320
1371 handle->timeout_task = 1321 handle->timeout_task =
1372 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); 1322 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1373
1374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 1323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1324 return GNUNET_YES;
1375} 1325}
1376 1326
1377 1327
@@ -1403,6 +1353,7 @@ libgnunet_plugin_rest_identity_init (void *cls)
1403 MHD_HTTP_METHOD_PUT, 1353 MHD_HTTP_METHOD_PUT,
1404 MHD_HTTP_METHOD_DELETE, 1354 MHD_HTTP_METHOD_DELETE,
1405 MHD_HTTP_METHOD_OPTIONS); 1355 MHD_HTTP_METHOD_OPTIONS);
1356 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
1406 1357
1407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n")); 1358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Identity REST API initialized\n"));
1408 return api; 1359 return api;
@@ -1420,8 +1371,21 @@ libgnunet_plugin_rest_identity_done (void *cls)
1420{ 1371{
1421 struct GNUNET_REST_Plugin *api = cls; 1372 struct GNUNET_REST_Plugin *api = cls;
1422 struct Plugin *plugin = api->cls; 1373 struct Plugin *plugin = api->cls;
1374 struct EgoEntry *ego_entry;
1375 struct EgoEntry *ego_tmp;
1423 1376
1424 plugin->cfg = NULL; 1377 plugin->cfg = NULL;
1378 if (NULL != identity_handle)
1379 GNUNET_IDENTITY_disconnect (identity_handle);
1380
1381 for (ego_entry = ego_head; NULL != ego_entry;)
1382 {
1383 ego_tmp = ego_entry;
1384 ego_entry = ego_entry->next;
1385 GNUNET_free (ego_tmp->identifier);
1386 GNUNET_free (ego_tmp->keystring);
1387 GNUNET_free (ego_tmp);
1388 }
1425 1389
1426 GNUNET_free (allow_methods); 1390 GNUNET_free (allow_methods);
1427 GNUNET_free (api); 1391 GNUNET_free (api);
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h
index 046aee72b..0c566df75 100644
--- a/src/include/gnunet_buffer_lib.h
+++ b/src/include/gnunet_buffer_lib.h
@@ -116,12 +116,12 @@ GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str);
116 * 116 *
117 * @param buf buffer to write to 117 * @param buf buffer to write to
118 * @param data data to read from 118 * @param data data to read from
119 * @param len number of bytes to copy from @a data to @a buf 119 * @param data_len number of bytes to copy from @a data to @a buf
120 */ 120 */
121void 121void
122GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, 122GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf,
123 const char *data, 123 const void *data,
124 size_t len); 124 size_t data_len);
125 125
126 126
127/** 127/**
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
69 * @param data_size the length of the data 69 * @param data_size the length of the data
70 * @param proc the callback for result 70 * @param proc the callback for result
71 * @param proc_cls closure for callback 71 * @param proc_cls closure for callback
72 * @return GNUNET_YES if the request was processed
72 */ 73 */
73 void (*process_request) (struct GNUNET_REST_RequestHandle *handle, 74 enum GNUNET_GenericReturnValue (*process_request)(
74 GNUNET_REST_ResultProcessor proc, 75 struct GNUNET_REST_RequestHandle *handle,
75 void *proc_cls); 76 GNUNET_REST_ResultProcessor proc,
77 void *proc_cls);
76}; 78};
77 79
78 80
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 663b44194..8d829d42e 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -350,6 +350,18 @@ GNUNET_STRINGS_base64_encode (const void *in,
350 350
351 351
352/** 352/**
353 * url/percent encode (RFC3986).
354 *
355 * @param data the data to decode
356 * @param len the length of the input
357 * @param output where to write the output (*output should be NULL,
358 * is allocated)
359 * @return the size of the output
360 */
361size_t
362GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out);
363
364/**
353 * Encode into Base64url. RFC7515 365 * Encode into Base64url. RFC7515
354 * 366 *
355 * @param in the data to encode 367 * @param in the data to encode
@@ -389,6 +401,18 @@ GNUNET_STRINGS_base64_decode (const char *data,
389size_t 401size_t
390GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out); 402GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out);
391 403
404/**
405 * url/percent encode (RFC3986).
406 *
407 * @param data the data to encode
408 * @param len the length of the input
409 * @param output where to write the output (*output should be NULL,
410 * is allocated)
411 * @return the size of the output
412 */
413size_t
414GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out);
415
392 416
393/** 417/**
394 * Convert a peer path to a human-readable string. 418 * Convert a peer path to a human-readable string.
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,
373 emsg = _ ("Namestore failed to store record\n"); 373 emsg = _ ("Namestore failed to store record\n");
374 else 374 else
375 emsg = NULL; 375 emsg = NULL;
376 if (NULL == qe)
377 return;
376 if (NULL != qe->cont) 378 if (NULL != qe->cont)
377 qe->cont (qe->cont_cls, res, emsg); 379 qe->cont (qe->cont_cls, res, emsg);
378 free_qe (qe); 380 free_qe (qe);
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
@@ -85,6 +85,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
85static char *allow_methods; 85static char *allow_methods;
86 86
87/** 87/**
88 * Ego list
89 */
90static struct EgoEntry *ego_head;
91
92/**
93 * Ego list
94 */
95static struct EgoEntry *ego_tail;
96
97/**
98 * The processing state
99 */
100static int state;
101
102/**
103 * Handle to NAMESTORE
104 */
105static struct GNUNET_NAMESTORE_Handle *ns_handle;
106
107/**
108 * Handle to Identity service.
109 */
110static struct GNUNET_IDENTITY_Handle *identity_handle;
111
112/**
88 * @brief struct returned by the initialization function of the plugin 113 * @brief struct returned by the initialization function of the plugin
89 */ 114 */
90struct Plugin 115struct Plugin
@@ -170,15 +195,6 @@ struct RequestHandle
170 */ 195 */
171 json_t *resp_object; 196 json_t *resp_object;
172 197
173 /**
174 * The processing state
175 */
176 int state;
177
178 /**
179 * Handle to NAMESTORE
180 */
181 struct GNUNET_NAMESTORE_Handle *ns_handle;
182 198
183 /** 199 /**
184 * Handle to NAMESTORE it 200 * Handle to NAMESTORE it
@@ -196,26 +212,11 @@ struct RequestHandle
196 struct EgoEntry *ego_entry; 212 struct EgoEntry *ego_entry;
197 213
198 /** 214 /**
199 * Ego list
200 */
201 struct EgoEntry *ego_head;
202
203 /**
204 * Ego list
205 */
206 struct EgoEntry *ego_tail;
207
208 /**
209 * IDENTITY Operation 215 * IDENTITY Operation
210 */ 216 */
211 struct GNUNET_IDENTITY_Operation *op; 217 struct GNUNET_IDENTITY_Operation *op;
212 218
213 /** 219 /**
214 * Handle to Identity service.
215 */
216 struct GNUNET_IDENTITY_Handle *identity_handle;
217
218 /**
219 * Rest connection 220 * Rest connection
220 */ 221 */
221 struct GNUNET_REST_RequestHandle *rest_handle; 222 struct GNUNET_REST_RequestHandle *rest_handle;
@@ -264,8 +265,6 @@ static void
264cleanup_handle (void *cls) 265cleanup_handle (void *cls)
265{ 266{
266 struct RequestHandle *handle = cls; 267 struct RequestHandle *handle = cls;
267 struct EgoEntry *ego_entry;
268 struct EgoEntry *ego_tmp;
269 268
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
271 if (NULL != handle->timeout_task) 270 if (NULL != handle->timeout_task)
@@ -294,21 +293,6 @@ cleanup_handle (void *cls)
294 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); 293 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
295 if (NULL != handle->ns_qe) 294 if (NULL != handle->ns_qe)
296 GNUNET_NAMESTORE_cancel (handle->ns_qe); 295 GNUNET_NAMESTORE_cancel (handle->ns_qe);
297 if (NULL != handle->identity_handle)
298 GNUNET_IDENTITY_disconnect (handle->identity_handle);
299 if (NULL != handle->ns_handle)
300 {
301 GNUNET_NAMESTORE_disconnect (handle->ns_handle);
302 }
303
304 for (ego_entry = handle->ego_head; NULL != ego_entry;)
305 {
306 ego_tmp = ego_entry;
307 ego_entry = ego_entry->next;
308 GNUNET_free (ego_tmp->identifier);
309 GNUNET_free (ego_tmp->keystring);
310 GNUNET_free (ego_tmp);
311 }
312 296
313 if (NULL != handle->resp_object) 297 if (NULL != handle->resp_object)
314 { 298 {
@@ -368,7 +352,7 @@ get_egoentry_namestore (struct RequestHandle *handle, char *name)
368 if (NULL == name) 352 if (NULL == name)
369 return NULL; 353 return NULL;
370 tmp = strtok (copy, "/"); 354 tmp = strtok (copy, "/");
371 for (ego_entry = handle->ego_head; NULL != ego_entry; 355 for (ego_entry = ego_head; NULL != ego_entry;
372 ego_entry = ego_entry->next) 356 ego_entry = ego_entry->next)
373 { 357 {
374 if (0 != strcasecmp (tmp, ego_entry->identifier)) 358 if (0 != strcasecmp (tmp, ego_entry->identifier))
@@ -647,7 +631,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
647 if (1 >= strlen (labelname)) 631 if (1 >= strlen (labelname))
648 { 632 {
649 handle->list_it = 633 handle->list_it =
650 GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 634 GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
651 handle->zone_pkey, 635 handle->zone_pkey,
652 &namestore_iteration_error, 636 &namestore_iteration_error,
653 handle, 637 handle,
@@ -664,7 +648,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
664 return; 648 return;
665 } 649 }
666 handle->record_name = GNUNET_strdup (labelname + 1); 650 handle->record_name = GNUNET_strdup (labelname + 1);
667 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 651 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
668 handle->zone_pkey, 652 handle->zone_pkey,
669 handle->record_name, 653 handle->record_name,
670 &ns_lookup_error_cb, 654 &ns_lookup_error_cb,
@@ -699,7 +683,7 @@ ns_lookup_cb (void *cls,
699 } 683 }
700 for (j = 0; j < handle->rd_count; j++) 684 for (j = 0; j < handle->rd_count; j++)
701 rd_new[i + j] = handle->rd[j]; 685 rd_new[i + j] = handle->rd[j];
702 handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 686 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
703 handle->zone_pkey, 687 handle->zone_pkey,
704 handle->record_name, 688 handle->record_name,
705 i + j, 689 i + j,
@@ -791,7 +775,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle *con_handle,
791 return; 775 return;
792 } 776 }
793 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 777 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
794 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, 778 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
795 handle->zone_pkey, 779 handle->zone_pkey,
796 handle->record_name, 780 handle->record_name,
797 &ns_lookup_error_cb, 781 &ns_lookup_error_cb,
@@ -892,7 +876,7 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
892 } 876 }
893 877
894 handle->record_name = GNUNET_strdup (labelname + 1); 878 handle->record_name = GNUNET_strdup (labelname + 1);
895 handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 879 handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
896 handle->zone_pkey, 880 handle->zone_pkey,
897 handle->record_name, 881 handle->record_name,
898 0, 882 0,
@@ -932,90 +916,79 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
932} 916}
933 917
934 918
935/**
936 * Handle rest request
937 *
938 * @param handle the request handle
939 */
940static void
941init_cont (struct RequestHandle *handle)
942{
943 struct GNUNET_REST_RequestHandlerError err;
944 static const struct GNUNET_REST_RequestHandler handlers[] =
945 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
946 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
947 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
948 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
949 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
950 GNUNET_REST_HANDLER_END };
951
952 if (GNUNET_NO ==
953 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
954 {
955 handle->response_code = err.error_code;
956 GNUNET_SCHEDULER_add_now (&do_error, handle);
957 }
958}
959
960
961/**
962 * This function is initially called for all egos and then again
963 * whenever a ego's identifier changes or if it is deleted. At the
964 * end of the initial pass over all egos, the function is once called
965 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
966 * be invoked in the future or that there was an error.
967 *
968 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
969 * this function is only called ONCE, and 'NULL' being passed in
970 * 'ego' does indicate an error (i.e. name is taken or no default
971 * value is known). If 'ego' is non-NULL and if '*ctx'
972 * is set in those callbacks, the value WILL be passed to a subsequent
973 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
974 * that one was not NULL).
975 *
976 * When an identity is renamed, this function is called with the
977 * (known) ego but the NEW identifier.
978 *
979 * When an identity is deleted, this function is called with the
980 * (known) ego and "NULL" for the 'identifier'. In this case,
981 * the 'ego' is henceforth invalid (and the 'ctx' should also be
982 * cleaned up).
983 *
984 * @param cls closure
985 * @param ego ego handle
986 * @param ctx context for application to store data for this ego
987 * (during the lifetime of this process, initially NULL)
988 * @param name identifier assigned by the user for this ego,
989 * NULL if the user just deleted the ego and it
990 * must thus no longer be used
991 */
992static void 919static void
993id_connect_cb (void *cls, 920list_ego (void *cls,
994 struct GNUNET_IDENTITY_Ego *ego, 921 struct GNUNET_IDENTITY_Ego *ego,
995 void **ctx, 922 void **ctx,
996 const char *name) 923 const char *identifier)
997{ 924{
998 struct RequestHandle *handle = cls;
999 struct EgoEntry *ego_entry; 925 struct EgoEntry *ego_entry;
1000 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 926 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1001 927
1002 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 928 if ((NULL == ego) && (ID_REST_STATE_INIT == state))
1003 { 929 {
1004 handle->state = ID_REST_STATE_POST_INIT; 930 state = ID_REST_STATE_POST_INIT;
1005 init_cont (handle);
1006 return; 931 return;
1007 } 932 }
1008 if (ID_REST_STATE_INIT == handle->state) 933 if (ID_REST_STATE_INIT == state)
1009 { 934 {
1010 ego_entry = GNUNET_new (struct EgoEntry); 935 ego_entry = GNUNET_new (struct EgoEntry);
1011 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 936 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1012 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 937 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1013 ego_entry->ego = ego; 938 ego_entry->ego = ego;
1014 GNUNET_asprintf (&ego_entry->identifier, "%s", name); 939 ego_entry->identifier = GNUNET_strdup (identifier);
1015 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 940 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1016 handle->ego_tail, 941 ego_tail,
1017 ego_entry); 942 ego_entry);
1018 } 943 }
944 /* Ego renamed or added */
945 if (identifier != NULL)
946 {
947 for (ego_entry = ego_head; NULL != ego_entry;
948 ego_entry = ego_entry->next)
949 {
950 if (ego_entry->ego == ego)
951 {
952 /* Rename */
953 GNUNET_free (ego_entry->identifier);
954 ego_entry->identifier = GNUNET_strdup (identifier);
955 break;
956 }
957 }
958 if (NULL == ego_entry)
959 {
960 /* Add */
961 ego_entry = GNUNET_new (struct EgoEntry);
962 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
963 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
964 ego_entry->ego = ego;
965 ego_entry->identifier = GNUNET_strdup (identifier);
966 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
967 ego_tail,
968 ego_entry);
969 }
970 }
971 else
972 {
973 /* Delete */
974 for (ego_entry = ego_head; NULL != ego_entry;
975 ego_entry = ego_entry->next)
976 {
977 if (ego_entry->ego == ego)
978 break;
979 }
980 if (NULL == ego_entry)
981 return; /* Not found */
982
983 GNUNET_CONTAINER_DLL_remove (ego_head,
984 ego_tail,
985 ego_entry);
986 GNUNET_free (ego_entry->identifier);
987 GNUNET_free (ego_entry->keystring);
988 GNUNET_free (ego_entry);
989 return;
990 }
991
1019} 992}
1020 993
1021 994
@@ -1030,12 +1003,20 @@ id_connect_cb (void *cls,
1030 * @param proc_cls closure for callback function 1003 * @param proc_cls closure for callback function
1031 * @return GNUNET_OK if request accepted 1004 * @return GNUNET_OK if request accepted
1032 */ 1005 */
1033static void 1006static enum GNUNET_GenericReturnValue
1034rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 1007rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1035 GNUNET_REST_ResultProcessor proc, 1008 GNUNET_REST_ResultProcessor proc,
1036 void *proc_cls) 1009 void *proc_cls)
1037{ 1010{
1038 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 1011 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1012 struct GNUNET_REST_RequestHandlerError err;
1013 static const struct GNUNET_REST_RequestHandler handlers[] =
1014 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
1015 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
1016 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
1017 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
1018 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
1019 GNUNET_REST_HANDLER_END };
1039 1020
1040 handle->response_code = 0; 1021 handle->response_code = 0;
1041 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1022 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1048,14 +1029,18 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1048 if (handle->url[strlen (handle->url) - 1] == '/') 1029 if (handle->url[strlen (handle->url) - 1] == '/')
1049 handle->url[strlen (handle->url) - 1] = '\0'; 1030 handle->url[strlen (handle->url) - 1] = '\0';
1050 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 1031 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1032 if (GNUNET_NO ==
1033 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1034 {
1035 cleanup_handle (handle);
1036 return GNUNET_NO;
1037 }
1051 1038
1052 handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
1053 handle->identity_handle =
1054 GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle);
1055 handle->timeout_task = 1039 handle->timeout_task =
1056 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); 1040 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1057 1041
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 1042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1043 return GNUNET_YES;
1059} 1044}
1060 1045
1061 1046
@@ -1087,6 +1072,8 @@ libgnunet_plugin_rest_namestore_init (void *cls)
1087 MHD_HTTP_METHOD_PUT, 1072 MHD_HTTP_METHOD_PUT,
1088 MHD_HTTP_METHOD_DELETE, 1073 MHD_HTTP_METHOD_DELETE,
1089 MHD_HTTP_METHOD_OPTIONS); 1074 MHD_HTTP_METHOD_OPTIONS);
1075 ns_handle = GNUNET_NAMESTORE_connect (cfg);
1076 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
1090 1077
1091 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n")); 1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
1092 return api; 1079 return api;
@@ -1104,8 +1091,23 @@ libgnunet_plugin_rest_namestore_done (void *cls)
1104{ 1091{
1105 struct GNUNET_REST_Plugin *api = cls; 1092 struct GNUNET_REST_Plugin *api = cls;
1106 struct Plugin *plugin = api->cls; 1093 struct Plugin *plugin = api->cls;
1094 struct EgoEntry *ego_entry;
1095 struct EgoEntry *ego_tmp;
1107 1096
1108 plugin->cfg = NULL; 1097 plugin->cfg = NULL;
1098 if (NULL != identity_handle)
1099 GNUNET_IDENTITY_disconnect (identity_handle);
1100 if (NULL != ns_handle)
1101 GNUNET_NAMESTORE_disconnect (ns_handle);
1102
1103 for (ego_entry = ego_head; NULL != ego_entry;)
1104 {
1105 ego_tmp = ego_entry;
1106 ego_entry = ego_entry->next;
1107 GNUNET_free (ego_tmp->identifier);
1108 GNUNET_free (ego_tmp->keystring);
1109 GNUNET_free (ego_tmp);
1110 }
1109 1111
1110 GNUNET_free (allow_methods); 1112 GNUNET_free (allow_methods);
1111 GNUNET_free (api); 1113 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;
70/** 70/**
71 * HTTP methods allows for this plugin 71 * HTTP methods allows for this plugin
72 */ 72 */
73static char*allow_methods; 73static char *allow_methods;
74
75/**
76 * Handle to PEERINFO
77 */
78static struct GNUNET_PEERINFO_Handle *peerinfo_handle;
74 79
75/** 80/**
76 * @brief struct returned by the initialization function of the plugin 81 * @brief struct returned by the initialization function of the plugin
@@ -204,10 +209,6 @@ struct RequestHandle
204 */ 209 */
205 struct GNUNET_PEERINFO_IteratorContext *list_it; 210 struct GNUNET_PEERINFO_IteratorContext *list_it;
206 211
207 /**
208 * Handle to PEERINFO
209 */
210 struct GNUNET_PEERINFO_Handle *peerinfo_handle;
211 212
212 /** 213 /**
213 * Rest connection 214 * Rest connection
@@ -294,10 +295,10 @@ cleanup_handle (void *cls)
294 GNUNET_PEERINFO_iterate_cancel (handle->list_it); 295 GNUNET_PEERINFO_iterate_cancel (handle->list_it);
295 handle->list_it = NULL; 296 handle->list_it = NULL;
296 } 297 }
297 if (NULL != handle->peerinfo_handle) 298 if (NULL != peerinfo_handle)
298 { 299 {
299 GNUNET_PEERINFO_disconnect (handle->peerinfo_handle); 300 GNUNET_PEERINFO_disconnect (peerinfo_handle);
300 handle->peerinfo_handle = NULL; 301 peerinfo_handle = NULL;
301 } 302 }
302 303
303 GNUNET_free (handle); 304 GNUNET_free (handle);
@@ -664,7 +665,7 @@ peerinfo_get (struct GNUNET_REST_RequestHandle *con_handle,
664 // specific_peer = GNUNET_PEER_resolve2(peer_id); 665 // specific_peer = GNUNET_PEER_resolve2(peer_id);
665 } 666 }
666 667
667 handle->list_it = GNUNET_PEERINFO_iterate (handle->peerinfo_handle, 668 handle->list_it = GNUNET_PEERINFO_iterate (peerinfo_handle,
668 include_friend_only, 669 include_friend_only,
669 specific_peer, 670 specific_peer,
670 &peerinfo_list_iteration, 671 &peerinfo_list_iteration,
@@ -699,32 +700,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
699 700
700 701
701/** 702/**
702 * Handle rest request
703 *
704 * @param handle the request handle
705 */
706static void
707init_cont (struct RequestHandle *handle)
708{
709 struct GNUNET_REST_RequestHandlerError err;
710 static const struct GNUNET_REST_RequestHandler handlers[] = {
711 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get },
712 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont },
713 GNUNET_REST_HANDLER_END
714 };
715
716 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
717 handlers,
718 &err,
719 handle))
720 {
721 handle->response_code = err.error_code;
722 GNUNET_SCHEDULER_add_now (&do_error, handle);
723 }
724}
725
726
727/**
728 * Function processing the REST call 703 * Function processing the REST call
729 * 704 *
730 * @param method HTTP method 705 * @param method HTTP method
@@ -735,12 +710,18 @@ init_cont (struct RequestHandle *handle)
735 * @param proc_cls closure for callback function 710 * @param proc_cls closure for callback function
736 * @return GNUNET_OK if request accepted 711 * @return GNUNET_OK if request accepted
737 */ 712 */
738static void 713static enum GNUNET_GenericReturnValue
739rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 714rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
740 GNUNET_REST_ResultProcessor proc, 715 GNUNET_REST_ResultProcessor proc,
741 void *proc_cls) 716 void *proc_cls)
742{ 717{
743 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 718 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
719 struct GNUNET_REST_RequestHandlerError err;
720 static const struct GNUNET_REST_RequestHandler handlers[] = {
721 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_PEERINFO, &peerinfo_get },
722 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_PEERINFO, &options_cont },
723 GNUNET_REST_HANDLER_END
724 };
744 725
745 handle->response_code = 0; 726 handle->response_code = 0;
746 handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 727 handle->timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
@@ -753,14 +734,20 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
753 if (handle->url[strlen (handle->url) - 1] == '/') 734 if (handle->url[strlen (handle->url) - 1] == '/')
754 handle->url[strlen (handle->url) - 1] = '\0'; 735 handle->url[strlen (handle->url) - 1] = '\0';
755 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
756 handle->peerinfo_handle = GNUNET_PEERINFO_connect (cfg); 737 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
757 init_cont (handle); 738 handlers,
739 &err,
740 handle))
741 {
742 cleanup_handle (handle);
743 return GNUNET_NO;
744 }
758 handle->timeout_task = 745 handle->timeout_task =
759 GNUNET_SCHEDULER_add_delayed (handle->timeout, 746 GNUNET_SCHEDULER_add_delayed (handle->timeout,
760 &do_error, 747 &do_error,
761 handle); 748 handle);
762
763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
750 return GNUNET_YES;
764} 751}
765 752
766 753
@@ -792,6 +779,7 @@ libgnunet_plugin_rest_peerinfo_init (void *cls)
792 MHD_HTTP_METHOD_PUT, 779 MHD_HTTP_METHOD_PUT,
793 MHD_HTTP_METHOD_DELETE, 780 MHD_HTTP_METHOD_DELETE,
794 MHD_HTTP_METHOD_OPTIONS); 781 MHD_HTTP_METHOD_OPTIONS);
782 peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
795 783
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
797 _ ("Peerinfo REST API initialized\n")); 785 _ ("Peerinfo REST API initialized\n"));
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,
850 struct ConsumeTicketResultMessage *crm; 850 struct ConsumeTicketResultMessage *crm;
851 struct GNUNET_MQ_Envelope *env; 851 struct GNUNET_MQ_Envelope *env;
852 char *data_tmp; 852 char *data_tmp;
853 size_t attrs_len; 853 size_t attrs_len = 0;
854 size_t attests_len; 854 size_t attests_len = 0;
855 855
856 if (GNUNET_OK != success) 856 if (GNUNET_OK != success)
857 { 857 {
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index ad2839200..9b5938c43 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -47,9 +47,9 @@ struct OIDC_Parameters
47 struct GNUNET_RECLAIM_Ticket ticket; 47 struct GNUNET_RECLAIM_Ticket ticket;
48 48
49 /** 49 /**
50 * The nonce 50 * The nonce length
51 */ 51 */
52 uint32_t nonce GNUNET_PACKED; 52 uint32_t nonce_len GNUNET_PACKED;
53 53
54 /** 54 /**
55 * The length of the PKCE code_challenge 55 * The length of the PKCE code_challenge
@@ -69,6 +69,51 @@ struct OIDC_Parameters
69 69
70GNUNET_NETWORK_STRUCT_END 70GNUNET_NETWORK_STRUCT_END
71 71
72/**
73 * Standard claims represented by the "profile" scope in OIDC
74 */
75static char OIDC_profile_claims[14][32] = {
76 "name", "family_name", "given_name", "middle_name", "nickname",
77 "preferred_username", "profile", "picture", "website", "gender", "birthdate",
78 "zoneinfo", "locale", "updated_at"
79};
80
81/**
82 * Standard claims represented by the "email" scope in OIDC
83 */
84static char OIDC_email_claims[2][16] = {
85 "email", "email_verified"
86};
87
88/**
89 * Standard claims represented by the "phone" scope in OIDC
90 */
91static char OIDC_phone_claims[2][32] = {
92 "phone_number", "phone_number_verified"
93};
94
95/**
96 * Standard claims represented by the "address" scope in OIDC
97 */
98static char OIDC_address_claims[5][32] = {
99 "street_address", "locality", "region", "postal_code", "country"
100};
101
102static enum GNUNET_GenericReturnValue
103is_claim_in_address_scope (const char *claim)
104{
105 int i;
106 for (i = 0; i < 5; i++)
107 {
108 if (0 == strcmp (claim, OIDC_address_claims[i]))
109 {
110 return GNUNET_YES;
111 }
112 }
113 return GNUNET_NO;
114}
115
116
72static char * 117static char *
73create_jwt_header (void) 118create_jwt_header (void)
74{ 119{
@@ -109,49 +154,22 @@ fix_base64 (char *str)
109 replace_char (str, '/', '_'); 154 replace_char (str, '/', '_');
110} 155}
111 156
112 157static json_t*
113/** 158generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
114 * Create a JWT from attributes 159 struct GNUNET_RECLAIM_AttributeList *attrs,
115 * 160 struct GNUNET_RECLAIM_AttestationList *attests)
116 * @param aud_key the public of the audience
117 * @param sub_key the public key of the subject
118 * @param attrs the attribute list
119 * @param expiration_time the validity of the token
120 * @param secret_key the key used to sign the JWT
121 * @return a new base64-encoded JWT string.
122 */
123char *
124OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
125 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
126 struct GNUNET_RECLAIM_AttributeList *attrs,
127 struct GNUNET_RECLAIM_AttestationList *attests,
128 const struct GNUNET_TIME_Relative *expiration_time,
129 const char *nonce,
130 const char *secret_key)
131{ 161{
132 struct GNUNET_RECLAIM_AttributeListEntry *le; 162 struct GNUNET_RECLAIM_AttributeListEntry *le;
133 struct GNUNET_RECLAIM_AttestationListEntry *ale; 163 struct GNUNET_RECLAIM_AttestationListEntry *ale;
134 struct GNUNET_HashCode signature;
135 struct GNUNET_TIME_Absolute exp_time;
136 struct GNUNET_TIME_Absolute time_now;
137 char *audience;
138 char *subject; 164 char *subject;
139 char *header;
140 char *body_str;
141 char *aggr_names_str;
142 char *aggr_sources_str;
143 char *source_name; 165 char *source_name;
144 char *result;
145 char *header_base64;
146 char *body_base64;
147 char *signature_target;
148 char *signature_base64;
149 char *attr_val_str; 166 char *attr_val_str;
150 char *attest_val_str; 167 char *attest_val_str;
151 json_t *body; 168 json_t *body;
152 json_t *aggr_names; 169 json_t *aggr_names;
153 json_t *aggr_sources; 170 json_t *aggr_sources;
154 json_t *aggr_sources_jwt; 171 json_t *aggr_sources_jwt;
172 json_t *addr_claim = NULL;
155 int num_attestations = 0; 173 int num_attestations = 0;
156 for (le = attrs->list_head; NULL != le; le = le->next) 174 for (le = attrs->list_head; NULL != le; le = le->next)
157 { 175 {
@@ -159,22 +177,10 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
159 num_attestations++; 177 num_attestations++;
160 } 178 }
161 179
162 // iat REQUIRED time now
163 time_now = GNUNET_TIME_absolute_get ();
164 // exp REQUIRED time expired from config
165 exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
166 // auth_time only if max_age
167 // nonce only if nonce
168 // OPTIONAL acr,amr,azp
169 subject = 180 subject =
170 GNUNET_STRINGS_data_to_string_alloc (sub_key, 181 GNUNET_STRINGS_data_to_string_alloc (sub_key,
171 sizeof(struct 182 sizeof(struct
172 GNUNET_CRYPTO_EcdsaPublicKey)); 183 GNUNET_CRYPTO_EcdsaPublicKey));
173 audience =
174 GNUNET_STRINGS_data_to_string_alloc (aud_key,
175 sizeof(struct
176 GNUNET_CRYPTO_EcdsaPublicKey));
177 header = create_jwt_header ();
178 body = json_object (); 184 body = json_object ();
179 aggr_names = json_object (); 185 aggr_names = json_object ();
180 aggr_sources = json_object (); 186 aggr_sources = json_object ();
@@ -185,26 +191,7 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
185 json_object_set_new (body, "iss", json_string (SERVER_ADDRESS)); 191 json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
186 // sub REQUIRED public key identity, not exceed 255 ASCII length 192 // sub REQUIRED public key identity, not exceed 255 ASCII length
187 json_object_set_new (body, "sub", json_string (subject)); 193 json_object_set_new (body, "sub", json_string (subject));
188 // aud REQUIRED public key client_id must be there
189 json_object_set_new (body, "aud", json_string (audience));
190 // iat
191 json_object_set_new (body,
192 "iat",
193 json_integer (time_now.abs_value_us / (1000 * 1000)));
194 // exp
195 json_object_set_new (body,
196 "exp",
197 json_integer (exp_time.abs_value_us / (1000 * 1000)));
198 // nbf
199 json_object_set_new (body,
200 "nbf",
201 json_integer (time_now.abs_value_us / (1000 * 1000)));
202 // nonce
203 if (NULL != nonce)
204 json_object_set_new (body, "nonce", json_string (nonce));
205 attest_val_str = NULL; 194 attest_val_str = NULL;
206 aggr_names_str = NULL;
207 aggr_sources_str = NULL;
208 source_name = NULL; 195 source_name = NULL;
209 int i = 0; 196 int i = 0;
210 for (ale = attests->list_head; NULL != ale; ale = ale->next) 197 for (ale = attests->list_head; NULL != ale; ale = ale->next)
@@ -236,8 +223,26 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
236 GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type, 223 GNUNET_RECLAIM_attribute_value_to_string (le->attribute->type,
237 le->attribute->data, 224 le->attribute->data,
238 le->attribute->data_size); 225 le->attribute->data_size);
239 json_object_set_new (body, le->attribute->name, 226 /**
240 json_string (attr_val_str)); 227 * There is this wierd quirk that the individual address claim(s) must be
228 * inside a JSON object of the "address" claim.
229 * FIXME: Possibly include formatted claim here
230 */
231 if (GNUNET_YES == is_claim_in_address_scope (le->attribute->name))
232 {
233 if (NULL == addr_claim)
234 {
235 addr_claim = json_object ();
236 }
237 json_object_set_new (addr_claim, le->attribute->name,
238 json_string (attr_val_str));
239
240 }
241 else
242 {
243 json_object_set_new (body, le->attribute->name,
244 json_string (attr_val_str));
245 }
241 GNUNET_free (attr_val_str); 246 GNUNET_free (attr_val_str);
242 } 247 }
243 else 248 else
@@ -262,21 +267,113 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
262 GNUNET_free (source_name); 267 GNUNET_free (source_name);
263 } 268 }
264 } 269 }
270 if (NULL != addr_claim)
271 json_object_set_new (body, "address", addr_claim);
265 272
266 if (NULL != attest_val_str) 273 if (NULL != attest_val_str)
267 GNUNET_free (attest_val_str); 274 GNUNET_free (attest_val_str);
268 if (0 != i) 275 if (0 != i)
269 { 276 {
270 aggr_names_str = json_dumps (aggr_names, JSON_INDENT (0) | JSON_COMPACT); 277 json_object_set_new (body, "_claim_names", aggr_names);
271 aggr_sources_str = json_dumps (aggr_sources, JSON_INDENT (0) 278 json_object_set_new (body, "_claim_sources", aggr_sources);
272 | JSON_COMPACT);
273 json_object_set_new (body, "_claim_names", json_string (aggr_names_str));
274 json_object_set_new (body, "_claim_sources", json_string (
275 aggr_sources_str));
276 } 279 }
277 280
278 json_decref (aggr_names); 281 return body;
279 json_decref (aggr_sources); 282}
283
284/**
285 * Generate userinfo JSON as string
286 *
287 * @param sub_key the subject (user)
288 * @param attrs user attribute list
289 * @param attests user attribute attestation list (may be empty)
290 * @return Userinfo JSON
291 */
292char *
293OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
294 struct GNUNET_RECLAIM_AttributeList *attrs,
295 struct GNUNET_RECLAIM_AttestationList *attests)
296{
297 char *body_str;
298 json_t* body = generate_userinfo_json (sub_key,
299 attrs,
300 attests);
301 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
302 json_decref (body);
303 return body_str;
304}
305
306
307/**
308 * Create a JWT from attributes
309 *
310 * @param aud_key the public of the audience
311 * @param sub_key the public key of the subject
312 * @param attrs the attribute list
313 * @param expiration_time the validity of the token
314 * @param secret_key the key used to sign the JWT
315 * @return a new base64-encoded JWT string.
316 */
317char *
318OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
319 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
320 struct GNUNET_RECLAIM_AttributeList *attrs,
321 struct GNUNET_RECLAIM_AttestationList *attests,
322 const struct GNUNET_TIME_Relative *expiration_time,
323 const char *nonce,
324 const char *secret_key)
325{
326 struct GNUNET_HashCode signature;
327 struct GNUNET_TIME_Absolute exp_time;
328 struct GNUNET_TIME_Absolute time_now;
329 char *audience;
330 char *subject;
331 char *header;
332 char *body_str;
333 char *result;
334 char *header_base64;
335 char *body_base64;
336 char *signature_target;
337 char *signature_base64;
338 json_t *body;
339
340 body = generate_userinfo_json (sub_key,
341 attrs,
342 attests);
343 // iat REQUIRED time now
344 time_now = GNUNET_TIME_absolute_get ();
345 // exp REQUIRED time expired from config
346 exp_time = GNUNET_TIME_absolute_add (time_now, *expiration_time);
347 // auth_time only if max_age
348 // nonce only if nonce
349 // OPTIONAL acr,amr,azp
350 subject =
351 GNUNET_STRINGS_data_to_string_alloc (sub_key,
352 sizeof(struct
353 GNUNET_CRYPTO_EcdsaPublicKey));
354 audience =
355 GNUNET_STRINGS_data_to_string_alloc (aud_key,
356 sizeof(struct
357 GNUNET_CRYPTO_EcdsaPublicKey));
358 header = create_jwt_header ();
359
360 // aud REQUIRED public key client_id must be there
361 json_object_set_new (body, "aud", json_string (audience));
362 // iat
363 json_object_set_new (body,
364 "iat",
365 json_integer (time_now.abs_value_us / (1000 * 1000)));
366 // exp
367 json_object_set_new (body,
368 "exp",
369 json_integer (exp_time.abs_value_us / (1000 * 1000)));
370 // nbf
371 json_object_set_new (body,
372 "nbf",
373 json_integer (time_now.abs_value_us / (1000 * 1000)));
374 // nonce
375 if (NULL != nonce)
376 json_object_set_new (body, "nonce", json_string (nonce));
280 377
281 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); 378 body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT);
282 json_decref (body); 379 json_decref (body);
@@ -315,10 +412,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
315 GNUNET_free (signature_target); 412 GNUNET_free (signature_target);
316 GNUNET_free (header); 413 GNUNET_free (header);
317 GNUNET_free (body_str); 414 GNUNET_free (body_str);
318 if (NULL != aggr_sources_str)
319 GNUNET_free (aggr_sources_str);
320 if (NULL != aggr_names_str)
321 GNUNET_free (aggr_names_str);
322 GNUNET_free (signature_base64); 415 GNUNET_free (signature_base64);
323 GNUNET_free (body_base64); 416 GNUNET_free (body_base64);
324 GNUNET_free (header_base64); 417 GNUNET_free (header_base64);
@@ -326,89 +419,6 @@ OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
326} 419}
327 420
328 421
329static void
330derive_aes_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
331 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
332 struct GNUNET_HashCode *key_material)
333{
334 static const char ctx_key[] = "reclaim-aes-ctx-key";
335 static const char ctx_iv[] = "reclaim-aes-ctx-iv";
336
337 GNUNET_CRYPTO_kdf (key,
338 sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey),
339 ctx_key,
340 strlen (ctx_key),
341 key_material,
342 sizeof(struct GNUNET_HashCode),
343 NULL);
344 GNUNET_CRYPTO_kdf (iv,
345 sizeof(
346 struct GNUNET_CRYPTO_SymmetricInitializationVector),
347 ctx_iv,
348 strlen (ctx_iv),
349 key_material,
350 sizeof(struct GNUNET_HashCode),
351 NULL);
352}
353
354
355static void
356calculate_key_priv (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
357 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
358 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
359 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub)
360{
361 struct GNUNET_HashCode key_material;
362
363 GNUNET_CRYPTO_ecdsa_ecdh (ecdsa_priv, ecdh_pub, &key_material);
364 derive_aes_key (key, iv, &key_material);
365}
366
367
368static void
369calculate_key_pub (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
370 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
371 const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
372 const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv)
373{
374 struct GNUNET_HashCode key_material;
375
376 GNUNET_CRYPTO_ecdh_ecdsa (ecdh_priv, ecdsa_pub, &key_material);
377 derive_aes_key (key, iv, &key_material);
378}
379
380
381static void
382decrypt_payload (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
383 const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub,
384 const char *ct,
385 size_t ct_len,
386 char *buf)
387{
388 struct GNUNET_CRYPTO_SymmetricSessionKey key;
389 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
390
391 calculate_key_priv (&key, &iv, ecdsa_priv, ecdh_pub);
392 GNUNET_break (GNUNET_CRYPTO_symmetric_decrypt (ct, ct_len, &key, &iv, buf));
393}
394
395
396static void
397encrypt_payload (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
398 const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_priv,
399 const char *payload,
400 size_t payload_len,
401 char *buf)
402{
403 struct GNUNET_CRYPTO_SymmetricSessionKey key;
404 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
405
406 calculate_key_pub (&key, &iv, ecdsa_pub, ecdh_priv);
407 GNUNET_break (
408 GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len, &key, &iv, buf));
409}
410
411
412/** 422/**
413 * Builds an OIDC authorization code including 423 * Builds an OIDC authorization code including
414 * a reclaim ticket and nonce 424 * a reclaim ticket and nonce
@@ -439,34 +449,21 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
439 size_t attr_list_len = 0; 449 size_t attr_list_len = 0;
440 size_t attests_list_len = 0; 450 size_t attests_list_len = 0;
441 size_t code_challenge_len = 0; 451 size_t code_challenge_len = 0;
442 uint32_t nonce; 452 uint32_t nonce_len = 0;
443 uint32_t nonce_tmp;
444 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 453 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
445 struct GNUNET_CRYPTO_EcdhePrivateKey ecdh_priv;
446 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pub;
447 454
448 /** PLAINTEXT **/ 455 /** PLAINTEXT **/
449 // Assign ticket 456 // Assign ticket
450 memset (&params, 0, sizeof(params)); 457 memset (&params, 0, sizeof(params));
451 params.ticket = *ticket; 458 params.ticket = *ticket;
452 // Assign nonce 459 // Assign nonce
453 nonce = 0;
454 payload_len = sizeof(struct OIDC_Parameters); 460 payload_len = sizeof(struct OIDC_Parameters);
455 if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0)) 461 if ((NULL != nonce_str) && (strcmp ("", nonce_str) != 0))
456 { 462 {
457 if ((1 != sscanf (nonce_str, "%u", &nonce)) || (nonce > UINT32_MAX)) 463 nonce_len = strlen (nonce_str);
458 { 464 payload_len += nonce_len;
459 GNUNET_break (0);
460 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid nonce %s\n", nonce_str);
461 return NULL;
462 }
463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
464 "Got nonce: %u from %s\n",
465 nonce,
466 nonce_str);
467 } 465 }
468 nonce_tmp = htonl (nonce); 466 params.nonce_len = htonl (nonce_len);
469 params.nonce = nonce_tmp;
470 // Assign code challenge 467 // Assign code challenge
471 if (NULL != code_challenge) 468 if (NULL != code_challenge)
472 code_challenge_len = strlen (code_challenge); 469 code_challenge_len = strlen (code_challenge);
@@ -506,6 +503,11 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
506 memcpy (tmp, code_challenge, code_challenge_len); 503 memcpy (tmp, code_challenge, code_challenge_len);
507 tmp += code_challenge_len; 504 tmp += code_challenge_len;
508 } 505 }
506 if (0 < nonce_len)
507 {
508 memcpy (tmp, nonce_str, nonce_len);
509 tmp += nonce_len;
510 }
509 if (0 < attr_list_len) 511 if (0 < attr_list_len)
510 GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp); 512 GNUNET_RECLAIM_attribute_list_serialize (attrs, tmp);
511 if (0 < attests_list_len) 513 if (0 < attests_list_len)
@@ -513,36 +515,24 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
513 515
514 /** END **/ 516 /** END **/
515 517
516 /** ENCRYPT **/
517 // Get length 518 // Get length
518 code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 519 code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
519 + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
520 + payload_len + sizeof(struct 520 + payload_len + sizeof(struct
521 GNUNET_CRYPTO_EcdsaSignature); 521 GNUNET_CRYPTO_EcdsaSignature);
522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 522 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
523 "Length of data to encode: %lu\n", 523 "Length of data to encode: %lu\n",
524 code_payload_len); 524 code_payload_len);
525 525
526 // Generate ECDH key
527 GNUNET_CRYPTO_ecdhe_key_create (&ecdh_priv);
528 GNUNET_CRYPTO_ecdhe_key_get_public (&ecdh_priv, &ecdh_pub);
529 // Initialize code payload 526 // Initialize code payload
530 code_payload = GNUNET_malloc (code_payload_len); 527 code_payload = GNUNET_malloc (code_payload_len);
531 GNUNET_assert (NULL != code_payload); 528 GNUNET_assert (NULL != code_payload);
532 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload; 529 purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) code_payload;
533 purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 530 purpose->size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
534 + sizeof(ecdh_pub) + payload_len); 531 + payload_len);
535 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN); 532 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN);
536 // Store pubkey 533 // Store pubkey
537 buf_ptr = (char *) &purpose[1]; 534 buf_ptr = (char *) &purpose[1];
538 memcpy (buf_ptr, &ecdh_pub, sizeof(ecdh_pub)); 535 memcpy (buf_ptr, payload, payload_len);
539 buf_ptr += sizeof(ecdh_pub);
540 // Encrypt plaintext and store
541 encrypt_payload (&ticket->audience,
542 &ecdh_priv,
543 payload,
544 payload_len,
545 buf_ptr);
546 GNUNET_free (payload); 536 GNUNET_free (payload);
547 buf_ptr += payload_len; 537 buf_ptr += payload_len;
548 // Sign and store signature 538 // Sign and store signature
@@ -570,14 +560,16 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
570 * 560 *
571 * @param audience the expected audience of the code 561 * @param audience the expected audience of the code
572 * @param code the string representation of the code 562 * @param code the string representation of the code
573 * @param code_verfier PKCE code verifier 563 * @param code_verfier PKCE code verifier. Optional, must be provided
564 * if used in request.
574 * @param ticket where to store the ticket 565 * @param ticket where to store the ticket
575 * @param attrs the attributes in the code 566 * @param attrs the attributes in the code
576 * @param nonce where to store the nonce 567 * @param attests the attestations in the code (if any)
568 * @param nonce_str where to store the nonce (if contained)
577 * @return GNUNET_OK if successful, else GNUNET_SYSERR 569 * @return GNUNET_OK if successful, else GNUNET_SYSERR
578 */ 570 */
579int 571int
580OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, 572OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
581 const char *code, 573 const char *code,
582 const char *code_verifier, 574 const char *code_verifier,
583 struct GNUNET_RECLAIM_Ticket *ticket, 575 struct GNUNET_RECLAIM_Ticket *ticket,
@@ -595,14 +587,12 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
595 char *code_verifier_hash; 587 char *code_verifier_hash;
596 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 588 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
597 struct GNUNET_CRYPTO_EcdsaSignature *signature; 589 struct GNUNET_CRYPTO_EcdsaSignature *signature;
598 struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub;
599 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pub;
600 uint32_t code_challenge_len; 590 uint32_t code_challenge_len;
601 uint32_t attrs_ser_len; 591 uint32_t attrs_ser_len;
602 uint32_t attests_ser_len; 592 uint32_t attests_ser_len;
603 size_t plaintext_len; 593 size_t plaintext_len;
604 size_t code_payload_len; 594 size_t code_payload_len;
605 uint32_t nonce = 0; 595 uint32_t nonce_len = 0;
606 struct OIDC_Parameters *params; 596 struct OIDC_Parameters *params;
607 597
608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code); 598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to decode `%s'\n", code);
@@ -611,7 +601,6 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
611 GNUNET_STRINGS_base64url_decode (code, strlen (code), 601 GNUNET_STRINGS_base64url_decode (code, strlen (code),
612 (void **) &code_payload); 602 (void **) &code_payload);
613 if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) 603 if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
614 + sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)
615 + sizeof(struct OIDC_Parameters) 604 + sizeof(struct OIDC_Parameters)
616 + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) 605 + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))
617 { 606 {
@@ -624,16 +613,8 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
624 plaintext_len = code_payload_len; 613 plaintext_len = code_payload_len;
625 plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); 614 plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose);
626 ptr = (char *) &purpose[1]; 615 ptr = (char *) &purpose[1];
627 // Public ECDH key
628 ecdh_pub = (struct GNUNET_CRYPTO_EcdhePublicKey *) ptr;
629 ptr += sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
630 plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdhePublicKey);
631
632 // Decrypt ciphertext
633 plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); 616 plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
634 plaintext = GNUNET_malloc (plaintext_len); 617 plaintext = ptr;
635 decrypt_payload (ecdsa_priv, ecdh_pub, ptr, plaintext_len, plaintext);
636 // ptr = plaintext;
637 ptr += plaintext_len; 618 ptr += plaintext_len;
638 signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; 619 signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr;
639 params = (struct OIDC_Parameters *) plaintext; 620 params = (struct OIDC_Parameters *) plaintext;
@@ -658,11 +639,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
658 // encode code verifier 639 // encode code verifier
659 GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8, 640 GNUNET_STRINGS_base64url_encode (code_verifier_hash, 256 / 8,
660 &expected_code_challenge); 641 &expected_code_challenge);
661 code_challenge = (char *) &params[1]; 642 code_challenge = ((char *) &params[1]);
662 GNUNET_free (code_verifier_hash); 643 GNUNET_free (code_verifier_hash);
663 if ((strlen (expected_code_challenge) != code_challenge_len) || 644 if (0 !=
664 (0 != 645 strncmp (expected_code_challenge, code_challenge, code_challenge_len))
665 strncmp (expected_code_challenge, code_challenge, code_challenge_len)))
666 { 646 {
667 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 647 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
668 "Invalid code verifier! Expected: %s, Got: %.*s\n", 648 "Invalid code verifier! Expected: %s, Got: %.*s\n",
@@ -675,17 +655,23 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
675 } 655 }
676 GNUNET_free (expected_code_challenge); 656 GNUNET_free (expected_code_challenge);
677 } 657 }
658 nonce_len = ntohl (params->nonce_len);
659 if (0 != nonce_len)
660 {
661 *nonce_str = GNUNET_strndup (code_challenge + code_challenge_len,
662 nonce_len);
663 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %s\n", *nonce_str);
664 }
665
678 // Ticket 666 // Ticket
679 memcpy (ticket, &params->ticket, sizeof(params->ticket)); 667 memcpy (ticket, &params->ticket, sizeof(params->ticket));
680 // Nonce
681 nonce = ntohl (params->nonce); // ntohl (*((uint32_t *) ptr));
682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got nonce: %u\n", nonce);
683 // Signature 668 // Signature
684 GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub); 669 // GNUNET_CRYPTO_ecdsa_key_get_public (ecdsa_priv, &ecdsa_pub);
685 if (0 != GNUNET_memcmp (&ecdsa_pub, &ticket->audience)) 670 if (0 != GNUNET_memcmp (audience, &ticket->audience))
686 { 671 {
687 GNUNET_free (code_payload); 672 GNUNET_free (code_payload);
688 GNUNET_free (plaintext); 673 if (NULL != *nonce_str)
674 GNUNET_free (*nonce_str);
689 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 675 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
690 "Audience in ticket does not match client!\n"); 676 "Audience in ticket does not match client!\n");
691 return GNUNET_SYSERR; 677 return GNUNET_SYSERR;
@@ -697,12 +683,13 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
697 &ticket->identity)) 683 &ticket->identity))
698 { 684 {
699 GNUNET_free (code_payload); 685 GNUNET_free (code_payload);
700 GNUNET_free (plaintext); 686 if (NULL != *nonce_str)
687 GNUNET_free (*nonce_str);
701 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n"); 688 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Signature of AuthZ code invalid!\n");
702 return GNUNET_SYSERR; 689 return GNUNET_SYSERR;
703 } 690 }
704 // Attributes 691 // Attributes
705 attrs_ser = ((char *) &params[1]) + code_challenge_len; 692 attrs_ser = ((char *) &params[1]) + code_challenge_len + nonce_len;
706 attrs_ser_len = ntohl (params->attr_list_len); 693 attrs_ser_len = ntohl (params->attr_list_len);
707 *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len); 694 *attrs = GNUNET_RECLAIM_attribute_list_deserialize (attrs_ser, attrs_ser_len);
708 attests_ser = ((char*) attrs_ser) + attrs_ser_len; 695 attests_ser = ((char*) attrs_ser) + attrs_ser_len;
@@ -710,11 +697,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv,
710 *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser, 697 *attests = GNUNET_RECLAIM_attestation_list_deserialize (attests_ser,
711 attests_ser_len); 698 attests_ser_len);
712 699
713 *nonce_str = NULL;
714 if (nonce != 0)
715 GNUNET_asprintf (nonce_str, "%u", nonce);
716 GNUNET_free (code_payload); 700 GNUNET_free (code_payload);
717 GNUNET_free (plaintext);
718 return GNUNET_OK; 701 return GNUNET_OK;
719} 702}
720 703
@@ -757,15 +740,102 @@ OIDC_build_token_response (const char *access_token,
757 * Generate a new access token 740 * Generate a new access token
758 */ 741 */
759char * 742char *
760OIDC_access_token_new () 743OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket)
761{ 744{
762 char *access_token; 745 char *access_token;
763 uint64_t random_number;
764 746
765 random_number = 747 GNUNET_STRINGS_base64_encode (ticket,
766 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, UINT64_MAX); 748 sizeof(*ticket),
767 GNUNET_STRINGS_base64_encode (&random_number,
768 sizeof(uint64_t),
769 &access_token); 749 &access_token);
770 return access_token; 750 return access_token;
771} 751}
752
753
754/**
755 * Parse an access token
756 */
757int
758OIDC_access_token_parse (const char *token,
759 struct GNUNET_RECLAIM_Ticket **ticket)
760{
761 if (sizeof (struct GNUNET_RECLAIM_Ticket) !=
762 GNUNET_STRINGS_base64_decode (token,
763 strlen (token),
764 (void**) ticket))
765 return GNUNET_SYSERR;
766 return GNUNET_OK;
767}
768
769
770/**
771 * Checks if a claim is implicitly requested through standard
772 * scope(s)
773 *
774 * @param scopes the scopes which have been requested
775 * @param attr the attribute name to check
776 * @return GNUNET_YES if attribute is implcitly requested
777 */
778enum GNUNET_GenericReturnValue
779OIDC_check_scopes_for_claim_request (const char*scopes,
780 const char*attr)
781{
782 char *scope_variables;
783 char *scope_variable;
784 char delimiter[] = " ";
785 int i;
786
787 scope_variables = GNUNET_strdup (scopes);
788 scope_variable = strtok (scope_variables, delimiter);
789 while (NULL != scope_variable)
790 {
791 if (0 == strcmp ("profile", scope_variable))
792 {
793 for (i = 0; i < 14; i++)
794 {
795 if (0 == strcmp (attr, OIDC_profile_claims[i]))
796 {
797 GNUNET_free (scope_variables);
798 return GNUNET_YES;
799 }
800 }
801 }
802 else if (0 == strcmp ("address", scope_variable))
803 {
804 for (i = 0; i < 5; i++)
805 {
806 if (0 == strcmp (attr, OIDC_address_claims[i]))
807 {
808 GNUNET_free (scope_variables);
809 return GNUNET_YES;
810 }
811 }
812 }
813 else if (0 == strcmp ("email", scope_variable))
814 {
815 for (i = 0; i < 2; i++)
816 {
817 if (0 == strcmp (attr, OIDC_email_claims[i]))
818 {
819 GNUNET_free (scope_variables);
820 return GNUNET_YES;
821 }
822 }
823 }
824 else if (0 == strcmp ("phone", scope_variable))
825 {
826 for (i = 0; i < 2; i++)
827 {
828 if (0 == strcmp (attr, OIDC_phone_claims[i]))
829 {
830 GNUNET_free (scope_variables);
831 return GNUNET_YES;
832 }
833 }
834
835 }
836 scope_variable = strtok (NULL, delimiter);
837 }
838 GNUNET_free (scope_variables);
839 return GNUNET_NO;
840
841}
diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h
index 2c533357e..e713dab62 100644
--- a/src/reclaim/oidc_helper.h
+++ b/src/reclaim/oidc_helper.h
@@ -49,7 +49,7 @@
49 * @return a new base64-encoded JWT string. 49 * @return a new base64-encoded JWT string.
50 */ 50 */
51char* 51char*
52OIDC_id_token_new (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, 52OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key,
53 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, 53 const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
54 struct GNUNET_RECLAIM_AttributeList *attrs, 54 struct GNUNET_RECLAIM_AttributeList *attrs,
55 struct GNUNET_RECLAIM_AttestationList *attests, 55 struct GNUNET_RECLAIM_AttestationList *attests,
@@ -90,7 +90,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
90 * @return GNUNET_OK if successful, else GNUNET_SYSERR 90 * @return GNUNET_OK if successful, else GNUNET_SYSERR
91 */ 91 */
92int 92int
93OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, 93OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub,
94 const char *code, 94 const char *code,
95 const char *code_verifier, 95 const char *code_verifier,
96 struct GNUNET_RECLAIM_Ticket *ticket, 96 struct GNUNET_RECLAIM_Ticket *ticket,
@@ -117,7 +117,40 @@ OIDC_build_token_response (const char *access_token,
117 * Generate a new access token 117 * Generate a new access token
118 */ 118 */
119char* 119char*
120OIDC_access_token_new (); 120OIDC_access_token_new (const struct GNUNET_RECLAIM_Ticket *ticket);
121 121
122/**
123 * Parse an access token
124 */
125int
126OIDC_access_token_parse (const char* token,
127 struct GNUNET_RECLAIM_Ticket **ticket);
128
129
130/**
131 * Checks if a claim is implicitly requested through standard
132 * scope(s)
133 *
134 * @param scopes the scopes which have been requested
135 * @param attr the attribute name to check
136 * @return GNUNET_YES if attribute is implcitly requested
137 */
138enum GNUNET_GenericReturnValue
139OIDC_check_scopes_for_claim_request (const char*scopes,
140 const char*attr);
141
142
143/**
144 * Generate userinfo JSON as string
145 *
146 * @param sub_key the subject (user)
147 * @param attrs user attribute list
148 * @param attests user attribute attestation list (may be empty)
149 * @return Userinfo JSON
150 */
151char *
152OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key,
153 struct GNUNET_RECLAIM_AttributeList *attrs,
154 struct GNUNET_RECLAIM_AttestationList *attests);
122 155
123#endif 156#endif
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 36ae937c1..06e1b0061 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -28,6 +28,8 @@
28#include <inttypes.h> 28#include <inttypes.h>
29#include <jansson.h> 29#include <jansson.h>
30 30
31#include "gnunet_buffer_lib.h"
32#include "gnunet_strings_lib.h"
31#include "gnunet_gns_service.h" 33#include "gnunet_gns_service.h"
32#include "gnunet_gnsrecord_lib.h" 34#include "gnunet_gnsrecord_lib.h"
33#include "gnunet_identity_service.h" 35#include "gnunet_identity_service.h"
@@ -39,12 +41,18 @@
39#include "gnunet_signatures.h" 41#include "gnunet_signatures.h"
40#include "microhttpd.h" 42#include "microhttpd.h"
41#include "oidc_helper.h" 43#include "oidc_helper.h"
44
42/** 45/**
43 * REST root namespace 46 * REST root namespace
44 */ 47 */
45#define GNUNET_REST_API_NS_OIDC "/openid" 48#define GNUNET_REST_API_NS_OIDC "/openid"
46 49
47/** 50/**
51 * OIDC config
52 */
53#define GNUNET_REST_API_NS_OIDC_CONFIG "/.well-known/openid-configuration"
54
55/**
48 * Authorize endpoint 56 * Authorize endpoint
49 */ 57 */
50#define GNUNET_REST_API_NS_AUTHORIZE "/openid/authorize" 58#define GNUNET_REST_API_NS_AUTHORIZE "/openid/authorize"
@@ -237,12 +245,6 @@ static char *OIDC_ignored_parameter_array[] = { "display",
237struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map; 245struct GNUNET_CONTAINER_MultiHashMap *OIDC_cookie_jar_map;
238 246
239/** 247/**
240 * Hash map that links the issued access token to the corresponding ticket and
241 * ego
242 */
243struct GNUNET_CONTAINER_MultiHashMap *OIDC_access_token_map;
244
245/**
246 * The configuration handle 248 * The configuration handle
247 */ 249 */
248const struct GNUNET_CONFIGURATION_Handle *cfg; 250const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -253,6 +255,36 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
253static char *allow_methods; 255static char *allow_methods;
254 256
255/** 257/**
258 * Ego list
259 */
260static struct EgoEntry *ego_head;
261
262/**
263 * Ego list
264 */
265static struct EgoEntry *ego_tail;
266
267/**
268 * The processing state
269 */
270static int state;
271
272/**
273 * Handle to Identity service.
274 */
275static struct GNUNET_IDENTITY_Handle *identity_handle;
276
277/**
278 * GNS handle
279 */
280static struct GNUNET_GNS_Handle *gns_handle;
281
282/**
283 * Identity Provider
284 */
285static struct GNUNET_RECLAIM_Handle *idp;
286
287/**
256 * @brief struct returned by the initialization function of the plugin 288 * @brief struct returned by the initialization function of the plugin
257 */ 289 */
258struct Plugin 290struct Plugin
@@ -325,10 +357,6 @@ struct OIDC_Variables
325 */ 357 */
326 char *code_verifier; 358 char *code_verifier;
327 359
328 /**
329 * The response JSON
330 */
331 json_t *response;
332}; 360};
333 361
334/** 362/**
@@ -365,15 +393,6 @@ struct EgoEntry
365 393
366struct RequestHandle 394struct RequestHandle
367{ 395{
368 /**
369 * Ego list
370 */
371 struct EgoEntry *ego_head;
372
373 /**
374 * Ego list
375 */
376 struct EgoEntry *ego_tail;
377 396
378 /** 397 /**
379 * Selected ego 398 * Selected ego
@@ -391,39 +410,14 @@ struct RequestHandle
391 struct OIDC_Variables *oidc; 410 struct OIDC_Variables *oidc;
392 411
393 /** 412 /**
394 * The processing state
395 */
396 int state;
397
398 /**
399 * Handle to Identity service.
400 */
401 struct GNUNET_IDENTITY_Handle *identity_handle;
402
403 /**
404 * Rest connection
405 */
406 struct GNUNET_REST_RequestHandle *rest_handle;
407
408 /**
409 * GNS handle
410 */
411 struct GNUNET_GNS_Handle *gns_handle;
412
413 /**
414 * GNS lookup op 413 * GNS lookup op
415 */ 414 */
416 struct GNUNET_GNS_LookupRequest *gns_op; 415 struct GNUNET_GNS_LookupRequest *gns_op;
417 416
418 /** 417 /**
419 * Handle to NAMESTORE 418 * Rest connection
420 */
421 struct GNUNET_NAMESTORE_Handle *namestore_handle;
422
423 /**
424 * Iterator for NAMESTORE
425 */ 419 */
426 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; 420 struct GNUNET_REST_RequestHandle *rest_handle;
427 421
428 /** 422 /**
429 * Attribute claim list for id_token 423 * Attribute claim list for id_token
@@ -446,10 +440,6 @@ struct RequestHandle
446 */ 440 */
447 struct GNUNET_IDENTITY_Operation *op; 441 struct GNUNET_IDENTITY_Operation *op;
448 442
449 /**
450 * Identity Provider
451 */
452 struct GNUNET_RECLAIM_Handle *idp;
453 443
454 /** 444 /**
455 * Idp Operation 445 * Idp Operation
@@ -531,8 +521,14 @@ struct RequestHandle
531 * Reponse code 521 * Reponse code
532 */ 522 */
533 int response_code; 523 int response_code;
524
525 /**
526 * Public client
527 */
528 int public_client;
534}; 529};
535 530
531
536/** 532/**
537 * Cleanup lookup handle 533 * Cleanup lookup handle
538 * @param handle Handle to clean up 534 * @param handle Handle to clean up
@@ -540,13 +536,10 @@ struct RequestHandle
540static void 536static void
541cleanup_handle (struct RequestHandle *handle) 537cleanup_handle (struct RequestHandle *handle)
542{ 538{
543 struct EgoEntry *ego_entry;
544 539
545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
546 if (NULL != handle->timeout_task) 541 if (NULL != handle->timeout_task)
547 GNUNET_SCHEDULER_cancel (handle->timeout_task); 542 GNUNET_SCHEDULER_cancel (handle->timeout_task);
548 if (NULL != handle->identity_handle)
549 GNUNET_IDENTITY_disconnect (handle->identity_handle);
550 if (NULL != handle->attr_it) 543 if (NULL != handle->attr_it)
551 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); 544 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
552 if (NULL != handle->attest_it) 545 if (NULL != handle->attest_it)
@@ -555,8 +548,6 @@ cleanup_handle (struct RequestHandle *handle)
555 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); 548 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
556 if (NULL != handle->idp_op) 549 if (NULL != handle->idp_op)
557 GNUNET_RECLAIM_cancel (handle->idp_op); 550 GNUNET_RECLAIM_cancel (handle->idp_op);
558 if (NULL != handle->idp)
559 GNUNET_RECLAIM_disconnect (handle->idp);
560 GNUNET_free (handle->url); 551 GNUNET_free (handle->url);
561 GNUNET_free (handle->tld); 552 GNUNET_free (handle->tld);
562 GNUNET_free (handle->redirect_prefix); 553 GNUNET_free (handle->redirect_prefix);
@@ -565,11 +556,6 @@ cleanup_handle (struct RequestHandle *handle)
565 GNUNET_free (handle->edesc); 556 GNUNET_free (handle->edesc);
566 if (NULL != handle->gns_op) 557 if (NULL != handle->gns_op)
567 GNUNET_GNS_lookup_cancel (handle->gns_op); 558 GNUNET_GNS_lookup_cancel (handle->gns_op);
568 if (NULL != handle->gns_handle)
569 GNUNET_GNS_disconnect (handle->gns_handle);
570
571 if (NULL != handle->namestore_handle)
572 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
573 if (NULL != handle->oidc) 559 if (NULL != handle->oidc)
574 { 560 {
575 GNUNET_free (handle->oidc->client_id); 561 GNUNET_free (handle->oidc->client_id);
@@ -579,7 +565,6 @@ cleanup_handle (struct RequestHandle *handle)
579 GNUNET_free (handle->oidc->response_type); 565 GNUNET_free (handle->oidc->response_type);
580 GNUNET_free (handle->oidc->scope); 566 GNUNET_free (handle->oidc->scope);
581 GNUNET_free (handle->oidc->state); 567 GNUNET_free (handle->oidc->state);
582 json_decref (handle->oidc->response);
583 GNUNET_free (handle->oidc); 568 GNUNET_free (handle->oidc);
584 } 569 }
585 if (NULL!=handle->attr_idtoken_list) 570 if (NULL!=handle->attr_idtoken_list)
@@ -589,15 +574,6 @@ cleanup_handle (struct RequestHandle *handle)
589 if (NULL!=handle->attests_list) 574 if (NULL!=handle->attests_list)
590 GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list); 575 GNUNET_RECLAIM_attestation_list_destroy (handle->attests_list);
591 576
592 while (NULL != (ego_entry = handle->ego_head))
593 {
594 GNUNET_CONTAINER_DLL_remove (handle->ego_head,
595 handle->ego_tail,
596 ego_entry);
597 GNUNET_free (ego_entry->identifier);
598 GNUNET_free (ego_entry->keystring);
599 GNUNET_free (ego_entry);
600 }
601 GNUNET_free (handle); 577 GNUNET_free (handle);
602} 578}
603 579
@@ -655,6 +631,8 @@ do_userinfo_error (void *cls)
655 struct MHD_Response *resp; 631 struct MHD_Response *resp;
656 char *error; 632 char *error;
657 633
634 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
635 "Error: %s\n", handle->edesc);
658 GNUNET_asprintf (&error, 636 GNUNET_asprintf (&error,
659 "error=\"%s\", error_description=\"%s\"", 637 "error=\"%s\", error_description=\"%s\"",
660 handle->emsg, 638 handle->emsg,
@@ -710,27 +688,6 @@ do_timeout (void *cls)
710 688
711 689
712/** 690/**
713 * Return attributes for claim
714 *
715 * @param cls the request handle
716 */
717static void
718return_userinfo_response (void *cls)
719{
720 char *result_str;
721 struct RequestHandle *handle = cls;
722 struct MHD_Response *resp;
723
724 result_str = json_dumps (handle->oidc->response, 0);
725 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
726 resp = GNUNET_REST_create_response (result_str);
727 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
728 GNUNET_free (result_str);
729 cleanup_handle (handle);
730}
731
732
733/**
734 * Respond to OPTIONS request 691 * Respond to OPTIONS request
735 * 692 *
736 * @param con_handle the connection handle 693 * @param con_handle the connection handle
@@ -854,7 +811,9 @@ login_redirect (void *cls)
854{ 811{
855 char *login_base_url; 812 char *login_base_url;
856 char *new_redirect; 813 char *new_redirect;
814 char *tmp;
857 struct MHD_Response *resp; 815 struct MHD_Response *resp;
816 struct GNUNET_Buffer buf = { 0 };
858 struct RequestHandle *handle = cls; 817 struct RequestHandle *handle = cls;
859 818
860 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 819 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -862,27 +821,68 @@ login_redirect (void *cls)
862 "address", 821 "address",
863 &login_base_url)) 822 &login_base_url))
864 { 823 {
865 GNUNET_asprintf (&new_redirect, 824 GNUNET_buffer_write_str (&buf, login_base_url);
866 "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", 825 GNUNET_buffer_write_fstr (&buf,
867 login_base_url, 826 "?%s=%s",
868 OIDC_RESPONSE_TYPE_KEY, 827 OIDC_RESPONSE_TYPE_KEY,
869 handle->oidc->response_type, 828 handle->oidc->response_type);
870 OIDC_CLIENT_ID_KEY, 829 GNUNET_buffer_write_fstr (&buf,
871 handle->oidc->client_id, 830 "&%s=%s",
872 OIDC_REDIRECT_URI_KEY, 831 OIDC_CLIENT_ID_KEY,
873 handle->oidc->redirect_uri, 832 handle->oidc->client_id);
874 OIDC_SCOPE_KEY, 833 GNUNET_STRINGS_urlencode (handle->oidc->redirect_uri,
875 handle->oidc->scope, 834 strlen (handle->oidc->redirect_uri),
876 OIDC_STATE_KEY, 835 &tmp);
877 (NULL != handle->oidc->state) ? handle->oidc->state : "", 836 GNUNET_buffer_write_fstr (&buf,
878 OIDC_CODE_CHALLENGE_KEY, 837 "&%s=%s",
879 (NULL != handle->oidc->code_challenge) ? 838 OIDC_REDIRECT_URI_KEY,
880 handle->oidc->code_challenge : "", 839 tmp);
881 OIDC_NONCE_KEY, 840 GNUNET_free (tmp);
882 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "", 841 GNUNET_STRINGS_urlencode (handle->oidc->scope,
883 OIDC_CLAIMS_KEY, 842 strlen (handle->oidc->scope),
884 (NULL != handle->oidc->claims) ? handle->oidc->claims : 843 &tmp);
885 ""); 844 GNUNET_buffer_write_fstr (&buf,
845 "&%s=%s",
846 OIDC_SCOPE_KEY,
847 tmp);
848 GNUNET_free (tmp);
849 if (NULL != handle->oidc->state)
850 {
851 GNUNET_STRINGS_urlencode (handle->oidc->state,
852 strlen (handle->oidc->state),
853 &tmp);
854 GNUNET_buffer_write_fstr (&buf,
855 "&%s=%s",
856 OIDC_STATE_KEY,
857 handle->oidc->state);
858 GNUNET_free (tmp);
859 }
860 if (NULL != handle->oidc->code_challenge)
861 {
862 GNUNET_buffer_write_fstr (&buf,
863 "&%s=%s",
864 OIDC_CODE_CHALLENGE_KEY,
865 handle->oidc->code_challenge);
866 }
867 if (NULL != handle->oidc->nonce)
868 {
869 GNUNET_buffer_write_fstr (&buf,
870 "&%s=%s",
871 OIDC_NONCE_KEY,
872 handle->oidc->nonce);
873 }
874 if (NULL != handle->oidc->claims)
875 {
876 GNUNET_STRINGS_urlencode (handle->oidc->claims,
877 strlen (handle->oidc->claims),
878 &tmp);
879 GNUNET_buffer_write_fstr (&buf,
880 "&%s=%s",
881 OIDC_CLAIMS_KEY,
882 tmp);
883 GNUNET_free (tmp);
884 }
885 new_redirect = GNUNET_buffer_reap_str (&buf);
886 resp = GNUNET_REST_create_response (""); 886 resp = GNUNET_REST_create_response ("");
887 MHD_add_response_header (resp, "Location", new_redirect); 887 MHD_add_response_header (resp, "Location", new_redirect);
888 GNUNET_free (login_base_url); 888 GNUNET_free (login_base_url);
@@ -954,6 +954,8 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
954 handle->redirect_prefix, 954 handle->redirect_prefix,
955 handle->tld, 955 handle->tld,
956 handle->redirect_suffix, 956 handle->redirect_suffix,
957 (NULL == strchr (handle->redirect_suffix, '?') ? "?" :
958 "&"),
957 handle->oidc->response_type, 959 handle->oidc->response_type,
958 code_string, 960 code_string,
959 handle->oidc->state); 961 handle->oidc->state);
@@ -961,8 +963,10 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
961 else 963 else
962 { 964 {
963 GNUNET_asprintf (&redirect_uri, 965 GNUNET_asprintf (&redirect_uri,
964 "%s?%s=%s&state=%s", 966 "%s%s%s=%s&state=%s",
965 handle->oidc->redirect_uri, 967 handle->oidc->redirect_uri,
968 (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" :
969 "&"),
966 handle->oidc->response_type, 970 handle->oidc->response_type,
967 code_string, 971 code_string,
968 handle->oidc->state); 972 handle->oidc->state);
@@ -1041,7 +1045,7 @@ oidc_attest_collect_finished_cb (void *cls)
1041 handle->attest_it = NULL; 1045 handle->attest_it = NULL;
1042 merged_list = attribute_list_merge (handle->attr_idtoken_list, 1046 merged_list = attribute_list_merge (handle->attr_idtoken_list,
1043 handle->attr_userinfo_list); 1047 handle->attr_userinfo_list);
1044 handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, 1048 handle->idp_op = GNUNET_RECLAIM_ticket_issue (idp,
1045 &handle->priv_key, 1049 &handle->priv_key,
1046 &handle->oidc->client_pkey, 1050 &handle->oidc->client_pkey,
1047 merged_list, 1051 merged_list,
@@ -1108,7 +1112,7 @@ oidc_attr_collect_finished_cb (void *cls)
1108 } 1112 }
1109 handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList); 1113 handle->attests_list = GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
1110 handle->attest_it = 1114 handle->attest_it =
1111 GNUNET_RECLAIM_get_attestations_start (handle->idp, 1115 GNUNET_RECLAIM_get_attestations_start (idp,
1112 &handle->priv_key, 1116 &handle->priv_key,
1113 &oidc_iteration_error, 1117 &oidc_iteration_error,
1114 handle, 1118 handle,
@@ -1125,9 +1129,6 @@ attr_in_claims_request (struct RequestHandle *handle,
1125 const char *attr_name, 1129 const char *attr_name,
1126 const char *claims_parameter) 1130 const char *claims_parameter)
1127{ 1131{
1128 char *scope_variables;
1129 char *scope_variable;
1130 char delimiter[] = " ";
1131 int ret = GNUNET_NO; 1132 int ret = GNUNET_NO;
1132 json_t *root; 1133 json_t *root;
1133 json_error_t error; 1134 json_error_t error;
@@ -1135,19 +1136,12 @@ attr_in_claims_request (struct RequestHandle *handle,
1135 const char *key; 1136 const char *key;
1136 json_t *value; 1137 json_t *value;
1137 1138
1138 scope_variables = GNUNET_strdup (handle->oidc->scope); 1139 /** Check if attribute is requested through standard scope **/
1139 scope_variable = strtok (scope_variables, delimiter); 1140 if (GNUNET_YES == OIDC_check_scopes_for_claim_request (handle->oidc->scope,
1140 while (NULL != scope_variable) 1141 attr_name))
1141 { 1142 return GNUNET_YES;
1142 if (0 == strcmp (attr_name, scope_variable))
1143 break;
1144 scope_variable = strtok (NULL, delimiter);
1145 }
1146 if (NULL != scope_variable)
1147 ret = GNUNET_YES;
1148 GNUNET_free (scope_variables);
1149 1143
1150 /** Try claims parameter if no in scope */ 1144 /** Try claims parameter if not in scope */
1151 if ((NULL != handle->oidc->claims) && 1145 if ((NULL != handle->oidc->claims) &&
1152 (GNUNET_YES != ret)) 1146 (GNUNET_YES != ret))
1153 { 1147 {
@@ -1274,7 +1268,7 @@ code_redirect (void *cls)
1274 return; 1268 return;
1275 } 1269 }
1276 // iterate over egos and compare their public key 1270 // iterate over egos and compare their public key
1277 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; 1271 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1278 handle->ego_entry = handle->ego_entry->next) 1272 handle->ego_entry = handle->ego_entry->next)
1279 { 1273 {
1280 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); 1274 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
@@ -1282,13 +1276,12 @@ code_redirect (void *cls)
1282 { 1276 {
1283 handle->priv_key = 1277 handle->priv_key =
1284 *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); 1278 *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1285 handle->idp = GNUNET_RECLAIM_connect (cfg);
1286 handle->attr_idtoken_list = 1279 handle->attr_idtoken_list =
1287 GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 1280 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1288 handle->attr_userinfo_list = 1281 handle->attr_userinfo_list =
1289 GNUNET_new (struct GNUNET_RECLAIM_AttributeList); 1282 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1290 handle->attr_it = 1283 handle->attr_it =
1291 GNUNET_RECLAIM_get_attributes_start (handle->idp, 1284 GNUNET_RECLAIM_get_attributes_start (idp,
1292 &handle->priv_key, 1285 &handle->priv_key,
1293 &oidc_iteration_error, 1286 &oidc_iteration_error,
1294 handle, 1287 handle,
@@ -1433,7 +1426,7 @@ client_redirect (void *cls)
1433 1426
1434 /* Lookup client redirect uri to verify request */ 1427 /* Lookup client redirect uri to verify request */
1435 handle->gns_op = 1428 handle->gns_op =
1436 GNUNET_GNS_lookup (handle->gns_handle, 1429 GNUNET_GNS_lookup (gns_handle,
1437 GNUNET_GNS_EMPTY_LABEL_AT, 1430 GNUNET_GNS_EMPTY_LABEL_AT,
1438 &handle->oidc->client_pkey, 1431 &handle->oidc->client_pkey,
1439 GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, 1432 GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT,
@@ -1448,6 +1441,7 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key)
1448{ 1441{
1449 struct GNUNET_HashCode hc; 1442 struct GNUNET_HashCode hc;
1450 char *value; 1443 char *value;
1444 char *res;
1451 1445
1452 GNUNET_CRYPTO_hash (key, strlen (key), &hc); 1446 GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1453 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1447 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
@@ -1458,7 +1452,8 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key)
1458 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); 1452 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc);
1459 if (NULL == value) 1453 if (NULL == value)
1460 return NULL; 1454 return NULL;
1461 return GNUNET_strdup (value); 1455 GNUNET_STRINGS_urldecode (value, strlen (value), &res);
1456 return res;
1462} 1457}
1463 1458
1464 1459
@@ -1657,14 +1652,14 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1657 1652
1658 // If we know this identity, translated the corresponding TLD 1653 // If we know this identity, translated the corresponding TLD
1659 // TODO: We might want to have a reverse lookup functionality for TLDs? 1654 // TODO: We might want to have a reverse lookup functionality for TLDs?
1660 for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) 1655 for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1661 { 1656 {
1662 priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); 1657 priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1663 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); 1658 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey);
1664 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) 1659 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1665 { 1660 {
1666 handle->tld = GNUNET_strdup (tmp_ego->identifier); 1661 handle->tld = GNUNET_strdup (tmp_ego->identifier);
1667 handle->ego_entry = handle->ego_tail; 1662 handle->ego_entry = ego_tail;
1668 } 1663 }
1669 } 1664 }
1670 handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); 1665 handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
@@ -1749,16 +1744,16 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle,
1749 1744
1750 1745
1751static int 1746static int
1752check_authorization (struct RequestHandle *handle, 1747parse_credentials_basic_auth (struct RequestHandle *handle,
1753 struct GNUNET_CRYPTO_EcdsaPublicKey *cid) 1748 char **client_id,
1749 char **client_secret)
1754{ 1750{
1755 struct GNUNET_HashCode cache_key; 1751 struct GNUNET_HashCode cache_key;
1756 char *authorization; 1752 char *authorization;
1757 char *credentials; 1753 char *credentials;
1758 char *basic_authorization; 1754 char *basic_authorization;
1759 char *client_id; 1755 char *client_id_tmp;
1760 char *pass; 1756 char *pass;
1761 char *expected_pass;
1762 1757
1763 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, 1758 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
1764 strlen (OIDC_AUTHORIZATION_HEADER_KEY), 1759 strlen (OIDC_AUTHORIZATION_HEADER_KEY),
@@ -1766,12 +1761,7 @@ check_authorization (struct RequestHandle *handle,
1766 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1761 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
1767 ->header_param_map, 1762 ->header_param_map,
1768 &cache_key)) 1763 &cache_key))
1769 {
1770 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1771 handle->edesc = GNUNET_strdup ("missing authorization");
1772 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1773 return GNUNET_SYSERR; 1764 return GNUNET_SYSERR;
1774 }
1775 authorization = 1765 authorization =
1776 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, 1766 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
1777 &cache_key); 1767 &cache_key);
@@ -1779,44 +1769,117 @@ check_authorization (struct RequestHandle *handle,
1779 // split header in "Basic" and [content] 1769 // split header in "Basic" and [content]
1780 credentials = strtok (authorization, " "); 1770 credentials = strtok (authorization, " ");
1781 if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) 1771 if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1782 {
1783 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1784 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1785 return GNUNET_SYSERR; 1772 return GNUNET_SYSERR;
1786 }
1787 credentials = strtok (NULL, " "); 1773 credentials = strtok (NULL, " ");
1788 if (NULL == credentials) 1774 if (NULL == credentials)
1789 {
1790 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1791 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1792 return GNUNET_SYSERR; 1775 return GNUNET_SYSERR;
1793 }
1794 GNUNET_STRINGS_base64_decode (credentials, 1776 GNUNET_STRINGS_base64_decode (credentials,
1795 strlen (credentials), 1777 strlen (credentials),
1796 (void **) &basic_authorization); 1778 (void **) &basic_authorization);
1797 1779
1798 if (NULL == basic_authorization) 1780 if (NULL == basic_authorization)
1799 {
1800 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1801 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1802 return GNUNET_SYSERR; 1781 return GNUNET_SYSERR;
1803 } 1782 client_id_tmp = strtok (basic_authorization, ":");
1804 client_id = strtok (basic_authorization, ":"); 1783 if (NULL == client_id_tmp)
1805 if (NULL == client_id)
1806 { 1784 {
1807 GNUNET_free (basic_authorization); 1785 GNUNET_free (basic_authorization);
1808 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1809 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1810 return GNUNET_SYSERR; 1786 return GNUNET_SYSERR;
1811 } 1787 }
1812 pass = strtok (NULL, ":"); 1788 pass = strtok (NULL, ":");
1813 if (NULL == pass) 1789 if (NULL == pass)
1814 { 1790 {
1815 GNUNET_free (basic_authorization); 1791 GNUNET_free (basic_authorization);
1816 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1817 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1818 return GNUNET_SYSERR; 1792 return GNUNET_SYSERR;
1819 } 1793 }
1794 *client_id = strdup (client_id_tmp);
1795 *client_secret = strdup (pass);
1796 GNUNET_free (basic_authorization);
1797 return GNUNET_OK;
1798}
1799
1800
1801static int
1802parse_credentials_post_body (struct RequestHandle *handle,
1803 char **client_id,
1804 char **client_secret)
1805{
1806 struct GNUNET_HashCode cache_key;
1807 char *client_id_tmp;
1808 char *pass;
1809
1810 GNUNET_CRYPTO_hash ("client_id",
1811 strlen ("client_id"),
1812 &cache_key);
1813 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
1814 ->url_param_map,
1815 &cache_key))
1816 return GNUNET_SYSERR;
1817 client_id_tmp = GNUNET_CONTAINER_multihashmap_get (
1818 handle->rest_handle->url_param_map,
1819 &cache_key);
1820 if (NULL == client_id_tmp)
1821 return GNUNET_SYSERR;
1822 *client_id = strdup (client_id_tmp);
1823 GNUNET_CRYPTO_hash ("client_secret",
1824 strlen ("client_secret"),
1825 &cache_key);
1826 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
1827 ->url_param_map,
1828 &cache_key))
1829 return GNUNET_SYSERR;
1830 pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
1831 &cache_key);
1832 if (NULL == pass)
1833 return GNUNET_SYSERR;
1834 *client_secret = strdup (pass);
1835 return GNUNET_OK;
1836}
1837
1838
1839static int
1840check_authorization (struct RequestHandle *handle,
1841 struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
1842{
1843 char *expected_pass;
1844 char *received_cid;
1845 char *received_cpw;
1846 char *pkce_cv;
1847
1848 if (GNUNET_OK == parse_credentials_basic_auth (handle,
1849 &received_cid,
1850 &received_cpw))
1851 {
1852 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1853 "Received client credentials in HTTP AuthZ header\n");
1854 }
1855 else if (GNUNET_OK == parse_credentials_post_body (handle,
1856 &received_cid,
1857 &received_cpw))
1858 {
1859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1860 "Received client credentials in POST body\n");
1861 }
1862 else
1863 {
1864 /** Allow public clients with PKCE **/
1865 pkce_cv = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY);
1866 if (NULL == pkce_cv)
1867 {
1868 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1869 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1870 return GNUNET_SYSERR;
1871 }
1872 handle->public_client = GNUNET_YES;
1873 GNUNET_free (pkce_cv);
1874 received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY);
1875 GNUNET_STRINGS_string_to_data (received_cid,
1876 strlen (received_cid),
1877 cid,
1878 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1879 GNUNET_free (received_cid);
1880 return GNUNET_OK;
1881
1882 }
1820 1883
1821 // check client password 1884 // check client password
1822 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 1885 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -1824,9 +1887,8 @@ check_authorization (struct RequestHandle *handle,
1824 "OIDC_CLIENT_SECRET", 1887 "OIDC_CLIENT_SECRET",
1825 &expected_pass)) 1888 &expected_pass))
1826 { 1889 {
1827 if (0 != strcmp (expected_pass, pass)) 1890 if (0 != strcmp (expected_pass, received_cpw))
1828 { 1891 {
1829 GNUNET_free (basic_authorization);
1830 GNUNET_free (expected_pass); 1892 GNUNET_free (expected_pass);
1831 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1893 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1832 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1894 handle->response_code = MHD_HTTP_UNAUTHORIZED;
@@ -1836,33 +1898,33 @@ check_authorization (struct RequestHandle *handle,
1836 } 1898 }
1837 else 1899 else
1838 { 1900 {
1839 GNUNET_free (basic_authorization);
1840 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1901 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR);
1841 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 1902 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1842 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1903 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1843 return GNUNET_SYSERR; 1904 return GNUNET_SYSERR;
1844 } 1905 }
1845
1846 // check client_id 1906 // check client_id
1847 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; 1907 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1848 handle->ego_entry = handle->ego_entry->next) 1908 handle->ego_entry = handle->ego_entry->next)
1849 { 1909 {
1850 if (0 == strcmp (handle->ego_entry->keystring, client_id)) 1910 if (0 == strcmp (handle->ego_entry->keystring, received_cid))
1851 break; 1911 break;
1852 } 1912 }
1853 if (NULL == handle->ego_entry) 1913 if (NULL == handle->ego_entry)
1854 { 1914 {
1855 GNUNET_free (basic_authorization); 1915 GNUNET_free (received_cpw);
1916 GNUNET_free (received_cid);
1856 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1917 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1857 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1918 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1858 return GNUNET_SYSERR; 1919 return GNUNET_SYSERR;
1859 } 1920 }
1860 GNUNET_STRINGS_string_to_data (client_id, 1921 GNUNET_STRINGS_string_to_data (received_cid,
1861 strlen (client_id), 1922 strlen (received_cid),
1862 cid, 1923 cid,
1863 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 1924 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1864 1925
1865 GNUNET_free (basic_authorization); 1926 GNUNET_free (received_cpw);
1927 GNUNET_free (received_cid);
1866 return GNUNET_OK; 1928 return GNUNET_OK;
1867} 1929}
1868 1930
@@ -1874,7 +1936,7 @@ find_ego (struct RequestHandle *handle,
1874 struct EgoEntry *ego_entry; 1936 struct EgoEntry *ego_entry;
1875 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 1937 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1876 1938
1877 for (ego_entry = handle->ego_head; NULL != ego_entry; 1939 for (ego_entry = ego_head; NULL != ego_entry;
1878 ego_entry = ego_entry->next) 1940 ego_entry = ego_entry->next)
1879 { 1941 {
1880 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); 1942 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
@@ -1885,26 +1947,6 @@ find_ego (struct RequestHandle *handle,
1885} 1947}
1886 1948
1887 1949
1888static void
1889persist_access_token (const struct RequestHandle *handle,
1890 const char *access_token,
1891 const struct GNUNET_RECLAIM_Ticket *ticket)
1892{
1893 struct GNUNET_HashCode hc;
1894 struct GNUNET_RECLAIM_Ticket *ticketbuf;
1895
1896 GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc);
1897 ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
1898 *ticketbuf = *ticket;
1899 GNUNET_assert (GNUNET_SYSERR !=
1900 GNUNET_CONTAINER_multihashmap_put (
1901 OIDC_access_token_map,
1902 &hc,
1903 ticketbuf,
1904 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1905}
1906
1907
1908/** 1950/**
1909 * Responds to token url-encoded POST request 1951 * Responds to token url-encoded POST request
1910 * 1952 *
@@ -2008,7 +2050,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2008 } 2050 }
2009 2051
2010 // decode code 2052 // decode code
2011 if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, 2053 if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket,
2012 &cl, &al, &nonce)) 2054 &cl, &al, &nonce))
2013 { 2055 {
2014 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 2056 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST);
@@ -2046,20 +2088,19 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2046 GNUNET_SCHEDULER_add_now (&do_error, handle); 2088 GNUNET_SCHEDULER_add_now (&do_error, handle);
2047 return; 2089 return;
2048 } 2090 }
2049 id_token = OIDC_id_token_new (&ticket.audience, 2091 id_token = OIDC_generate_id_token (&ticket.audience,
2050 &ticket.identity, 2092 &ticket.identity,
2051 cl, 2093 cl,
2052 al, 2094 al,
2053 &expiration_time, 2095 &expiration_time,
2054 (NULL != nonce) ? nonce : NULL, 2096 (NULL != nonce) ? nonce : NULL,
2055 jwt_secret); 2097 jwt_secret);
2056 access_token = OIDC_access_token_new (); 2098 access_token = OIDC_access_token_new (&ticket);
2057 OIDC_build_token_response (access_token, 2099 OIDC_build_token_response (access_token,
2058 id_token, 2100 id_token,
2059 &expiration_time, 2101 &expiration_time,
2060 &json_response); 2102 &json_response);
2061 2103
2062 persist_access_token (handle, access_token, &ticket);
2063 resp = GNUNET_REST_create_response (json_response); 2104 resp = GNUNET_REST_create_response (json_response);
2064 MHD_add_response_header (resp, "Cache-Control", "no-store"); 2105 MHD_add_response_header (resp, "Cache-Control", "no-store");
2065 MHD_add_response_header (resp, "Pragma", "no-cache"); 2106 MHD_add_response_header (resp, "Pragma", "no-cache");
@@ -2084,83 +2125,56 @@ consume_ticket (void *cls,
2084 const struct GNUNET_RECLAIM_Attestation *attest) 2125 const struct GNUNET_RECLAIM_Attestation *attest)
2085{ 2126{
2086 struct RequestHandle *handle = cls; 2127 struct RequestHandle *handle = cls;
2128 struct GNUNET_RECLAIM_AttributeListEntry *ale;
2129 struct GNUNET_RECLAIM_AttestationListEntry *atle;
2130 struct MHD_Response *resp;
2131 char *result_str;
2087 handle->idp_op = NULL; 2132 handle->idp_op = NULL;
2088 2133
2134 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attr: %s\n", attr->name);
2089 if (NULL == identity) 2135 if (NULL == identity)
2090 { 2136 {
2091 GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); 2137 result_str = OIDC_generate_userinfo (&handle->ticket.identity,
2138 handle->attr_userinfo_list,
2139 handle->attests_list);
2140 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Userinfo: %s\n", result_str);
2141 resp = GNUNET_REST_create_response (result_str);
2142 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2143 GNUNET_free (result_str);
2144 cleanup_handle (handle);
2092 return; 2145 return;
2093 } 2146 }
2094 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attr->attestation)) 2147 ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
2148 ale->attribute = GNUNET_RECLAIM_attribute_new (attr->name,
2149 &attr->attestation,
2150 attr->type,
2151 attr->data,
2152 attr->data_size);
2153 ale->attribute->id = attr->id;
2154 ale->attribute->flag = attr->flag;
2155 ale->attribute->attestation = attr->attestation;
2156 GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head,
2157 handle->attr_userinfo_list->list_tail,
2158 ale);
2159 for (atle = handle->attests_list->list_head; NULL != atle; atle = atle->next)
2160 {
2161 if (GNUNET_NO == GNUNET_RECLAIM_id_is_equal (&atle->attestation->id,
2162 &attest->id))
2163 continue;
2164 break; /** already in list **/
2165 }
2166 if (NULL == atle)
2095 { 2167 {
2096 char *tmp_value; 2168 /** Attestation matches for attribute, add **/
2097 json_t *value; 2169 atle = GNUNET_new (struct GNUNET_RECLAIM_AttestationListEntry);
2098 tmp_value = GNUNET_RECLAIM_attribute_value_to_string (attr->type, 2170 atle->attestation = GNUNET_RECLAIM_attestation_new (attest->name,
2099 attr->data, 2171 attest->type,
2100 attr->data_size); 2172 attest->data,
2101 value = json_string (tmp_value); 2173 attest->data_size);
2102 json_object_set_new (handle->oidc->response, attr->name, value); 2174 GNUNET_CONTAINER_DLL_insert (handle->attests_list->list_head,
2103 GNUNET_free (tmp_value); 2175 handle->attests_list->list_tail,
2104 return; 2176 atle);
2105 } 2177 }
2106 json_t *claim_sources;
2107 json_t *claim_sources_jwt;
2108 json_t *claim_names;
2109 char *attest_val_str;
2110 claim_sources = json_object_get (handle->oidc->response,"_claim_sources");
2111 claim_names = json_object_get (handle->oidc->response,"_claim_names");
2112 attest_val_str =
2113 GNUNET_RECLAIM_attestation_value_to_string (attest->type,
2114 attest->data,
2115 attest->data_size);
2116 if ((NULL == claim_sources) && (NULL == claim_names) )
2117 {
2118 claim_sources = json_object ();
2119 claim_names = json_object ();
2120 }
2121 char *source_name;
2122 int i = 0;
2123 GNUNET_asprintf (&source_name, "src%d", i);
2124 while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
2125 source_name)))
2126 {
2127 if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
2128 "JWT")),
2129 attest_val_str))
2130 {
2131 // Adapt only the claim names
2132 json_object_set_new (claim_names, attr->data,
2133 json_string (source_name));
2134 json_object_set (handle->oidc->response,
2135 "_claim_names", claim_names);
2136 break;
2137 }
2138 i++;
2139 GNUNET_free (source_name);
2140 GNUNET_asprintf (&source_name, "src%d", i);
2141 }
2142
2143 // Create new one
2144 if (NULL == claim_sources_jwt)
2145 {
2146 claim_sources_jwt = json_object ();
2147 // Set the JWT for names
2148 json_object_set_new (claim_names, attr->data,
2149 json_string (source_name));
2150 // Set the JWT for the inner source
2151 json_object_set_new (claim_sources_jwt, "JWT",
2152 json_string (attest_val_str));
2153 // Set the JWT for the source
2154 json_object_set_new (claim_sources, source_name, claim_sources_jwt);
2155 // Set as claims
2156 json_object_set (handle->oidc->response, "_claim_names", claim_names);
2157 json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
2158 }
2159
2160 json_decref (claim_sources);
2161 json_decref (claim_names);
2162 json_decref (claim_sources_jwt);
2163 GNUNET_free (attest_val_str);
2164} 2178}
2165 2179
2166 2180
@@ -2178,15 +2192,16 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2178{ 2192{
2179 // TODO expiration time 2193 // TODO expiration time
2180 struct RequestHandle *handle = cls; 2194 struct RequestHandle *handle = cls;
2195 struct GNUNET_RECLAIM_Ticket *ticket;
2181 char delimiter[] = " "; 2196 char delimiter[] = " ";
2182 struct GNUNET_HashCode cache_key; 2197 struct GNUNET_HashCode cache_key;
2183 char *authorization; 2198 char *authorization;
2184 char *authorization_type; 2199 char *authorization_type;
2185 char *authorization_access_token; 2200 char *authorization_access_token;
2186 struct GNUNET_RECLAIM_Ticket *ticket; 2201 const struct EgoEntry *aud_ego;
2187 const struct EgoEntry *ego_entry;
2188 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 2202 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
2189 2203
2204 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n");
2190 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, 2205 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
2191 strlen (OIDC_AUTHORIZATION_HEADER_KEY), 2206 strlen (OIDC_AUTHORIZATION_HEADER_KEY),
2192 &cache_key); 2207 &cache_key);
@@ -2228,25 +2243,22 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2228 return; 2243 return;
2229 } 2244 }
2230 2245
2231 GNUNET_CRYPTO_hash (authorization_access_token, 2246 if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token,
2232 strlen (authorization_access_token), 2247 &ticket))
2233 &cache_key);
2234 if (GNUNET_NO ==
2235 GNUNET_CONTAINER_multihashmap_contains (OIDC_access_token_map,
2236 &cache_key))
2237 { 2248 {
2238 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 2249 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN);
2239 handle->edesc = GNUNET_strdup ("The access token expired"); 2250 handle->edesc = GNUNET_strdup ("The access token is invalid");
2240 handle->response_code = MHD_HTTP_UNAUTHORIZED; 2251 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2241 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 2252 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle);
2242 GNUNET_free (authorization); 2253 GNUNET_free (authorization);
2243 return; 2254 return;
2255
2244 } 2256 }
2245 ticket =
2246 GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key);
2247 GNUNET_assert (NULL != ticket); 2257 GNUNET_assert (NULL != ticket);
2248 ego_entry = find_ego (handle, &ticket->audience); 2258 handle->ticket = *ticket;
2249 if (NULL == ego_entry) 2259 GNUNET_free (ticket);
2260 aud_ego = find_ego (handle, &handle->ticket.audience);
2261 if (NULL == aud_ego)
2250 { 2262 {
2251 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 2263 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN);
2252 handle->edesc = GNUNET_strdup ("The access token expired"); 2264 handle->edesc = GNUNET_strdup ("The access token expired");
@@ -2255,53 +2267,23 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2255 GNUNET_free (authorization); 2267 GNUNET_free (authorization);
2256 return; 2268 return;
2257 } 2269 }
2270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n");
2271 privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego);
2272 handle->attr_userinfo_list =
2273 GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
2274 handle->attests_list =
2275 GNUNET_new (struct GNUNET_RECLAIM_AttestationList);
2258 2276
2259 handle->idp = GNUNET_RECLAIM_connect (cfg); 2277 handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp,
2260 handle->oidc->response = json_object ();
2261 json_object_set_new (handle->oidc->response,
2262 "sub",
2263 json_string (ego_entry->keystring));
2264 privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
2265 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
2266 privkey, 2278 privkey,
2267 ticket, 2279 &handle->ticket,
2268 consume_ticket, 2280 &consume_ticket,
2269 handle); 2281 handle);
2270 GNUNET_free (authorization); 2282 GNUNET_free (authorization);
2271} 2283}
2272 2284
2273 2285
2274/** 2286/**
2275 * Handle rest request
2276 *
2277 * @param handle the request handle
2278 */
2279static void
2280init_cont (struct RequestHandle *handle)
2281{
2282 struct GNUNET_REST_RequestHandlerError err;
2283 static const struct GNUNET_REST_RequestHandler handlers[] =
2284 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
2285 { MHD_HTTP_METHOD_POST,
2286 GNUNET_REST_API_NS_AUTHORIZE,
2287 &authorize_endpoint }, // url-encoded
2288 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
2289 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
2290 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2291 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2292 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
2293 GNUNET_REST_HANDLER_END };
2294
2295 if (GNUNET_NO ==
2296 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
2297 {
2298 handle->response_code = err.error_code;
2299 GNUNET_SCHEDULER_add_now (&do_error, handle);
2300 }
2301}
2302
2303
2304/**
2305 * If listing is enabled, prints information about the egos. 2287 * If listing is enabled, prints information about the egos.
2306 * 2288 *
2307 * This function is initially called for all egos and then again 2289 * This function is initially called for all egos and then again
@@ -2340,18 +2322,16 @@ list_ego (void *cls,
2340 void **ctx, 2322 void **ctx,
2341 const char *identifier) 2323 const char *identifier)
2342{ 2324{
2343 struct RequestHandle *handle = cls;
2344 struct EgoEntry *ego_entry; 2325 struct EgoEntry *ego_entry;
2345 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 2326 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
2346 2327
2347 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 2328 if ((NULL == ego) && (ID_REST_STATE_INIT == state))
2348 { 2329 {
2349 handle->state = ID_REST_STATE_POST_INIT; 2330 state = ID_REST_STATE_POST_INIT;
2350 init_cont (handle);
2351 return; 2331 return;
2352 } 2332 }
2353 GNUNET_assert (NULL != ego); 2333 GNUNET_assert (NULL != ego);
2354 if (ID_REST_STATE_INIT == handle->state) 2334 if (ID_REST_STATE_INIT == state)
2355 2335
2356 { 2336 {
2357 ego_entry = GNUNET_new (struct EgoEntry); 2337 ego_entry = GNUNET_new (struct EgoEntry);
@@ -2359,15 +2339,15 @@ list_ego (void *cls,
2359 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 2339 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
2360 ego_entry->ego = ego; 2340 ego_entry->ego = ego;
2361 ego_entry->identifier = GNUNET_strdup (identifier); 2341 ego_entry->identifier = GNUNET_strdup (identifier);
2362 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 2342 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
2363 handle->ego_tail, 2343 ego_tail,
2364 ego_entry); 2344 ego_entry);
2365 return; 2345 return;
2366 } 2346 }
2367 /* Ego renamed or added */ 2347 /* Ego renamed or added */
2368 if (identifier != NULL) 2348 if (identifier != NULL)
2369 { 2349 {
2370 for (ego_entry = handle->ego_head; NULL != ego_entry; 2350 for (ego_entry = ego_head; NULL != ego_entry;
2371 ego_entry = ego_entry->next) 2351 ego_entry = ego_entry->next)
2372 { 2352 {
2373 if (ego_entry->ego == ego) 2353 if (ego_entry->ego == ego)
@@ -2386,15 +2366,15 @@ list_ego (void *cls,
2386 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 2366 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
2387 ego_entry->ego = ego; 2367 ego_entry->ego = ego;
2388 ego_entry->identifier = GNUNET_strdup (identifier); 2368 ego_entry->identifier = GNUNET_strdup (identifier);
2389 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 2369 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
2390 handle->ego_tail, 2370 ego_tail,
2391 ego_entry); 2371 ego_entry);
2392 } 2372 }
2393 } 2373 }
2394 else 2374 else
2395 { 2375 {
2396 /* Delete */ 2376 /* Delete */
2397 for (ego_entry = handle->ego_head; NULL != ego_entry; 2377 for (ego_entry = ego_head; NULL != ego_entry;
2398 ego_entry = ego_entry->next) 2378 ego_entry = ego_entry->next)
2399 { 2379 {
2400 if (ego_entry->ego == ego) 2380 if (ego_entry->ego == ego)
@@ -2403,8 +2383,8 @@ list_ego (void *cls,
2403 if (NULL == ego_entry) 2383 if (NULL == ego_entry)
2404 return; /* Not found */ 2384 return; /* Not found */
2405 2385
2406 GNUNET_CONTAINER_DLL_remove (handle->ego_head, 2386 GNUNET_CONTAINER_DLL_remove (ego_head,
2407 handle->ego_tail, 2387 ego_tail,
2408 ego_entry); 2388 ego_entry);
2409 GNUNET_free (ego_entry->identifier); 2389 GNUNET_free (ego_entry->identifier);
2410 GNUNET_free (ego_entry->keystring); 2390 GNUNET_free (ego_entry->keystring);
@@ -2415,36 +2395,153 @@ list_ego (void *cls,
2415 2395
2416 2396
2417static void 2397static void
2398oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2399 const char *url,
2400 void *cls)
2401{
2402 json_t *oidc_config;
2403 json_t *auth_methods;
2404 json_t *sig_algs;
2405 json_t *scopes;
2406 json_t *response_types;
2407 json_t *sub_types;
2408 json_t *claim_types;
2409 char *oidc_config_str;
2410 struct MHD_Response *resp;
2411 struct RequestHandle *handle = cls;
2412
2413 oidc_config = json_object ();
2414 // FIXME get from config?
2415 json_object_set_new (oidc_config,
2416 "issuer", json_string ("http://localhost:7776"));
2417 json_object_set_new (oidc_config,
2418 "authorization_endpoint",
2419 json_string ("https://api.reclaim/openid/authorize"));
2420 json_object_set_new (oidc_config,
2421 "token_endpoint",
2422 json_string ("http://localhost:7776/openid/token"));
2423 auth_methods = json_array ();
2424 json_array_append_new (auth_methods,
2425 json_string ("client_secret_basic"));
2426 json_array_append_new (auth_methods,
2427 json_string ("client_secret_post"));
2428 json_object_set_new (oidc_config,
2429 "token_endpoint_auth_methods_supported",
2430 auth_methods);
2431 sig_algs = json_array ();
2432 json_array_append_new (sig_algs,
2433 json_string ("HS512"));
2434 json_object_set_new (oidc_config,
2435 "id_token_signing_alg_values_supported",
2436 sig_algs);
2437 json_object_set_new (oidc_config,
2438 "userinfo_endpoint",
2439 json_string ("http://localhost:7776/openid/userinfo"));
2440 scopes = json_array ();
2441 json_array_append_new (scopes,
2442 json_string ("openid"));
2443 json_array_append_new (scopes,
2444 json_string ("profile"));
2445 json_object_set_new (oidc_config,
2446 "scopes_supported",
2447 scopes);
2448 response_types = json_array ();
2449 json_array_append_new (response_types,
2450 json_string ("code"));
2451 json_object_set_new (oidc_config,
2452 "response_types_supported",
2453 response_types);
2454 sub_types = json_array ();
2455 json_array_append_new (sub_types,
2456 json_string ("public")); /* no pairwise suppport */
2457 json_object_set_new (oidc_config,
2458 "subject_types_supported",
2459 sub_types);
2460 claim_types = json_array ();
2461 json_array_append_new (claim_types,
2462 json_string ("normal"));
2463 json_array_append_new (claim_types,
2464 json_string ("aggregated"));
2465 json_object_set_new (oidc_config,
2466 "claim_types_supported",
2467 claim_types);
2468 json_object_set_new (oidc_config,
2469 "claims_parameter_supported",
2470 json_boolean (1));
2471 oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1));
2472 resp = GNUNET_REST_create_response (oidc_config_str);
2473 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2474 GNUNET_free (oidc_config_str);
2475 cleanup_handle (handle);
2476}
2477
2478
2479/**
2480 * Respond to OPTIONS request
2481 *
2482 * @param con_handle the connection handle
2483 * @param url the url
2484 * @param cls the RequestHandle
2485 */
2486static void
2487oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle,
2488 const char *url,
2489 void *cls)
2490{
2491 struct MHD_Response *resp;
2492 struct RequestHandle *handle = cls;
2493
2494 // For now, independent of path return all options
2495 resp = GNUNET_REST_create_response (NULL);
2496 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
2497 MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*");
2498 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2499 cleanup_handle (handle);
2500 return;
2501}
2502
2503
2504static enum GNUNET_GenericReturnValue
2418rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 2505rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
2419 GNUNET_REST_ResultProcessor proc, 2506 GNUNET_REST_ResultProcessor proc,
2420 void *proc_cls) 2507 void *proc_cls)
2421{ 2508{
2422 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 2509 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2510 struct GNUNET_REST_RequestHandlerError err;
2511 static const struct GNUNET_REST_RequestHandler handlers[] =
2512 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
2513 { MHD_HTTP_METHOD_POST,
2514 GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, // url-encoded
2515 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
2516 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
2517 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2518 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2519 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG,
2520 &oidc_config_endpoint },
2521 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG,
2522 &oidc_config_cors },
2523 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
2524 GNUNET_REST_HANDLER_END };
2423 2525
2424 handle->oidc = GNUNET_new (struct OIDC_Variables); 2526 handle->oidc = GNUNET_new (struct OIDC_Variables);
2425 if (NULL == OIDC_cookie_jar_map) 2527 if (NULL == OIDC_cookie_jar_map)
2426 OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, 2528 OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10,
2427 GNUNET_NO); 2529 GNUNET_NO);
2428 if (NULL == OIDC_access_token_map)
2429 OIDC_access_token_map =
2430 GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
2431 handle->response_code = 0; 2530 handle->response_code = 0;
2432 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 2531 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
2433 handle->proc_cls = proc_cls; 2532 handle->proc_cls = proc_cls;
2434 handle->proc = proc; 2533 handle->proc = proc;
2435 handle->state = ID_REST_STATE_INIT;
2436 handle->rest_handle = rest_handle; 2534 handle->rest_handle = rest_handle;
2437
2438 handle->url = GNUNET_strdup (rest_handle->url); 2535 handle->url = GNUNET_strdup (rest_handle->url);
2439 if (handle->url[strlen (handle->url) - 1] == '/') 2536 if (handle->url[strlen (handle->url) - 1] == '/')
2440 handle->url[strlen (handle->url) - 1] = '\0'; 2537 handle->url[strlen (handle->url) - 1] = '\0';
2441 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 2538 if (GNUNET_NO ==
2442 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); 2539 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
2443 handle->gns_handle = GNUNET_GNS_connect (cfg); 2540 return GNUNET_NO;
2444 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); 2541
2445 handle->timeout_task = 2542 handle->timeout_task =
2446 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); 2543 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
2447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 2544 return GNUNET_YES;
2448} 2545}
2449 2546
2450 2547
@@ -2469,6 +2566,11 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
2469 api->cls = &plugin; 2566 api->cls = &plugin;
2470 api->name = GNUNET_REST_API_NS_OIDC; 2567 api->name = GNUNET_REST_API_NS_OIDC;
2471 api->process_request = &rest_identity_process_request; 2568 api->process_request = &rest_identity_process_request;
2569 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
2570 gns_handle = GNUNET_GNS_connect (cfg);
2571 idp = GNUNET_RECLAIM_connect (cfg);
2572
2573 state = ID_REST_STATE_INIT;
2472 GNUNET_asprintf (&allow_methods, 2574 GNUNET_asprintf (&allow_methods,
2473 "%s, %s, %s, %s, %s", 2575 "%s, %s, %s, %s, %s",
2474 MHD_HTTP_METHOD_GET, 2576 MHD_HTTP_METHOD_GET,
@@ -2494,6 +2596,7 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
2494{ 2596{
2495 struct GNUNET_REST_Plugin *api = cls; 2597 struct GNUNET_REST_Plugin *api = cls;
2496 struct Plugin *plugin = api->cls; 2598 struct Plugin *plugin = api->cls;
2599 struct EgoEntry *ego_entry;
2497 2600
2498 plugin->cfg = NULL; 2601 plugin->cfg = NULL;
2499 2602
@@ -2508,15 +2611,23 @@ libgnunet_plugin_rest_openid_connect_done (void *cls)
2508 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); 2611 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it);
2509 GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map); 2612 GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map);
2510 2613
2511 hashmap_it =
2512 GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_access_token_map);
2513 while (GNUNET_YES ==
2514 GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL,
2515 value))
2516 GNUNET_free (value);
2517 GNUNET_CONTAINER_multihashmap_destroy (OIDC_access_token_map);
2518 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); 2614 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it);
2519 GNUNET_free (allow_methods); 2615 GNUNET_free (allow_methods);
2616 if (NULL != gns_handle)
2617 GNUNET_GNS_disconnect (gns_handle);
2618 if (NULL != identity_handle)
2619 GNUNET_IDENTITY_disconnect (identity_handle);
2620 if (NULL != idp)
2621 GNUNET_RECLAIM_disconnect (idp);
2622 while (NULL != (ego_entry = ego_head))
2623 {
2624 GNUNET_CONTAINER_DLL_remove (ego_head,
2625 ego_tail,
2626 ego_entry);
2627 GNUNET_free (ego_entry->identifier);
2628 GNUNET_free (ego_entry->keystring);
2629 GNUNET_free (ego_entry);
2630 }
2520 GNUNET_free (api); 2631 GNUNET_free (api);
2521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2632 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2522 "OpenID Connect REST plugin is finished\n"); 2633 "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..c2d14825e 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -88,6 +88,31 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
88static char *allow_methods; 88static char *allow_methods;
89 89
90/** 90/**
91 * Ego list
92 */
93static struct EgoEntry *ego_head;
94
95/**
96 * Ego list
97 */
98static struct EgoEntry *ego_tail;
99
100/**
101 * The processing state
102 */
103static int state;
104
105/**
106 * Handle to Identity service.
107 */
108static struct GNUNET_IDENTITY_Handle *identity_handle;
109
110/**
111 * Identity Provider
112 */
113static struct GNUNET_RECLAIM_Handle *idp;
114
115/**
91 * @brief struct returned by the initialization function of the plugin 116 * @brief struct returned by the initialization function of the plugin
92 */ 117 */
93struct Plugin 118struct Plugin
@@ -129,15 +154,6 @@ struct EgoEntry
129 154
130struct RequestHandle 155struct RequestHandle
131{ 156{
132 /**
133 * Ego list
134 */
135 struct EgoEntry *ego_head;
136
137 /**
138 * Ego list
139 */
140 struct EgoEntry *ego_tail;
141 157
142 /** 158 /**
143 * Selected ego 159 * Selected ego
@@ -150,16 +166,6 @@ struct RequestHandle
150 struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; 166 struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
151 167
152 /** 168 /**
153 * The processing state
154 */
155 int state;
156
157 /**
158 * Handle to Identity service.
159 */
160 struct GNUNET_IDENTITY_Handle *identity_handle;
161
162 /**
163 * Rest connection 169 * Rest connection
164 */ 170 */
165 struct GNUNET_REST_RequestHandle *rest_handle; 171 struct GNUNET_REST_RequestHandle *rest_handle;
@@ -175,11 +181,6 @@ struct RequestHandle
175 struct GNUNET_IDENTITY_Operation *op; 181 struct GNUNET_IDENTITY_Operation *op;
176 182
177 /** 183 /**
178 * Identity Provider
179 */
180 struct GNUNET_RECLAIM_Handle *idp;
181
182 /**
183 * Idp Operation 184 * Idp Operation
184 */ 185 */
185 struct GNUNET_RECLAIM_Operation *idp_op; 186 struct GNUNET_RECLAIM_Operation *idp_op;
@@ -194,7 +195,6 @@ struct RequestHandle
194 */ 195 */
195 struct GNUNET_RECLAIM_AttestationIterator *attest_it; 196 struct GNUNET_RECLAIM_AttestationIterator *attest_it;
196 197
197
198 /** 198 /**
199 * Ticket iterator 199 * Ticket iterator
200 */ 200 */
@@ -251,51 +251,31 @@ struct RequestHandle
251 * @param handle Handle to clean up 251 * @param handle Handle to clean up
252 */ 252 */
253static void 253static void
254cleanup_handle (struct RequestHandle *handle) 254cleanup_handle (void *cls)
255{ 255{
256 struct EgoEntry *ego_entry; 256 struct RequestHandle *handle = cls;
257 struct EgoEntry *ego_tmp;
258 257
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
260 if (NULL != handle->resp_object) 259 if (NULL != handle->resp_object)
261 json_decref (handle->resp_object); 260 json_decref (handle->resp_object);
262 if (NULL != handle->timeout_task) 261 if (NULL != handle->timeout_task)
263 GNUNET_SCHEDULER_cancel (handle->timeout_task); 262 GNUNET_SCHEDULER_cancel (handle->timeout_task);
264 if (NULL != handle->identity_handle)
265 GNUNET_IDENTITY_disconnect (handle->identity_handle);
266 if (NULL != handle->attr_it) 263 if (NULL != handle->attr_it)
267 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); 264 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
268 if (NULL != handle->attest_it) 265 if (NULL != handle->attest_it)
269 GNUNET_RECLAIM_get_attestations_stop (handle->attest_it); 266 GNUNET_RECLAIM_get_attestations_stop (handle->attest_it);
270 if (NULL != handle->ticket_it) 267 if (NULL != handle->ticket_it)
271 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); 268 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
272 if (NULL != handle->idp)
273 GNUNET_RECLAIM_disconnect (handle->idp);
274 if (NULL != handle->url) 269 if (NULL != handle->url)
275 GNUNET_free (handle->url); 270 GNUNET_free (handle->url);
276 if (NULL != handle->emsg) 271 if (NULL != handle->emsg)
277 GNUNET_free (handle->emsg); 272 GNUNET_free (handle->emsg);
278 if (NULL != handle->attr_list) 273 if (NULL != handle->attr_list)
279 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list); 274 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_list);
280 for (ego_entry = handle->ego_head; NULL != ego_entry;)
281 {
282 ego_tmp = ego_entry;
283 ego_entry = ego_entry->next;
284 GNUNET_free (ego_tmp->identifier);
285 GNUNET_free (ego_tmp->keystring);
286 GNUNET_free (ego_tmp);
287 }
288 GNUNET_free (handle); 275 GNUNET_free (handle);
289} 276}
290 277
291 278
292static void
293cleanup_handle_delayed (void *cls)
294{
295 cleanup_handle (cls);
296}
297
298
299/** 279/**
300 * Task run on error, sends error message. Cleans up everything. 280 * Task run on error, sends error message. Cleans up everything.
301 * 281 *
@@ -316,7 +296,7 @@ do_error (void *cls)
316 resp = GNUNET_REST_create_response (json_error); 296 resp = GNUNET_REST_create_response (json_error);
317 MHD_add_response_header (resp, "Content-Type", "application/json"); 297 MHD_add_response_header (resp, "Content-Type", "application/json");
318 handle->proc (handle->proc_cls, resp, handle->response_code); 298 handle->proc (handle->proc_cls, resp, handle->response_code);
319 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 299 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
320 GNUNET_free (json_error); 300 GNUNET_free (json_error);
321} 301}
322 302
@@ -339,9 +319,7 @@ do_timeout (void *cls)
339static void 319static void
340collect_error_cb (void *cls) 320collect_error_cb (void *cls)
341{ 321{
342 struct RequestHandle *handle = cls; 322 do_error (cls);
343
344 do_error (handle);
345} 323}
346 324
347 325
@@ -353,13 +331,14 @@ finished_cont (void *cls, int32_t success, const char *emsg)
353 331
354 resp = GNUNET_REST_create_response (emsg); 332 resp = GNUNET_REST_create_response (emsg);
355 MHD_add_response_header (resp, "Content-Type", "application/json"); 333 MHD_add_response_header (resp, "Content-Type", "application/json");
334 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
356 if (GNUNET_OK != success) 335 if (GNUNET_OK != success)
357 { 336 {
358 GNUNET_SCHEDULER_add_now (&do_error, handle); 337 GNUNET_SCHEDULER_add_now (&do_error, handle);
359 return; 338 return;
360 } 339 }
361 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 340 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
362 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 341 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
363} 342}
364 343
365 344
@@ -370,13 +349,14 @@ delete_finished_cb (void *cls, int32_t success, const char *emsg)
370 struct MHD_Response *resp; 349 struct MHD_Response *resp;
371 350
372 resp = GNUNET_REST_create_response (emsg); 351 resp = GNUNET_REST_create_response (emsg);
352 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
373 if (GNUNET_OK != success) 353 if (GNUNET_OK != success)
374 { 354 {
375 GNUNET_SCHEDULER_add_now (&do_error, handle); 355 GNUNET_SCHEDULER_add_now (&do_error, handle);
376 return; 356 return;
377 } 357 }
378 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 358 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
379 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 359 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
380} 360}
381 361
382 362
@@ -395,6 +375,7 @@ return_response (void *cls)
395 result_str = json_dumps (handle->resp_object, 0); 375 result_str = json_dumps (handle->resp_object, 0);
396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
397 resp = GNUNET_REST_create_response (result_str); 377 resp = GNUNET_REST_create_response (result_str);
378 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
398 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 379 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
399 GNUNET_free (result_str); 380 GNUNET_free (result_str);
400 cleanup_handle (handle); 381 cleanup_handle (handle);
@@ -485,7 +466,7 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
485 identity = handle->url + strlen ( 466 identity = handle->url + strlen (
486 GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; 467 GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1;
487 468
488 for (ego_entry = handle->ego_head; NULL != ego_entry; 469 for (ego_entry = ego_head; NULL != ego_entry;
489 ego_entry = ego_entry->next) 470 ego_entry = ego_entry->next)
490 if (0 == strcmp (identity, ego_entry->identifier)) 471 if (0 == strcmp (identity, ego_entry->identifier))
491 break; 472 break;
@@ -523,9 +504,8 @@ add_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
523 */ 504 */
524 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) 505 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id))
525 GNUNET_RECLAIM_id_generate (&attribute->id); 506 GNUNET_RECLAIM_id_generate (&attribute->id);
526 handle->idp = GNUNET_RECLAIM_connect (cfg);
527 exp = GNUNET_TIME_UNIT_HOURS; 507 exp = GNUNET_TIME_UNIT_HOURS;
528 handle->idp_op = GNUNET_RECLAIM_attestation_store (handle->idp, 508 handle->idp_op = GNUNET_RECLAIM_attestation_store (idp,
529 identity_priv, 509 identity_priv,
530 attribute, 510 attribute,
531 &exp, 511 &exp,
@@ -644,7 +624,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
644 identity = handle->url + strlen ( 624 identity = handle->url + strlen (
645 GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1; 625 GNUNET_REST_API_NS_RECLAIM_ATTESTATION) + 1;
646 626
647 for (ego_entry = handle->ego_head; NULL != ego_entry; 627 for (ego_entry = ego_head; NULL != ego_entry;
648 ego_entry = ego_entry->next) 628 ego_entry = ego_entry->next)
649 if (0 == strcmp (identity, ego_entry->identifier)) 629 if (0 == strcmp (identity, ego_entry->identifier))
650 break; 630 break;
@@ -659,8 +639,7 @@ list_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
659 return; 639 return;
660 } 640 }
661 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 641 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
662 handle->idp = GNUNET_RECLAIM_connect (cfg); 642 handle->attest_it = GNUNET_RECLAIM_get_attestations_start (idp,
663 handle->attest_it = GNUNET_RECLAIM_get_attestations_start (handle->idp,
664 priv_key, 643 priv_key,
665 &collect_error_cb, 644 &collect_error_cb,
666 handle, 645 handle,
@@ -713,7 +692,7 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
713 return; 692 return;
714 } 693 }
715 694
716 for (ego_entry = handle->ego_head; NULL != ego_entry; 695 for (ego_entry = ego_head; NULL != ego_entry;
717 ego_entry = ego_entry->next) 696 ego_entry = ego_entry->next)
718 if (0 == strcmp (identity, ego_entry->identifier)) 697 if (0 == strcmp (identity, ego_entry->identifier))
719 break; 698 break;
@@ -727,11 +706,10 @@ delete_attestation_cont (struct GNUNET_REST_RequestHandle *con_handle,
727 return; 706 return;
728 } 707 }
729 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 708 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
730 handle->idp = GNUNET_RECLAIM_connect (cfg);
731 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation)); 709 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attestation));
732 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); 710 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id));
733 attr.name = ""; 711 attr.name = "";
734 handle->idp_op = GNUNET_RECLAIM_attestation_delete (handle->idp, 712 handle->idp_op = GNUNET_RECLAIM_attestation_delete (idp,
735 priv_key, 713 priv_key,
736 &attr, 714 &attr,
737 &delete_finished_cb, 715 &delete_finished_cb,
@@ -768,7 +746,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
768 } 746 }
769 identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; 747 identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
770 748
771 for (ego_entry = handle->ego_head; NULL != ego_entry; 749 for (ego_entry = ego_head; NULL != ego_entry;
772 ego_entry = ego_entry->next) 750 ego_entry = ego_entry->next)
773 if (0 == strcmp (identity, ego_entry->identifier)) 751 if (0 == strcmp (identity, ego_entry->identifier))
774 break; 752 break;
@@ -782,9 +760,8 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
782 return; 760 return;
783 } 761 }
784 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 762 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
785 handle->idp = GNUNET_RECLAIM_connect (cfg);
786 handle->ticket_it = 763 handle->ticket_it =
787 GNUNET_RECLAIM_ticket_iteration_start (handle->idp, 764 GNUNET_RECLAIM_ticket_iteration_start (idp,
788 priv_key, 765 priv_key,
789 &collect_error_cb, 766 &collect_error_cb,
790 handle, 767 handle,
@@ -823,7 +800,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
823 } 800 }
824 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; 801 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
825 802
826 for (ego_entry = handle->ego_head; NULL != ego_entry; 803 for (ego_entry = ego_head; NULL != ego_entry;
827 ego_entry = ego_entry->next) 804 ego_entry = ego_entry->next)
828 if (0 == strcmp (identity, ego_entry->identifier)) 805 if (0 == strcmp (identity, ego_entry->identifier))
829 break; 806 break;
@@ -862,9 +839,8 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
862 */ 839 */
863 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id)) 840 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&attribute->id))
864 GNUNET_RECLAIM_id_generate (&attribute->id); 841 GNUNET_RECLAIM_id_generate (&attribute->id);
865 handle->idp = GNUNET_RECLAIM_connect (cfg);
866 exp = GNUNET_TIME_UNIT_HOURS; 842 exp = GNUNET_TIME_UNIT_HOURS;
867 handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, 843 handle->idp_op = GNUNET_RECLAIM_attribute_store (idp,
868 identity_priv, 844 identity_priv,
869 attribute, 845 attribute,
870 &exp, 846 &exp,
@@ -1012,7 +988,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
1012 } 988 }
1013 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; 989 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
1014 990
1015 for (ego_entry = handle->ego_head; NULL != ego_entry; 991 for (ego_entry = ego_head; NULL != ego_entry;
1016 ego_entry = ego_entry->next) 992 ego_entry = ego_entry->next)
1017 if (0 == strcmp (identity, ego_entry->identifier)) 993 if (0 == strcmp (identity, ego_entry->identifier))
1018 break; 994 break;
@@ -1027,8 +1003,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
1027 return; 1003 return;
1028 } 1004 }
1029 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1005 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1030 handle->idp = GNUNET_RECLAIM_connect (cfg); 1006 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (idp,
1031 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
1032 priv_key, 1007 priv_key,
1033 &collect_error_cb, 1008 &collect_error_cb,
1034 handle, 1009 handle,
@@ -1078,7 +1053,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
1078 return; 1053 return;
1079 } 1054 }
1080 1055
1081 for (ego_entry = handle->ego_head; NULL != ego_entry; 1056 for (ego_entry = ego_head; NULL != ego_entry;
1082 ego_entry = ego_entry->next) 1057 ego_entry = ego_entry->next)
1083 if (0 == strcmp (identity, ego_entry->identifier)) 1058 if (0 == strcmp (identity, ego_entry->identifier))
1084 break; 1059 break;
@@ -1092,11 +1067,10 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
1092 return; 1067 return;
1093 } 1068 }
1094 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1069 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1095 handle->idp = GNUNET_RECLAIM_connect (cfg);
1096 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute)); 1070 memset (&attr, 0, sizeof(struct GNUNET_RECLAIM_Attribute));
1097 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id)); 1071 GNUNET_STRINGS_string_to_data (id, strlen (id), &attr.id, sizeof(attr.id));
1098 attr.name = ""; 1072 attr.name = "";
1099 handle->idp_op = GNUNET_RECLAIM_attribute_delete (handle->idp, 1073 handle->idp_op = GNUNET_RECLAIM_attribute_delete (idp,
1100 priv_key, 1074 priv_key,
1101 &attr, 1075 &attr,
1102 &delete_finished_cb, 1076 &delete_finished_cb,
@@ -1152,7 +1126,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
1152 return; 1126 return;
1153 } 1127 }
1154 1128
1155 for (ego_entry = handle->ego_head; NULL != ego_entry; 1129 for (ego_entry = ego_head; NULL != ego_entry;
1156 ego_entry = ego_entry->next) 1130 ego_entry = ego_entry->next)
1157 { 1131 {
1158 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); 1132 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
@@ -1169,8 +1143,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
1169 } 1143 }
1170 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1144 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1171 1145
1172 handle->idp = GNUNET_RECLAIM_connect (cfg); 1146 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (idp,
1173 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
1174 identity_priv, 1147 identity_priv,
1175 ticket, 1148 ticket,
1176 &finished_cont, 1149 &finished_cont,
@@ -1256,7 +1229,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
1256 json_decref (data_json); 1229 json_decref (data_json);
1257 return; 1230 return;
1258 } 1231 }
1259 for (ego_entry = handle->ego_head; NULL != ego_entry; 1232 for (ego_entry = ego_head; NULL != ego_entry;
1260 ego_entry = ego_entry->next) 1233 ego_entry = ego_entry->next)
1261 { 1234 {
1262 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); 1235 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk);
@@ -1273,8 +1246,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
1273 } 1246 }
1274 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1247 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1275 handle->resp_object = json_object (); 1248 handle->resp_object = json_object ();
1276 handle->idp = GNUNET_RECLAIM_connect (cfg); 1249 handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp,
1277 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
1278 identity_priv, 1250 identity_priv,
1279 ticket, 1251 ticket,
1280 &consume_cont, 1252 &consume_cont,
@@ -1308,55 +1280,6 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1308 1280
1309 1281
1310/** 1282/**
1311 * Handle rest request
1312 *
1313 * @param handle the request handle
1314 */
1315static void
1316init_cont (struct RequestHandle *handle)
1317{
1318 struct GNUNET_REST_RequestHandlerError err;
1319 static const struct GNUNET_REST_RequestHandler handlers[] =
1320 { { MHD_HTTP_METHOD_GET,
1321 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
1322 &list_attribute_cont },
1323 { MHD_HTTP_METHOD_POST,
1324 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
1325 &add_attribute_cont },
1326 { MHD_HTTP_METHOD_DELETE,
1327 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES,
1328 &delete_attribute_cont },
1329 { MHD_HTTP_METHOD_GET,
1330 GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
1331 &list_attestation_cont },
1332 { MHD_HTTP_METHOD_POST,
1333 GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
1334 &add_attestation_cont },
1335 { MHD_HTTP_METHOD_DELETE,
1336 GNUNET_REST_API_NS_RECLAIM_ATTESTATION,
1337 &delete_attestation_cont },
1338 { MHD_HTTP_METHOD_GET,
1339 GNUNET_REST_API_NS_IDENTITY_TICKETS,
1340 &list_tickets_cont },
1341 { MHD_HTTP_METHOD_POST,
1342 GNUNET_REST_API_NS_IDENTITY_REVOKE,
1343 &revoke_ticket_cont },
1344 { MHD_HTTP_METHOD_POST,
1345 GNUNET_REST_API_NS_IDENTITY_CONSUME,
1346 &consume_ticket_cont },
1347 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont },
1348 GNUNET_REST_HANDLER_END };
1349
1350 if (GNUNET_NO ==
1351 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1352 {
1353 handle->response_code = err.error_code;
1354 GNUNET_SCHEDULER_add_now (&do_error, handle);
1355 }
1356}
1357
1358
1359/**
1360 * If listing is enabled, prints information about the egos. 1283 * If listing is enabled, prints information about the egos.
1361 * 1284 *
1362 * This function is initially called for all egos and then again 1285 * This function is initially called for all egos and then again
@@ -1395,52 +1318,126 @@ list_ego (void *cls,
1395 void **ctx, 1318 void **ctx,
1396 const char *identifier) 1319 const char *identifier)
1397{ 1320{
1398 struct RequestHandle *handle = cls;
1399 struct EgoEntry *ego_entry; 1321 struct EgoEntry *ego_entry;
1400 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 1322 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1401 1323
1402 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 1324 if ((NULL == ego) && (ID_REST_STATE_INIT == state))
1403 { 1325 {
1404 handle->state = ID_REST_STATE_POST_INIT; 1326 state = ID_REST_STATE_POST_INIT;
1405 init_cont (handle);
1406 return; 1327 return;
1407 } 1328 }
1408 if (ID_REST_STATE_INIT == handle->state) 1329 if (ID_REST_STATE_INIT == state)
1409 { 1330 {
1410 ego_entry = GNUNET_new (struct EgoEntry); 1331 ego_entry = GNUNET_new (struct EgoEntry);
1411 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 1332 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1412 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 1333 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1413 ego_entry->ego = ego; 1334 ego_entry->ego = ego;
1414 ego_entry->identifier = GNUNET_strdup (identifier); 1335 ego_entry->identifier = GNUNET_strdup (identifier);
1415 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 1336 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1416 handle->ego_tail, 1337 ego_tail,
1417 ego_entry); 1338 ego_entry);
1418 } 1339 }
1340 /* Ego renamed or added */
1341 if (identifier != NULL)
1342 {
1343 for (ego_entry = ego_head; NULL != ego_entry;
1344 ego_entry = ego_entry->next)
1345 {
1346 if (ego_entry->ego == ego)
1347 {
1348 /* Rename */
1349 GNUNET_free (ego_entry->identifier);
1350 ego_entry->identifier = GNUNET_strdup (identifier);
1351 break;
1352 }
1353 }
1354 if (NULL == ego_entry)
1355 {
1356 /* Add */
1357 ego_entry = GNUNET_new (struct EgoEntry);
1358 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1359 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1360 ego_entry->ego = ego;
1361 ego_entry->identifier = GNUNET_strdup (identifier);
1362 GNUNET_CONTAINER_DLL_insert_tail (ego_head,
1363 ego_tail,
1364 ego_entry);
1365 }
1366 }
1367 else
1368 {
1369 /* Delete */
1370 for (ego_entry = ego_head; NULL != ego_entry;
1371 ego_entry = ego_entry->next)
1372 {
1373 if (ego_entry->ego == ego)
1374 break;
1375 }
1376 if (NULL == ego_entry)
1377 return; /* Not found */
1378
1379 GNUNET_CONTAINER_DLL_remove (ego_head,
1380 ego_tail,
1381 ego_entry);
1382 GNUNET_free (ego_entry->identifier);
1383 GNUNET_free (ego_entry->keystring);
1384 GNUNET_free (ego_entry);
1385 return;
1386 }
1387
1419} 1388}
1420 1389
1421 1390
1422static void 1391static enum GNUNET_GenericReturnValue
1423rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 1392rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1424 GNUNET_REST_ResultProcessor proc, 1393 GNUNET_REST_ResultProcessor proc,
1425 void *proc_cls) 1394 void *proc_cls)
1426{ 1395{
1427 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 1396 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1397 struct GNUNET_REST_RequestHandlerError err;
1398 static const struct GNUNET_REST_RequestHandler handlers[] =
1399 { { MHD_HTTP_METHOD_GET,
1400 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont },
1401 { MHD_HTTP_METHOD_POST,
1402 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont },
1403 { MHD_HTTP_METHOD_DELETE,
1404 GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &delete_attribute_cont },
1405 { MHD_HTTP_METHOD_GET,
1406 GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &list_attestation_cont },
1407 { MHD_HTTP_METHOD_POST,
1408 GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &add_attestation_cont },
1409 { MHD_HTTP_METHOD_DELETE,
1410 GNUNET_REST_API_NS_RECLAIM_ATTESTATION, &delete_attestation_cont },
1411 { MHD_HTTP_METHOD_GET,
1412 GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont },
1413 { MHD_HTTP_METHOD_POST,
1414 GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont },
1415 { MHD_HTTP_METHOD_POST,
1416 GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont },
1417 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, &options_cont },
1418 GNUNET_REST_HANDLER_END
1419 };
1428 1420
1429 handle->response_code = 0; 1421 handle->response_code = 0;
1430 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1422 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1431 handle->proc_cls = proc_cls; 1423 handle->proc_cls = proc_cls;
1432 handle->proc = proc; 1424 handle->proc = proc;
1433 handle->state = ID_REST_STATE_INIT; 1425 state = ID_REST_STATE_INIT;
1434 handle->rest_handle = rest_handle; 1426 handle->rest_handle = rest_handle;
1435 1427
1436 handle->url = GNUNET_strdup (rest_handle->url); 1428 handle->url = GNUNET_strdup (rest_handle->url);
1437 if (handle->url[strlen (handle->url) - 1] == '/') 1429 if (handle->url[strlen (handle->url) - 1] == '/')
1438 handle->url[strlen (handle->url) - 1] = '\0'; 1430 handle->url[strlen (handle->url) - 1] = '\0';
1439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 1431 if (GNUNET_NO ==
1440 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); 1432 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1433 {
1434 cleanup_handle (handle);
1435 return GNUNET_NO;
1436 }
1437
1441 handle->timeout_task = 1438 handle->timeout_task =
1442 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); 1439 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
1443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 1440 return GNUNET_YES;
1444} 1441}
1445 1442
1446 1443
@@ -1472,7 +1469,8 @@ libgnunet_plugin_rest_reclaim_init (void *cls)
1472 MHD_HTTP_METHOD_PUT, 1469 MHD_HTTP_METHOD_PUT,
1473 MHD_HTTP_METHOD_DELETE, 1470 MHD_HTTP_METHOD_DELETE,
1474 MHD_HTTP_METHOD_OPTIONS); 1471 MHD_HTTP_METHOD_OPTIONS);
1475 1472 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
1473 idp = GNUNET_RECLAIM_connect (cfg);
1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1477 _ ("Identity Provider REST API initialized\n")); 1475 _ ("Identity Provider REST API initialized\n"));
1478 return api; 1476 return api;
@@ -1490,8 +1488,22 @@ libgnunet_plugin_rest_reclaim_done (void *cls)
1490{ 1488{
1491 struct GNUNET_REST_Plugin *api = cls; 1489 struct GNUNET_REST_Plugin *api = cls;
1492 struct Plugin *plugin = api->cls; 1490 struct Plugin *plugin = api->cls;
1491 struct EgoEntry *ego_entry;
1492 struct EgoEntry *ego_tmp;
1493 1493
1494 plugin->cfg = NULL; 1494 plugin->cfg = NULL;
1495 if (NULL != idp)
1496 GNUNET_RECLAIM_disconnect (idp);
1497 if (NULL != identity_handle)
1498 GNUNET_IDENTITY_disconnect (identity_handle);
1499 for (ego_entry = ego_head; NULL != ego_entry;)
1500 {
1501 ego_tmp = ego_entry;
1502 ego_entry = ego_entry->next;
1503 GNUNET_free (ego_tmp->identifier);
1504 GNUNET_free (ego_tmp->keystring);
1505 GNUNET_free (ego_tmp);
1506 }
1495 1507
1496 GNUNET_free (allow_methods); 1508 GNUNET_free (allow_methods);
1497 GNUNET_free (api); 1509 GNUNET_free (api);
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 (
1572 ctm->ticket = *ticket; 1572 ctm->ticket = *ticket;
1573 if (NULL != h->mq) 1573 if (NULL != h->mq)
1574 GNUNET_MQ_send_copy (h->mq, op->env); 1574 GNUNET_MQ_send_copy (h->mq, op->env);
1575 else
1576 reconnect(h);
1575 return op; 1577 return op;
1576} 1578}
1577 1579
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index 875509536..436b5b205 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -115,11 +115,6 @@ static struct MHD_Response *failure_response;
115static const struct GNUNET_CONFIGURATION_Handle *cfg; 115static const struct GNUNET_CONFIGURATION_Handle *cfg;
116 116
117/** 117/**
118 * Map of loaded plugins.
119 */
120static struct GNUNET_CONTAINER_MultiHashMap *plugin_map;
121
122/**
123 * Echo request Origin in CORS 118 * Echo request Origin in CORS
124 */ 119 */
125static int echo_origin; 120static int echo_origin;
@@ -140,6 +135,38 @@ static char *allow_headers;
140static char *allow_credentials; 135static char *allow_credentials;
141 136
142/** 137/**
138 * Plugin list head
139 */
140static struct PluginListEntry *plugins_head;
141
142/**
143 * Plugin list tail
144 */
145static struct PluginListEntry *plugins_tail;
146
147/**
148 * A plugin list entry
149 */
150struct PluginListEntry
151{
152 /* DLL */
153 struct PluginListEntry *next;
154
155 /* DLL */
156 struct PluginListEntry *prev;
157
158 /**
159 * libname (to cleanup)
160 */
161 char *libname;
162
163 /**
164 * The plugin
165 */
166 struct GNUNET_REST_Plugin *plugin;
167};
168
169/**
143 * MHD Connection handle 170 * MHD Connection handle
144 */ 171 */
145struct MhdConnectionHandle 172struct MhdConnectionHandle
@@ -148,8 +175,6 @@ struct MhdConnectionHandle
148 175
149 struct MHD_Response *response; 176 struct MHD_Response *response;
150 177
151 struct GNUNET_REST_Plugin *plugin;
152
153 struct GNUNET_REST_RequestHandle *data_handle; 178 struct GNUNET_REST_RequestHandle *data_handle;
154 179
155 struct MHD_PostProcessor *pp; 180 struct MHD_PostProcessor *pp;
@@ -159,6 +184,42 @@ struct MhdConnectionHandle
159 int state; 184 int state;
160}; 185};
161 186
187/**
188 * Accepted requests
189 */
190struct AcceptedRequest
191{
192 /**
193 * DLL
194 */
195 struct AcceptedRequest *next;
196
197 /**
198 * DLL
199 */
200 struct AcceptedRequest *prev;
201
202 /**
203 * Socket
204 */
205 struct GNUNET_NETWORK_Handle *sock;
206
207 /**
208 * Connection
209 */
210 struct MhdConnectionHandle *con_handle;
211};
212
213/**
214 * AcceptedRequest list head
215 */
216static struct AcceptedRequest *req_list_head;
217
218/**
219 * AcceptedRequest list tail
220 */
221static struct AcceptedRequest *req_list_tail;
222
162/* ************************* Global helpers ********************* */ 223/* ************************* Global helpers ********************* */
163 224
164 225
@@ -213,7 +274,6 @@ cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value)
213 return GNUNET_YES; 274 return GNUNET_YES;
214} 275}
215 276
216
217static void 277static void
218cleanup_handle (struct MhdConnectionHandle *handle) 278cleanup_handle (struct MhdConnectionHandle *handle)
219{ 279{
@@ -243,6 +303,19 @@ cleanup_handle (struct MhdConnectionHandle *handle)
243 GNUNET_free (handle); 303 GNUNET_free (handle);
244} 304}
245 305
306static void
307cleanup_ar (struct AcceptedRequest *ar)
308{
309 if (NULL != ar->con_handle)
310 {
311 cleanup_handle (ar->con_handle);
312 }
313 GNUNET_NETWORK_socket_free_memory_only_ (ar->sock);
314 GNUNET_CONTAINER_DLL_remove (req_list_head,
315 req_list_tail,
316 ar);
317 GNUNET_free (ar);
318}
246 319
247static int 320static int
248header_iterator (void *cls, 321header_iterator (void *cls,
@@ -321,19 +394,24 @@ post_data_iter (void *cls,
321 return MHD_YES; 394 return MHD_YES;
322 395
323 GNUNET_CRYPTO_hash (key, strlen (key), &hkey); 396 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
324 GNUNET_asprintf (&val, "%s", data); 397 val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map,
325 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( 398 &hkey);
326 handle->url_param_map, 399 if (NULL == val)
327 &hkey,
328 val,
329 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
330 { 400 {
331 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 401 val = GNUNET_malloc (65536);
332 "Could not load add url param '%s'=%s\n", 402 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (
333 key, 403 handle->url_param_map,
334 data); 404 &hkey,
335 GNUNET_free (val); 405 val,
406 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
407 {
408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
409 "Could not add url param '%s'\n",
410 key);
411 GNUNET_free (val);
412 }
336 } 413 }
414 memcpy (val + off, data, size);
337 return MHD_YES; 415 return MHD_YES;
338} 416}
339 417
@@ -373,41 +451,30 @@ create_response (void *cls,
373 size_t *upload_data_size, 451 size_t *upload_data_size,
374 void **con_cls) 452 void **con_cls)
375{ 453{
376 char *plugin_name;
377 char *origin; 454 char *origin;
455 struct AcceptedRequest *ar;
378 struct GNUNET_HashCode key; 456 struct GNUNET_HashCode key;
379 struct MhdConnectionHandle *con_handle; 457 struct MhdConnectionHandle *con_handle;
380 struct GNUNET_REST_RequestHandle *rest_conndata_handle; 458 struct GNUNET_REST_RequestHandle *rest_conndata_handle;
459 struct PluginListEntry *ple;
381 460
382 con_handle = *con_cls; 461 ar = *con_cls;
462 if (NULL == ar)
463 {
464 GNUNET_break (0);
465 return MHD_NO;
466 }
383 467
384 if (NULL == *con_cls) 468 if (NULL == ar->con_handle)
385 { 469 {
386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url); 470 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
387 char tmp_url[strlen (url) + 1];
388 strcpy (tmp_url, url);
389 con_handle = GNUNET_new (struct MhdConnectionHandle); 471 con_handle = GNUNET_new (struct MhdConnectionHandle);
390 con_handle->con = con; 472 con_handle->con = con;
391 con_handle->state = GN_REST_STATE_INIT; 473 con_handle->state = GN_REST_STATE_INIT;
392 *con_cls = con_handle; 474 ar->con_handle = con_handle;
393
394 plugin_name = strtok (tmp_url, "/");
395
396 if (NULL != plugin_name)
397 {
398 GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key);
399
400 con_handle->plugin = GNUNET_CONTAINER_multihashmap_get (plugin_map, &key);
401 }
402 if (NULL == con_handle->plugin)
403 {
404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n");
405 GNUNET_free (con_handle);
406 return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
407 }
408
409 return MHD_YES; 475 return MHD_YES;
410 } 476 }
477 con_handle = ar->con_handle;
411 if (GN_REST_STATE_INIT == con_handle->state) 478 if (GN_REST_STATE_INIT == con_handle->state)
412 { 479 {
413 rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle); 480 rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
@@ -428,6 +495,7 @@ create_response (void *cls,
428 MHD_HEADER_KIND, 495 MHD_HEADER_KIND,
429 (MHD_KeyValueIterator) & header_iterator, 496 (MHD_KeyValueIterator) & header_iterator,
430 rest_conndata_handle); 497 rest_conndata_handle);
498
431 con_handle->pp = MHD_create_post_processor (con, 499 con_handle->pp = MHD_create_post_processor (con,
432 65536, 500 65536,
433 &post_data_iter, 501 &post_data_iter,
@@ -439,9 +507,18 @@ create_response (void *cls,
439 MHD_destroy_post_processor (con_handle->pp); 507 MHD_destroy_post_processor (con_handle->pp);
440 508
441 con_handle->state = GN_REST_STATE_PROCESSING; 509 con_handle->state = GN_REST_STATE_PROCESSING;
442 con_handle->plugin->process_request (rest_conndata_handle, 510 for (ple = plugins_head; NULL != ple; ple = ple->next)
443 &plugin_callback, 511 {
444 con_handle); 512 if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle,
513 &plugin_callback,
514 con_handle))
515 break; /* Request handled */
516 }
517 if (NULL == ple)
518 {
519 /** Request not handled **/
520 MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
521 }
445 *upload_data_size = 0; 522 *upload_data_size = 0;
446 run_mhd_now (); 523 run_mhd_now ();
447 return MHD_YES; 524 return MHD_YES;
@@ -513,7 +590,7 @@ create_response (void *cls,
513 MHD_RESULT ret = MHD_queue_response (con, 590 MHD_RESULT ret = MHD_queue_response (con,
514 con_handle->status, 591 con_handle->status,
515 con_handle->response); 592 con_handle->response);
516 cleanup_handle (con_handle); 593 //cleanup_handle (con_handle);
517 return ret; 594 return ret;
518 } 595 }
519} 596}
@@ -521,27 +598,6 @@ create_response (void *cls,
521 598
522/* ******************** MHD HTTP setup and event loop ******************** */ 599/* ******************** MHD HTTP setup and event loop ******************** */
523 600
524/**
525 * Function called when MHD decides that we are done with a connection.
526 *
527 * @param cls NULL
528 * @param connection connection handle
529 * @param con_cls value as set by the last call to
530 * the MHD_AccessHandlerCallback, should be our handle
531 * @param toe reason for request termination (ignored)
532 */
533static void
534mhd_completed_cb (void *cls,
535 struct MHD_Connection *connection,
536 void **con_cls,
537 enum MHD_RequestTerminationCode toe)
538{
539 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
540 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
541 "MHD encountered error handling request: %d\n",
542 toe);
543}
544
545 601
546/** 602/**
547 * Kill the MHD daemon. 603 * Kill the MHD daemon.
@@ -649,6 +705,135 @@ schedule_httpd ()
649 GNUNET_NETWORK_fdset_destroy (wws); 705 GNUNET_NETWORK_fdset_destroy (wws);
650} 706}
651 707
708/**
709 * Function called when MHD first processes an incoming connection.
710 * Gives us the respective URI information.
711 *
712 * We use this to associate the `struct MHD_Connection` with our
713 * internal `struct AcceptedRequest` data structure (by checking
714 * for matching sockets).
715 *
716 * @param cls the HTTP server handle (a `struct MhdHttpList`)
717 * @param url the URL that is being requested
718 * @param connection MHD connection object for the request
719 * @return the `struct Socks5Request` that this @a connection is for
720 */
721static void *
722mhd_log_callback (void *cls,
723 const char *url,
724 struct MHD_Connection *connection)
725{
726 struct AcceptedRequest *ar;
727 const union MHD_ConnectionInfo *ci;
728
729 ci = MHD_get_connection_info (connection,
730 MHD_CONNECTION_INFO_SOCKET_CONTEXT);
731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
732 if (NULL == ci)
733 {
734 GNUNET_break (0);
735 return NULL;
736 }
737 ar = ci->socket_context;
738 return ar;
739}
740
741
742
743/**
744 * Function called when MHD decides that we are done with a connection.
745 *
746 * @param cls NULL
747 * @param connection connection handle
748 * @param con_cls value as set by the last call to
749 * the MHD_AccessHandlerCallback, should be our handle
750 * @param toe reason for request termination (ignored)
751 */
752static void
753mhd_completed_cb (void *cls,
754 struct MHD_Connection *connection,
755 void **con_cls,
756 enum MHD_RequestTerminationCode toe)
757{
758 struct AcceptedRequest *ar = *con_cls;
759 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
760 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
761 "MHD encountered error handling request: %d\n",
762 toe);
763 if (NULL == ar)
764 return;
765 if (NULL != ar->con_handle)
766 {
767 cleanup_handle (ar->con_handle);
768 ar->con_handle = NULL;
769 }
770 schedule_httpd ();
771 *con_cls = NULL;
772}
773
774/**
775 * Function called when MHD connection is opened or closed.
776 *
777 * @param cls NULL
778 * @param connection connection handle
779 * @param con_cls value as set by the last call to
780 * the MHD_AccessHandlerCallback, should be our `struct Socks5Request *`
781 * @param toe connection notification type
782 */
783static void
784mhd_connection_cb (void *cls,
785 struct MHD_Connection *connection,
786 void **con_cls,
787 enum MHD_ConnectionNotificationCode cnc)
788{
789 struct AcceptedRequest *ar;
790 const union MHD_ConnectionInfo *ci;
791 int sock;
792
793 switch (cnc)
794 {
795 case MHD_CONNECTION_NOTIFY_STARTED:
796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
797 ci = MHD_get_connection_info (connection,
798 MHD_CONNECTION_INFO_CONNECTION_FD);
799 if (NULL == ci)
800 {
801 GNUNET_break (0);
802 return;
803 }
804 sock = ci->connect_fd;
805 for (ar = req_list_head; NULL != ar; ar = ar->next)
806 {
807 if (GNUNET_NETWORK_get_fd (ar->sock) == sock)
808 {
809 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
810 "Context set...\n");
811 *con_cls = ar;
812 break;
813 }
814 }
815 break;
816
817 case MHD_CONNECTION_NOTIFY_CLOSED:
818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
819 "Connection closed... cleaning up\n");
820 ar = *con_cls;
821 if (NULL == ar)
822 {
823 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
824 "Connection stale!\n");
825 return;
826 }
827 cleanup_ar (ar);
828 *con_cls = NULL;
829 break;
830
831 default:
832 GNUNET_break (0);
833 }
834}
835
836
652 837
653/** 838/**
654 * Task run whenever HTTP server operations are pending. 839 * Task run whenever HTTP server operations are pending.
@@ -674,7 +859,7 @@ static void
674do_accept (void *cls) 859do_accept (void *cls)
675{ 860{
676 struct GNUNET_NETWORK_Handle *lsock = cls; 861 struct GNUNET_NETWORK_Handle *lsock = cls;
677 struct GNUNET_NETWORK_Handle *s; 862 struct AcceptedRequest *ar;
678 int fd; 863 int fd;
679 const struct sockaddr *addr; 864 const struct sockaddr *addr;
680 socklen_t len; 865 socklen_t len;
@@ -696,24 +881,30 @@ do_accept (void *cls)
696 } 881 }
697 else 882 else
698 GNUNET_assert (0); 883 GNUNET_assert (0);
699 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); 884 ar = GNUNET_new (struct AcceptedRequest);
700 if (NULL == s) 885 ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
886 if (NULL == ar->sock)
701 { 887 {
888 GNUNET_free (ar);
702 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); 889 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept");
703 return; 890 return;
704 } 891 }
705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 892 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
706 "Got an inbound connection, waiting for data\n"); 893 "Got an inbound connection, waiting for data\n");
707 fd = GNUNET_NETWORK_get_fd (s); 894 fd = GNUNET_NETWORK_get_fd (ar->sock);
708 addr = GNUNET_NETWORK_get_addr (s); 895 addr = GNUNET_NETWORK_get_addr (ar->sock);
709 len = GNUNET_NETWORK_get_addrlen (s); 896 len = GNUNET_NETWORK_get_addrlen (ar->sock);
897 GNUNET_CONTAINER_DLL_insert (req_list_head,
898 req_list_tail,
899 ar);
710 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len)) 900 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
711 { 901 {
902 GNUNET_NETWORK_socket_close (ar->sock);
903 GNUNET_free (ar);
712 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 904 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
713 _ ("Failed to pass client to MHD\n")); 905 _ ("Failed to pass client to MHD\n"));
714 return; 906 return;
715 } 907 }
716 GNUNET_free (s);
717 schedule_httpd (); 908 schedule_httpd ();
718} 909}
719 910
@@ -726,6 +917,18 @@ do_accept (void *cls)
726static void 917static void
727do_shutdown (void *cls) 918do_shutdown (void *cls)
728{ 919{
920 struct PluginListEntry *ple;
921
922 while (NULL != plugins_head)
923 {
924 ple = plugins_head;
925 GNUNET_CONTAINER_DLL_remove (plugins_head,
926 plugins_tail,
927 ple);
928 GNUNET_PLUGIN_unload (ple->libname, NULL);
929 GNUNET_free (ple->libname);
930 GNUNET_free (ple);
931 }
729 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n"); 932 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
730 kill_httpd (); 933 kill_httpd ();
731 GNUNET_free (allow_credentials); 934 GNUNET_free (allow_credentials);
@@ -814,7 +1017,7 @@ static void
814load_plugin (void *cls, const char *libname, void *lib_ret) 1017load_plugin (void *cls, const char *libname, void *lib_ret)
815{ 1018{
816 struct GNUNET_REST_Plugin *plugin = lib_ret; 1019 struct GNUNET_REST_Plugin *plugin = lib_ret;
817 struct GNUNET_HashCode key; 1020 struct PluginListEntry *ple;
818 1021
819 if (NULL == lib_ret) 1022 if (NULL == lib_ret)
820 { 1023 {
@@ -825,18 +1028,12 @@ load_plugin (void *cls, const char *libname, void *lib_ret)
825 } 1028 }
826 GNUNET_assert (1 < strlen (plugin->name)); 1029 GNUNET_assert (1 < strlen (plugin->name));
827 GNUNET_assert ('/' == *plugin->name); 1030 GNUNET_assert ('/' == *plugin->name);
828 GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key); 1031 ple = GNUNET_new (struct PluginListEntry);
829 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put ( 1032 ple->libname = GNUNET_strdup (libname);
830 plugin_map, 1033 ple->plugin = plugin;
831 &key, 1034 GNUNET_CONTAINER_DLL_insert (plugins_head,
832 plugin, 1035 plugins_tail,
833 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 1036 ple);
834 {
835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
836 "Could not load add plugin `%s'\n",
837 libname);
838 return;
839 }
840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname); 1037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname);
841} 1038}
842 1039
@@ -858,8 +1055,8 @@ run (void *cls,
858 char *addr_str; 1055 char *addr_str;
859 1056
860 cfg = c; 1057 cfg = c;
861 plugin_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 1058 plugins_head = NULL;
862 1059 plugins_tail = NULL;
863 /* Get port to bind to */ 1060 /* Get port to bind to */
864 if (GNUNET_OK != 1061 if (GNUNET_OK !=
865 GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port)) 1062 GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
@@ -1004,6 +1201,12 @@ run (void *cls,
1004 NULL, 1201 NULL,
1005 MHD_OPTION_CONNECTION_TIMEOUT, 1202 MHD_OPTION_CONNECTION_TIMEOUT,
1006 (unsigned int) 16, 1203 (unsigned int) 16,
1204 MHD_OPTION_NOTIFY_CONNECTION,
1205 &mhd_connection_cb,
1206 NULL,
1207 MHD_OPTION_URI_LOG_CALLBACK,
1208 mhd_log_callback,
1209 NULL,
1007 MHD_OPTION_NOTIFY_COMPLETED, 1210 MHD_OPTION_NOTIFY_COMPLETED,
1008 &mhd_completed_cb, 1211 &mhd_completed_cb,
1009 NULL, 1212 NULL,
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,
347 * @param proc_cls closure for @a proc 347 * @param proc_cls closure for @a proc
348 * @return #GNUNET_OK if request accepted 348 * @return #GNUNET_OK if request accepted
349 */ 349 */
350static void 350static enum GNUNET_GenericReturnValue
351rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, 351rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
352 GNUNET_REST_ResultProcessor proc, 352 GNUNET_REST_ResultProcessor proc,
353 void *proc_cls) 353 void *proc_cls)
@@ -371,9 +371,10 @@ rest_config_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
371 if (GNUNET_NO == 371 if (GNUNET_NO ==
372 GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle)) 372 GNUNET_REST_handle_request (conndata_handle, handlers, &err, handle))
373 { 373 {
374 handle->response_code = err.error_code; 374 cleanup_handle (handle);
375 GNUNET_SCHEDULER_add_now (&do_error, handle); 375 return GNUNET_NO;
376 } 376 }
377 return GNUNET_YES;
377} 378}
378 379
379 380
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
@@ -82,24 +82,6 @@ cleanup_handle (struct RequestHandle *handle)
82 82
83 83
84/** 84/**
85 * Task run on shutdown. Cleans up everything.
86 *
87 * @param cls unused
88 * @param tc scheduler context
89 */
90static void
91do_error (void *cls)
92{
93 struct RequestHandle *handle = cls;
94 struct MHD_Response *resp;
95
96 resp = GNUNET_REST_create_response (NULL);
97 handle->proc (handle->proc_cls, resp, handle->response_code);
98 cleanup_handle (handle);
99}
100
101
102/**
103 * Handle rest request 85 * Handle rest request
104 * 86 *
105 * @param handle the lookup handle 87 * @param handle the lookup handle
@@ -155,7 +137,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
155 * @param proc_cls closure for @a proc 137 * @param proc_cls closure for @a proc
156 * @return #GNUNET_OK if request accepted 138 * @return #GNUNET_OK if request accepted
157 */ 139 */
158static void 140static enum GNUNET_GenericReturnValue
159rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle, 141rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
160 GNUNET_REST_ResultProcessor proc, 142 GNUNET_REST_ResultProcessor proc,
161 void *proc_cls) 143 void *proc_cls)
@@ -172,14 +154,10 @@ rest_copying_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
172 handle->proc = proc; 154 handle->proc = proc;
173 handle->rest_handle = conndata_handle; 155 handle->rest_handle = conndata_handle;
174 156
175 if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle, 157 return GNUNET_REST_handle_request (conndata_handle,
176 handlers, 158 handlers,
177 &err, 159 &err,
178 handle)) 160 handle);
179 {
180 handle->response_code = err.error_code;
181 GNUNET_SCHEDULER_add_now (&do_error, handle);
182 }
183} 161}
184 162
185 163
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
index 0c85660dd..e194b0159 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -1023,11 +1023,7 @@ peerstore_start (
1023{ 1023{
1024 char *binary; 1024 char *binary;
1025 1025
1026 LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start\n");
1027 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-peerstore"); 1026 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-peerstore");
1028 LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start binary %s\n",
1029 binary);
1030 LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start 2\n");
1031 tc_h->ps_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 1027 tc_h->ps_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
1032 NULL, 1028 NULL,
1033 NULL, 1029 NULL,
@@ -1037,7 +1033,6 @@ peerstore_start (
1037 "-c", 1033 "-c",
1038 tc_h->cfg_filename, 1034 tc_h->cfg_filename,
1039 NULL); 1035 NULL);
1040 LOG (GNUNET_ERROR_TYPE_DEBUG, "peerstore_start 3\n");
1041 if (NULL == tc_h->ps_proc) 1036 if (NULL == tc_h->ps_proc)
1042 { 1037 {
1043 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start Peerstore!"); 1038 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start Peerstore!");
@@ -1059,8 +1054,6 @@ nat_start (
1059 1054
1060 LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start\n"); 1055 LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start\n");
1061 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-nat"); 1056 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-nat");
1062 LOG (GNUNET_ERROR_TYPE_DEBUG, "nat_start binary %s\n",
1063 binary);
1064 tc_h->nat_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR 1057 tc_h->nat_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR
1065 | GNUNET_OS_USE_PIPE_CONTROL, 1058 | GNUNET_OS_USE_PIPE_CONTROL,
1066 NULL, 1059 NULL,
@@ -1158,8 +1151,6 @@ void
1158GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop ( 1151GNUNET_TRANSPORT_TESTING_transport_communicator_service_stop (
1159 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h) 1152 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h)
1160{ 1153{
1161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1162 "transport communicator service stop\n");
1163 shutdown_communicator (tc_h->c_proc); 1154 shutdown_communicator (tc_h->c_proc);
1164 shutdown_service (tc_h->sh); 1155 shutdown_service (tc_h->sh);
1165 shutdown_nat (tc_h->nat_proc); 1156 shutdown_nat (tc_h->nat_proc);
diff --git a/src/util/buffer.c b/src/util/buffer.c
index 2af972413..662e4d0f2 100644
--- a/src/util/buffer.c
+++ b/src/util/buffer.c
@@ -32,7 +32,8 @@
32 * @param capacity the capacity (in bytes) to allocate for @a buf 32 * @param capacity the capacity (in bytes) to allocate for @a buf
33 */ 33 */
34void 34void
35GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity) 35GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf,
36 size_t capacity)
36{ 37{
37 /* Buffer should be zero-initialized */ 38 /* Buffer should be zero-initialized */
38 GNUNET_assert (0 == buf->mem); 39 GNUNET_assert (0 == buf->mem);
@@ -257,25 +258,25 @@ GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
257 * 258 *
258 * @param buf buffer to write to 259 * @param buf buffer to write to
259 * @param data data to read from 260 * @param data data to read from
260 * @param len number of bytes to copy from @a data to @a buf 261 * @param data_len number of bytes to copy from @a data to @a buf
261 */ 262 */
262void 263void
263GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf, 264GNUNET_buffer_write_data_encoded (struct GNUNET_Buffer *buf,
264 const char *data, 265 const void *data,
265 size_t len) 266 size_t data_len)
266{ 267{
267 size_t outlen = len * 8; 268 size_t outlen = data_len * 8;
268 char *p = buf->mem + buf->position;
269 269
270 if (outlen % 5 > 0) 270 if (outlen % 5 > 0)
271 outlen += 5 - outlen % 5; 271 outlen += 5 - outlen % 5;
272 outlen /= 5; 272 outlen /= 5;
273 273 GNUNET_buffer_ensure_remaining (buf,
274 GNUNET_buffer_ensure_remaining (buf, outlen); 274 outlen);
275 GNUNET_assert (NULL != 275 GNUNET_assert (NULL !=
276 GNUNET_STRINGS_data_to_string (data, 276 GNUNET_STRINGS_data_to_string (data,
277 len, 277 data_len,
278 p, 278 (buf->mem
279 + buf->position),
279 outlen)); 280 outlen));
280 buf->position += outlen; 281 buf->position += outlen;
281 GNUNET_assert (buf->position <= buf->capacity); 282 GNUNET_assert (buf->position <= buf->capacity);
diff --git a/src/util/strings.c b/src/util/strings.c
index 41180dd71..9d6f4039e 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -29,6 +29,7 @@
29#include <iconv.h> 29#include <iconv.h>
30#endif 30#endif
31#include "gnunet_crypto_lib.h" 31#include "gnunet_crypto_lib.h"
32#include "gnunet_buffer_lib.h"
32#include "gnunet_strings_lib.h" 33#include "gnunet_strings_lib.h"
33#include <unicase.h> 34#include <unicase.h>
34#include <unistr.h> 35#include <unistr.h>
@@ -2088,4 +2089,161 @@ GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out)
2088} 2089}
2089 2090
2090 2091
2092/**
2093 * url/percent encode (RFC3986).
2094 *
2095 * @param data the data to encode
2096 * @param len the length of the input
2097 * @param output where to write the output (*output should be NULL,
2098 * is allocated)
2099 * @return the size of the output
2100 */
2101size_t
2102GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out)
2103{
2104 const char *rpos = data;
2105 *out = GNUNET_malloc (len + 1); /* output should always fit into input */
2106 char *wpos = *out;
2107 size_t resl = 0;
2108
2109 while ('\0' != *rpos)
2110 {
2111 unsigned int num;
2112 switch (*rpos)
2113 {
2114 case '%':
2115 if (1 != sscanf (rpos + 1, "%2x", &num))
2116 break;
2117 *wpos = (char) ((unsigned char) num);
2118 wpos++;
2119 resl++;
2120 rpos += 3;
2121 break;
2122 /* TODO: add bad sequence handling */
2123 /* intentional fall through! */
2124 default:
2125 *wpos = *rpos;
2126 wpos++;
2127 resl++;
2128 rpos++;
2129 }
2130 }
2131 *wpos = '\0'; /* add 0-terminator */
2132 return resl;
2133}
2134
2135
2136/**
2137 * url/percent encode (RFC3986).
2138 *
2139 * @param data the data to decode
2140 * @param len the length of the input
2141 * @param output where to write the output (*output should be NULL,
2142 * is allocated)
2143 * @return the size of the output
2144 */
2145size_t
2146GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out)
2147{
2148 struct GNUNET_Buffer buf = { 0 };
2149 const uint8_t *i8 = (uint8_t *) data;
2150
2151 while (0 != *i8)
2152 {
2153 if (0 == (0x80 & *i8))
2154 {
2155 /* traditional ASCII */
2156 if (isalnum (*i8) || (*i8 == '-') || (*i8 == '_') || (*i8 == '.') ||
2157 (*i8 == '~') )
2158 GNUNET_buffer_write (&buf, (const char*) i8, 1);
2159 else if (*i8 == ' ')
2160 GNUNET_buffer_write (&buf, "+", 1);
2161 else
2162 GNUNET_buffer_write_fstr (&buf,
2163 "%%%X%X",
2164 *i8 >> 4,
2165 *i8 & 15);
2166 i8++;
2167 continue;
2168 }
2169 if (0x80 + 0x40 == ((0x80 + 0x40 + 0x20) & *i8))
2170 {
2171 /* 2-byte value, percent-encode */
2172 GNUNET_buffer_write_fstr (&buf,
2173 "%%%X%X",
2174 *i8 >> 4,
2175 *i8 & 15);
2176 i8++;
2177 GNUNET_buffer_write_fstr (&buf,
2178 "%%%X%X",
2179 *i8 >> 4,
2180 *i8 & 15);
2181 i8++;
2182 continue;
2183 }
2184 if (0x80 + 0x40 + 0x20 == ((0x80 + 0x40 + 0x20 + 0x10) & *i8))
2185 {
2186 /* 3-byte value, percent-encode */
2187 for (unsigned int i = 0; i<3; i++)
2188 {
2189 GNUNET_buffer_write_fstr (&buf,
2190 "%%%X%X",
2191 *i8 >> 4,
2192 *i8 & 15);
2193 i8++;
2194 }
2195 continue;
2196 }
2197 if (0x80 + 0x40 + 0x20 + 0x10 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08) & *i8))
2198 {
2199 /* 4-byte value, percent-encode */
2200 for (unsigned int i = 0; i<4; i++)
2201 {
2202 GNUNET_buffer_write_fstr (&buf,
2203 "%%%X%X",
2204 *i8 >> 4,
2205 *i8 & 15);
2206 i8++;
2207 }
2208 continue;
2209 }
2210 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 == ((0x80 + 0x40 + 0x20 + 0x10 + 0x08
2211 + 0x04) & *i8))
2212 {
2213 /* 5-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
2214 for (unsigned int i = 0; i<5; i++)
2215 {
2216 GNUNET_buffer_write_fstr (&buf,
2217 "%%%X%X",
2218 *i8 >> 4,
2219 *i8 & 15);
2220 i8++;
2221 }
2222 continue;
2223 }
2224 if (0x80 + 0x40 + 0x20 + 0x10 + 0x08 + 0x04 == ((0x80 + 0x40 + 0x20 + 0x10
2225 + 0x08 + 0x04 + 0x02)
2226 & *i8))
2227 {
2228 /* 6-byte value, percent-encode (outside of UTF-8 modern standard, but so what) */
2229 for (unsigned int i = 0; i<6; i++)
2230 {
2231 GNUNET_buffer_write_fstr (&buf,
2232 "%%%X%X",
2233 *i8 >> 4,
2234 *i8 & 15);
2235 i8++;
2236 }
2237 continue;
2238 }
2239 /* really, really invalid UTF-8: fail */
2240 GNUNET_break (0);
2241 GNUNET_buffer_clear (&buf);
2242 return 0;
2243 }
2244 *out = GNUNET_buffer_reap_str (&buf);
2245 return strlen (*out);
2246}
2247
2248
2091/* end of strings.c */ 2249/* end of strings.c */
diff --git a/src/util/test_strings.c b/src/util/test_strings.c
index 90d06a473..753ec6908 100644
--- a/src/util/test_strings.c
+++ b/src/util/test_strings.c
@@ -39,6 +39,10 @@
39#define WANTB(a, b, l) if (0 != memcmp (a, b, l)) { GNUNET_break (0); return 1; \ 39#define WANTB(a, b, l) if (0 != memcmp (a, b, l)) { GNUNET_break (0); return 1; \
40} else { } 40} else { }
41 41
42#define URLENCODE_TEST_VECTOR_PLAIN "Asbjlaw=ljsdlasjd?人aslkdsa"
43
44#define URLENCODE_TEST_VECTOR_ENCODED "Asbjlaw\%3Dljsdlasjd\%3F\%E4\%BA\%BAaslkdsa"
45
42int 46int
43main (int argc, char *argv[]) 47main (int argc, char *argv[])
44{ 48{
@@ -137,6 +141,16 @@ main (int argc, char *argv[])
137 GNUNET_STRINGS_fancy_time_to_relative ("15 m", &rtx)); 141 GNUNET_STRINGS_fancy_time_to_relative ("15 m", &rtx));
138 GNUNET_assert (rt.rel_value_us == rtx.rel_value_us); 142 GNUNET_assert (rt.rel_value_us == rtx.rel_value_us);
139 143
144 GNUNET_assert (0 != GNUNET_STRINGS_urlencode (URLENCODE_TEST_VECTOR_PLAIN,
145 strlen (URLENCODE_TEST_VECTOR_PLAIN),
146 &b));
147 WANT (URLENCODE_TEST_VECTOR_ENCODED, b);
148 GNUNET_free (b);
149 GNUNET_assert (0 != GNUNET_STRINGS_urldecode (URLENCODE_TEST_VECTOR_ENCODED,
150 strlen (URLENCODE_TEST_VECTOR_ENCODED),
151 &b));
152 WANT (URLENCODE_TEST_VECTOR_PLAIN, b);
153 GNUNET_free (b);
140 return 0; 154 return 0;
141} 155}
142 156