From 8bf864c25bda97c1448b709a76a168834753ff86 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Thu, 1 Oct 2020 21:13:43 +0200 Subject: adding the messenger service and its client-side library Signed-off-by: TheJackiMonster --- src/Makefile.am | 7 +- src/ats-tests/ats-testing-log.c | 4 +- src/cadet/gnunet-service-cadet_channel.c | 10 +- src/cadet/gnunet-service-cadet_core.c | 4 +- src/cadet/gnunet-service-cadet_dht.c | 4 +- src/cadet/gnunet-service-cadet_tunnels.c | 2 +- src/consensus/consensus_api.c | 2 +- src/conversation/Makefile.am | 1 + src/conversation/conversation.h | 10 +- src/conversation/conversation_api.c | 4 +- src/conversation/gnunet-conversation.c | 6 +- src/conversation/gnunet-service-conversation.c | 15 +- src/conversation/test_conversation_api.c | 8 +- src/conversation/test_conversation_api_reject.c | 8 +- src/conversation/test_conversation_api_twocalls.c | 8 +- src/datacache/plugin_datacache_postgres.c | 9 +- src/datastore/datastore_api.c | 8 +- src/datastore/plugin_datastore_postgres.c | 14 +- src/dht/gnunet-service-dht_clients.c | 6 +- src/dht/gnunet-service-dht_datacache.c | 4 +- src/dht/gnunet-service-dht_neighbours.c | 4 +- src/dht/plugin_block_dht.c | 2 +- src/dns/gnunet-dns-monitor.c | 2 +- src/fragmentation/fragmentation.c | 2 +- src/fs/fs_download.c | 2 +- src/fs/gnunet-daemon-fsprofiler.c | 4 +- src/fs/gnunet-publish.c | 18 +- src/gns/Makefile.am | 5 + src/gns/gns.h | 2 +- src/gns/gns_api.c | 4 +- src/gns/gns_tld_api.c | 21 +- src/gns/gnunet-gns-import.c | 9 +- src/gns/gnunet-service-gns.c | 6 +- src/gns/gnunet-service-gns.h | 3 +- src/gns/gnunet-service-gns_interceptor.c | 2 +- src/gns/gnunet-service-gns_resolver.c | 71 +- src/gns/gnunet-service-gns_resolver.h | 2 +- src/gns/plugin_block_gns.c | 15 +- src/gns/plugin_gnsrecord_gns.c | 33 +- src/gns/plugin_rest_gns.c | 3 +- src/gns/test_gns_dht_lookup.sh | 1 + src/gnsrecord/Makefile.am | 21 +- src/gnsrecord/gnsrecord_crypto.c | 315 ++++-- src/gnsrecord/gnsrecord_misc.c | 151 ++- src/gnsrecord/gnunet-gnsrecord-tvg.c | 49 +- src/gnsrecord/json_gnsrecord.c | 391 ++++++++ src/gnsrecord/perf_gnsrecord_crypto.c | 5 +- src/gnsrecord/plugin_gnsrecord_dns.c | 2 +- src/gnsrecord/test_gnsrecord_crypto.c | 11 +- src/identity/gnunet-identity.c | 45 +- src/identity/gnunet-service-identity.c | 77 +- src/identity/identity.h | 81 +- src/identity/identity_api.c | 391 +++++++- src/identity/identity_api_lookup.c | 4 +- src/identity/plugin_rest_identity.c | 23 +- src/identity/test_identity.c | 8 +- src/identity/test_identity_defaults.c | 8 +- src/include/Makefile.am | 1 + src/include/gnunet_buffer_lib.h | 3 +- src/include/gnunet_common.h | 15 +- src/include/gnunet_conversation_service.h | 2 +- src/include/gnunet_crypto_lib.h | 6 +- src/include/gnunet_gns_service.h | 5 +- src/include/gnunet_gnsrecord_json_lib.h | 73 ++ src/include/gnunet_gnsrecord_lib.h | 125 ++- src/include/gnunet_identity_service.h | 422 +++++++- src/include/gnunet_json_lib.h | 27 +- src/include/gnunet_messenger_service.h | 436 ++++++++ src/include/gnunet_namestore_plugin.h | 12 +- src/include/gnunet_namestore_service.h | 15 +- src/include/gnunet_pq_lib.h | 55 +- src/include/gnunet_protocols.h | 43 +- src/include/gnunet_reclaim_service.h | 33 +- src/include/gnunet_revocation_service.h | 34 +- src/include/gnunet_uri_lib.h | 8 +- src/json/Makefile.am | 7 +- src/json/json.c | 14 +- src/json/json_generator.c | 108 -- src/json/json_gnsrecord.c | 279 ------ src/messenger/.gitignore | 4 + src/messenger/Makefile.am | 131 +++ src/messenger/gnunet-messenger.c | 306 ++++++ src/messenger/gnunet-service-messenger.c | 306 ++++++ src/messenger/gnunet-service-messenger.h | 121 +++ src/messenger/gnunet-service-messenger_basement.c | 58 ++ src/messenger/gnunet-service-messenger_basement.h | 66 ++ src/messenger/gnunet-service-messenger_contact.c | 96 ++ src/messenger/gnunet-service-messenger_contact.h | 112 +++ src/messenger/gnunet-service-messenger_handle.c | 503 ++++++++++ src/messenger/gnunet-service-messenger_handle.h | 216 ++++ .../gnunet-service-messenger_list_handles.c | 95 ++ .../gnunet-service-messenger_list_handles.h | 96 ++ .../gnunet-service-messenger_list_messages.c | 76 ++ .../gnunet-service-messenger_list_messages.h | 81 ++ .../gnunet-service-messenger_message_handle.c | 130 +++ .../gnunet-service-messenger_message_handle.h | 128 +++ .../gnunet-service-messenger_message_kind.c | 192 ++++ .../gnunet-service-messenger_message_kind.h | 160 +++ .../gnunet-service-messenger_message_recv.c | 204 ++++ .../gnunet-service-messenger_message_recv.h | 159 +++ .../gnunet-service-messenger_message_send.c | 118 +++ .../gnunet-service-messenger_message_send.h | 155 +++ .../gnunet-service-messenger_message_store.c | 282 ++++++ .../gnunet-service-messenger_message_store.h | 120 +++ src/messenger/gnunet-service-messenger_room.c | 1051 ++++++++++++++++++++ src/messenger/gnunet-service-messenger_room.h | 378 +++++++ src/messenger/gnunet-service-messenger_service.c | 516 ++++++++++ src/messenger/gnunet-service-messenger_service.h | 259 +++++ src/messenger/gnunet-service-messenger_tunnel.c | 300 ++++++ src/messenger/gnunet-service-messenger_tunnel.h | 155 +++ src/messenger/gnunet-service-messenger_util.c | 64 ++ src/messenger/gnunet-service-messenger_util.h | 53 + src/messenger/messenger.conf.in | 13 + src/messenger/messenger_api.c | 568 +++++++++++ src/messenger/messenger_api_contact.c | 78 ++ src/messenger/messenger_api_contact.h | 93 ++ src/messenger/messenger_api_ego.h | 38 + src/messenger/messenger_api_handle.c | 213 ++++ src/messenger/messenger_api_handle.h | 174 ++++ src/messenger/messenger_api_list_tunnels.c | 112 +++ src/messenger/messenger_api_list_tunnels.h | 112 +++ src/messenger/messenger_api_message.c | 602 +++++++++++ src/messenger/messenger_api_message.h | 190 ++++ src/messenger/messenger_api_room.c | 189 ++++ src/messenger/messenger_api_room.h | 95 ++ src/messenger/test_messenger.c | 187 ++++ src/messenger/test_messenger_anonymous.c | 179 ++++ src/messenger/test_messenger_comm0.c | 252 +++++ src/my/my_query_helper.c | 8 +- src/namecache/Makefile.am | 9 + src/namecache/gnunet-namecache.c | 4 +- src/namecache/gnunet-service-namecache.c | 47 +- src/namecache/namecache.h | 4 +- src/namecache/namecache_api.c | 23 +- src/namecache/plugin_namecache_flat.c | 16 +- src/namecache/plugin_namecache_postgres.c | 30 +- src/namecache/plugin_namecache_sqlite.c | 16 +- src/namecache/test_namecache_api_cache_block.c | 20 +- src/namestore/Makefile.am | 11 +- src/namestore/gnunet-namestore-fcfsd.c | 49 +- src/namestore/gnunet-namestore.c | 45 +- src/namestore/gnunet-service-namestore.c | 34 +- src/namestore/gnunet-zoneimport.c | 4 +- src/namestore/namestore.h | 18 +- src/namestore/namestore_api.c | 14 +- src/namestore/namestore_api_monitor.c | 4 +- src/namestore/perf_namestore_api_zone_iteration.c | 7 +- src/namestore/plugin_namestore_flat.c | 37 +- src/namestore/plugin_namestore_postgres.c | 35 +- src/namestore/plugin_namestore_sqlite.c | 28 +- src/namestore/plugin_rest_namestore.c | 30 +- src/namestore/test_namestore_api_lookup_nick.c | 11 +- src/namestore/test_namestore_api_lookup_private.c | 11 +- src/namestore/test_namestore_api_lookup_public.c | 17 +- src/namestore/test_namestore_api_lookup_shadow.c | 17 +- .../test_namestore_api_lookup_shadow_filter.c | 17 +- src/namestore/test_namestore_api_monitoring.c | 12 +- .../test_namestore_api_monitoring_existing.c | 12 +- src/namestore/test_namestore_api_remove.c | 11 +- ...test_namestore_api_remove_not_existing_record.c | 9 +- src/namestore/test_namestore_api_store.c | 9 +- src/namestore/test_namestore_api_store_update.c | 13 +- src/namestore/test_namestore_api_zone_iteration.c | 39 +- .../test_namestore_api_zone_iteration_nick.c | 14 +- ...st_namestore_api_zone_iteration_specific_zone.c | 14 +- .../test_namestore_api_zone_iteration_stop.c | 39 +- src/namestore/test_namestore_api_zone_to_name.c | 18 +- src/namestore/test_plugin_namestore.c | 6 +- src/namestore/test_plugin_rest_namestore.sh | 21 +- src/nse/gnunet-nse-profiler.c | 2 +- src/peerinfo-tool/gnunet-peerinfo.c | 4 +- src/peerinfo-tool/plugin_rest_peerinfo.c | 4 +- src/pq/pq.c | 45 +- src/pq/pq_eval.c | 6 +- src/pq/pq_query_helper.c | 126 ++- src/pq/pq_result_helper.c | 101 +- src/pq/test_pq.c | 17 +- src/pt/test_gns_vpn.c | 2 +- src/reclaim/Makefile.am | 1 + src/reclaim/gnunet-reclaim.c | 14 +- src/reclaim/gnunet-service-reclaim.c | 26 +- src/reclaim/gnunet-service-reclaim_tickets.c | 36 +- src/reclaim/gnunet-service-reclaim_tickets.h | 12 +- src/reclaim/oidc_helper.c | 73 +- src/reclaim/oidc_helper.h | 10 +- src/reclaim/plugin_rest_openid_connect.c | 57 +- src/reclaim/plugin_rest_reclaim.c | 44 +- src/reclaim/reclaim.h | 26 +- src/reclaim/reclaim_api.c | 30 +- src/reclaim/test_reclaim_attribute.c | 2 - src/regex/regex_block_lib.c | 8 +- src/regex/regex_internal_dht.c | 9 +- src/regex/regex_test_graph.c | 9 +- src/revocation/Makefile.am | 3 + src/revocation/gnunet-revocation-tvg.c | 43 +- src/revocation/gnunet-revocation.c | 71 +- src/revocation/gnunet-service-revocation.c | 75 +- src/revocation/plugin_block_revocation.c | 23 +- src/revocation/revocation.h | 11 +- src/revocation/revocation_api.c | 182 +++- src/revocation/test_revocation.c | 20 +- src/set/gnunet-service-set_union.c | 18 +- src/set/set_api.c | 3 +- src/setu/gnunet-service-setu.c | 20 +- src/statistics/statistics_api.c | 2 +- src/testbed-logger/gnunet-service-testbed-logger.c | 2 +- src/testbed/gnunet-service-testbed_cpustatus.c | 2 +- src/testbed/test_testbed_api_template.conf | 2 +- src/testbed/testbed_api.c | 2 +- src/testbed/testbed_api_topology.c | 6 +- src/transport/gnunet-communicator-udp.c | 494 ++++++--- src/transport/gnunet-service-transport.c | 2 + src/transport/plugin_transport_http_client.c | 15 +- src/transport/plugin_transport_http_common.c | 2 +- src/transport/plugin_transport_http_server.c | 24 +- src/transport/plugin_transport_tcp.c | 12 +- src/transport/plugin_transport_udp.c | 15 +- src/transport/plugin_transport_unix.c | 4 +- src/transport/tcp_connection_legacy.c | 16 +- src/transport/tcp_service_legacy.c | 2 +- src/transport/test_communicator_basic.c | 206 +++- src/transport/transport-testing2.c | 7 + src/util/bio.c | 4 +- src/util/client.c | 2 +- src/util/configuration_loader.c | 15 +- src/util/os_installation.c | 2 + src/util/program.c | 25 +- src/util/service.c | 4 +- src/util/strings.c | 25 +- src/zonemaster/Makefile.am | 3 +- src/zonemaster/gnunet-service-zonemaster-monitor.c | 8 +- src/zonemaster/gnunet-service-zonemaster.c | 8 +- 232 files changed, 14167 insertions(+), 2096 deletions(-) create mode 100644 src/gnsrecord/json_gnsrecord.c create mode 100644 src/include/gnunet_gnsrecord_json_lib.h create mode 100644 src/include/gnunet_messenger_service.h delete mode 100644 src/json/json_gnsrecord.c create mode 100644 src/messenger/.gitignore create mode 100644 src/messenger/Makefile.am create mode 100644 src/messenger/gnunet-messenger.c create mode 100644 src/messenger/gnunet-service-messenger.c create mode 100644 src/messenger/gnunet-service-messenger.h create mode 100644 src/messenger/gnunet-service-messenger_basement.c create mode 100644 src/messenger/gnunet-service-messenger_basement.h create mode 100644 src/messenger/gnunet-service-messenger_contact.c create mode 100644 src/messenger/gnunet-service-messenger_contact.h create mode 100644 src/messenger/gnunet-service-messenger_handle.c create mode 100644 src/messenger/gnunet-service-messenger_handle.h create mode 100644 src/messenger/gnunet-service-messenger_list_handles.c create mode 100644 src/messenger/gnunet-service-messenger_list_handles.h create mode 100644 src/messenger/gnunet-service-messenger_list_messages.c create mode 100644 src/messenger/gnunet-service-messenger_list_messages.h create mode 100644 src/messenger/gnunet-service-messenger_message_handle.c create mode 100644 src/messenger/gnunet-service-messenger_message_handle.h create mode 100644 src/messenger/gnunet-service-messenger_message_kind.c create mode 100644 src/messenger/gnunet-service-messenger_message_kind.h create mode 100644 src/messenger/gnunet-service-messenger_message_recv.c create mode 100644 src/messenger/gnunet-service-messenger_message_recv.h create mode 100644 src/messenger/gnunet-service-messenger_message_send.c create mode 100644 src/messenger/gnunet-service-messenger_message_send.h create mode 100644 src/messenger/gnunet-service-messenger_message_store.c create mode 100644 src/messenger/gnunet-service-messenger_message_store.h create mode 100644 src/messenger/gnunet-service-messenger_room.c create mode 100644 src/messenger/gnunet-service-messenger_room.h create mode 100644 src/messenger/gnunet-service-messenger_service.c create mode 100644 src/messenger/gnunet-service-messenger_service.h create mode 100644 src/messenger/gnunet-service-messenger_tunnel.c create mode 100644 src/messenger/gnunet-service-messenger_tunnel.h create mode 100644 src/messenger/gnunet-service-messenger_util.c create mode 100644 src/messenger/gnunet-service-messenger_util.h create mode 100644 src/messenger/messenger.conf.in create mode 100644 src/messenger/messenger_api.c create mode 100644 src/messenger/messenger_api_contact.c create mode 100644 src/messenger/messenger_api_contact.h create mode 100644 src/messenger/messenger_api_ego.h create mode 100644 src/messenger/messenger_api_handle.c create mode 100644 src/messenger/messenger_api_handle.h create mode 100644 src/messenger/messenger_api_list_tunnels.c create mode 100644 src/messenger/messenger_api_list_tunnels.h create mode 100644 src/messenger/messenger_api_message.c create mode 100644 src/messenger/messenger_api_message.h create mode 100644 src/messenger/messenger_api_room.c create mode 100644 src/messenger/messenger_api_room.h create mode 100644 src/messenger/test_messenger.c create mode 100644 src/messenger/test_messenger_anonymous.c create mode 100644 src/messenger/test_messenger_comm0.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 234a63389..c04d730be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,8 @@ endif if HAVE_EXPERIMENTAL EXP_DIR = \ rps \ - abd + #abd FTBFS + messenger if HAVE_ABE EXP_DIR += \ abe @@ -51,7 +52,6 @@ SUBDIRS = \ include $(INTLEMU_SUBDIRS) \ util \ nt \ - gnsrecord \ hello \ block \ statistics \ @@ -74,7 +74,6 @@ SUBDIRS = \ fragmentation \ transport \ ats-tool \ - peerinfo-tool \ core \ $(TESTBED) \ $(ATS_TESTS) \ @@ -85,8 +84,10 @@ SUBDIRS = \ regex \ dns \ identity \ + gnsrecord \ namecache \ namestore \ + peerinfo-tool \ cadet \ set \ seti \ diff --git a/src/ats-tests/ats-testing-log.c b/src/ats-tests/ats-testing-log.c index 38094a438..955401dd8 100644 --- a/src/ats-tests/ats-testing-log.c +++ b/src/ats-tests/ats-testing-log.c @@ -575,7 +575,7 @@ GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, /* Assembling slave string */ GNUNET_asprintf (&data, - "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%.3f;%.3f\n", + "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%llu;%u;%u;%u;%u;%.3f;%.3f\n", (long long unsigned int) cur_lt->timestamp.abs_value_us, (long long unsigned @@ -593,7 +593,7 @@ GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, (double) plt->app_rtt / 1000, plt->bandwidth_in, plt->bandwidth_out, - plt->ats_delay, + plt->ats_delay.rel_value_us, plt->ats_distance, plt->ats_network_type, plt->ats_utilization_out, diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index dab53b8c4..ae6d21452 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c @@ -442,7 +442,7 @@ GCCH_2s (const struct CadetChannel *ch) ? "loopback" : GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))), GNUNET_h2s (&ch->port), - ch->ctn, + ch->ctn.cn, (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client), @@ -1899,10 +1899,10 @@ GCCH_handle_local_data (struct CadetChannel *ch, GNUNET_memcpy (&crm->data_message[1], buf, buf_len); GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent, ch->tail_sent, crm); LOG (GNUNET_ERROR_TYPE_DEBUG, - "Sending message %u from local client to %s with %u bytes\n", + "Sending message %u from local client to %s with %lu bytes\n", ntohl (crm->data_message->mid.mid), GCCH_2s (ch), - buf_len); + (unsigned long) buf_len); if (NULL != ch->retry_data_task) { GNUNET_SCHEDULER_cancel (ch->retry_data_task); @@ -2044,7 +2044,7 @@ GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level) LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n"); return; } - LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn, ch); + LOG2 (level, "CHN %s:%X (%p)\n", GCT_2s (ch->t), ch->ctn.cn, ch); if (NULL != ch->owner) { LOG2 (level, @@ -2062,7 +2062,7 @@ GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level) ntohl (ch->dest->ccn.channel_of_client)); } LOG2 (level, - "CHN Message IDs recv: %d (%LLX), send: %d\n", + "CHN Message IDs recv: %d (%llX), send: %d\n", ntohl (ch->mid_recv.mid), (unsigned long long) ch->mid_futures, ntohl (ch->mid_send.mid)); diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c index 9a83fa31d..95a5d3f63 100644 --- a/src/cadet/gnunet-service-cadet_core.c +++ b/src/cadet/gnunet-service-cadet_core.c @@ -296,7 +296,7 @@ discard_all_from_rung_tail () while (NULL != (dir = tail->rd_head)) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Queue full due new message %s on connection %s, dropping old message\n", + "Queue full due new message on connection %s, dropping old message\n", GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel)); GNUNET_STATISTICS_update (stats, "# messages dropped due to full buffer", @@ -408,7 +408,7 @@ route_message (struct CadetPeer *prev, { /* We are in the highest rung, drop our own! */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Queue full due new message %s on connection %s, dropping old message\n", + "Queue full due new message on connection %s, dropping old message\n", GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel)); GNUNET_STATISTICS_update (stats, "# messages dropped due to full buffer", diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c index 4e8ccbb08..e1bbeb2c3 100644 --- a/src/cadet/gnunet-service-cadet_dht.c +++ b/src/cadet/gnunet-service-cadet_dht.c @@ -195,8 +195,8 @@ announce_id (void *cls) &my_full_id, sizeof(my_full_id)); LOG (GNUNET_ERROR_TYPE_DEBUG, - "Announcing my HELLO (%u bytes) in the DHT\n", - size); + "Announcing my HELLO (%lu bytes) in the DHT\n", + (unsigned long) size); GNUNET_DHT_put (dht_handle, /* DHT handle */ &phash, /* Key to use */ dht_replication_level, /* Replication level */ diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c index 2ca46b5aa..78bc54a5c 100644 --- a/src/cadet/gnunet-service-cadet_tunnels.c +++ b/src/cadet/gnunet-service-cadet_tunnels.c @@ -2431,7 +2431,7 @@ connection_ready_cb (void *cls, { case CADET_TUNNEL_KEY_UNINITIALIZED: LOG (GNUNET_ERROR_TYPE_DEBUG, - "Do not begin KX for %s if WE have no channels waiting. Retrying after %d\n", + "Do not begin KX for %s if WE have no channels waiting. Retrying after %llu\n", GCT_2s (t), GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us); /* Do not begin KX if WE have no channels waiting! */ diff --git a/src/consensus/consensus_api.c b/src/consensus/consensus_api.c index 06b4c88ef..b4a9e5d39 100644 --- a/src/consensus/consensus_api.c +++ b/src/consensus/consensus_api.c @@ -280,7 +280,7 @@ GNUNET_CONSENSUS_insert (struct GNUNET_CONSENSUS_Handle *consensus, struct GNUNET_MQ_Envelope *ev; struct InsertDoneInfo *i; - LOG (GNUNET_ERROR_TYPE_DEBUG, "inserting, size=%llu\n", element->size); + LOG (GNUNET_ERROR_TYPE_DEBUG, "inserting, size=%u\n", element->size); ev = GNUNET_MQ_msg_extra (element_msg, element->size, GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_INSERT); diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am index 7645b7973..0f99a6526 100644 --- a/src/conversation/Makefile.am +++ b/src/conversation/Makefile.am @@ -185,6 +185,7 @@ gnunet_service_conversation_LDADD = \ libgnunetmicrophone.la \ $(top_builddir)/src/cadet/libgnunetcadet.la \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(INTLLIBS) #gnunet_service_conversation_LDFLAGS = \ # diff --git a/src/conversation/conversation.h b/src/conversation/conversation.h index ed614ab1b..d244f5163 100644 --- a/src/conversation/conversation.h +++ b/src/conversation/conversation.h @@ -27,6 +27,8 @@ #ifndef CONVERSATION_H #define CONVERSATION_H +#include "gnunet_identity_service.h" + #ifdef __cplusplus extern "C" { @@ -105,7 +107,7 @@ struct ClientPhoneRingMessage /** * Who is calling us? */ - struct GNUNET_CRYPTO_EcdsaPublicKey caller_id; + struct GNUNET_IDENTITY_PublicKey caller_id; }; @@ -230,7 +232,7 @@ struct ClientCallMessage /** * Identity of the caller. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey caller_id; + struct GNUNET_IDENTITY_PrivateKey caller_id; }; @@ -301,7 +303,7 @@ struct CadetPhoneRingMessage /** * Who is calling us? (also who is signing). */ - struct GNUNET_CRYPTO_EcdsaPublicKey caller_id; + struct GNUNET_IDENTITY_PublicKey caller_id; /** * When does the signature expire? @@ -311,7 +313,7 @@ struct CadetPhoneRingMessage /** * Signature over a `struct CadetPhoneRingInfoPS` */ - struct GNUNET_CRYPTO_EcdsaSignature signature; + struct GNUNET_IDENTITY_Signature signature; }; diff --git a/src/conversation/conversation_api.c b/src/conversation/conversation_api.c index daf51042a..88fe8f11c 100644 --- a/src/conversation/conversation_api.c +++ b/src/conversation/conversation_api.c @@ -105,7 +105,7 @@ struct GNUNET_CONVERSATION_Caller /** * Identity of the person calling us. */ - struct GNUNET_CRYPTO_EcdsaPublicKey caller_id; + struct GNUNET_IDENTITY_PublicKey caller_id; /** * Internal handle to identify the caller with the service. @@ -192,7 +192,7 @@ struct GNUNET_CONVERSATION_Phone /** * My GNS zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey my_zone; + struct GNUNET_IDENTITY_PrivateKey my_zone; /** * State machine for the phone. diff --git a/src/conversation/gnunet-conversation.c b/src/conversation/gnunet-conversation.c index 7a2a727a5..9ff0002e7 100644 --- a/src/conversation/gnunet-conversation.c +++ b/src/conversation/gnunet-conversation.c @@ -116,7 +116,7 @@ struct CallList /** * Public key identifying the caller. */ - struct GNUNET_CRYPTO_EcdsaPublicKey caller_id; + struct GNUNET_IDENTITY_PublicKey caller_id; /** * Unique number of the call. @@ -194,7 +194,7 @@ static char *ego_name; /** * Public key of active conversation partner (if any). */ -static struct GNUNET_CRYPTO_EcdsaPublicKey peer_key; +static struct GNUNET_IDENTITY_PublicKey peer_key; /** * Name of active conversation partner (if any). @@ -244,7 +244,7 @@ static void phone_event_handler (void *cls, enum GNUNET_CONVERSATION_PhoneEventCode code, struct GNUNET_CONVERSATION_Caller *caller, - const struct GNUNET_CRYPTO_EcdsaPublicKey *caller_id) + const struct GNUNET_IDENTITY_PublicKey *caller_id) { struct CallList *cl; diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c index 502146255..a69c95a80 100644 --- a/src/conversation/gnunet-service-conversation.c +++ b/src/conversation/gnunet-service-conversation.c @@ -752,10 +752,11 @@ handle_cadet_ring_message (void *cls, const struct CadetPhoneRingMessage *msg) rs.expiration_time = msg->expiration_time; if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, - &rs, - &msg->signature, - &msg->caller_id)) + GNUNET_IDENTITY_signature_verify ( + GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, + &rs, + &msg->signature, + &msg->caller_id)) { GNUNET_break_op (0); destroy_line_cadet_channels (ch); @@ -1136,11 +1137,9 @@ handle_client_call_message (void *cls, const struct ClientCallMessage *msg) cadet_handlers); ch->mq = GNUNET_CADET_get_mq (ch->channel); e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); - GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, &ring->caller_id); + GNUNET_IDENTITY_key_get_public (&msg->caller_id, &ring->caller_id); ring->expiration_time = rs.expiration_time; - GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, - &rs, - &ring->signature); + GNUNET_IDENTITY_sign (&msg->caller_id, &rs, &ring->signature); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n"); GNUNET_MQ_send (ch->mq, e); GNUNET_SERVICE_client_continue (line->client); diff --git a/src/conversation/test_conversation_api.c b/src/conversation/test_conversation_api.c index b51186dc8..c5efecd52 100644 --- a/src/conversation/test_conversation_api.c +++ b/src/conversation/test_conversation_api.c @@ -305,7 +305,7 @@ static void phone_event_handler (void *cls, enum GNUNET_CONVERSATION_PhoneEventCode code, struct GNUNET_CONVERSATION_Caller *caller, - const struct GNUNET_CRYPTO_EcdsaPublicKey *caller_id) + const struct GNUNET_IDENTITY_PublicKey *caller_id) { static enum GNUNET_CONVERSATION_PhoneEventCode expect = GNUNET_CONVERSATION_EC_PHONE_RING; @@ -385,7 +385,7 @@ call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code) static void caller_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; @@ -414,7 +414,7 @@ identity_cb (void *cls, const char *name) { struct GNUNET_GNSRECORD_Data rd; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; (void) cls; (void) ctx; @@ -465,7 +465,7 @@ identity_cb (void *cls, static void phone_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; diff --git a/src/conversation/test_conversation_api_reject.c b/src/conversation/test_conversation_api_reject.c index 69fa9f1dc..08c64df37 100644 --- a/src/conversation/test_conversation_api_reject.c +++ b/src/conversation/test_conversation_api_reject.c @@ -179,7 +179,7 @@ static void phone_event_handler (void *cls, enum GNUNET_CONVERSATION_PhoneEventCode code, struct GNUNET_CONVERSATION_Caller *caller, - const struct GNUNET_CRYPTO_EcdsaPublicKey *caller_id) + const struct GNUNET_IDENTITY_PublicKey *caller_id) { static enum GNUNET_CONVERSATION_PhoneEventCode expect = GNUNET_CONVERSATION_EC_PHONE_RING; @@ -238,7 +238,7 @@ call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code) static void caller_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; @@ -267,7 +267,7 @@ identity_cb (void *cls, const char *name) { struct GNUNET_GNSRECORD_Data rd; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; (void) cls; (void) ctx; @@ -318,7 +318,7 @@ identity_cb (void *cls, static void phone_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; diff --git a/src/conversation/test_conversation_api_twocalls.c b/src/conversation/test_conversation_api_twocalls.c index 83e8cb55a..ac7a3c9dd 100644 --- a/src/conversation/test_conversation_api_twocalls.c +++ b/src/conversation/test_conversation_api_twocalls.c @@ -403,7 +403,7 @@ static void phone_event_handler (void *cls, enum GNUNET_CONVERSATION_PhoneEventCode code, struct GNUNET_CONVERSATION_Caller *caller, - const struct GNUNET_CRYPTO_EcdsaPublicKey *caller_id) + const struct GNUNET_IDENTITY_PublicKey *caller_id) { const char *cid; @@ -507,7 +507,7 @@ call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code) static void caller_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; @@ -536,7 +536,7 @@ identity_cb (void *cls, const char *name) { struct GNUNET_GNSRECORD_Data rd; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; (void) cls; (void) ctx; @@ -594,7 +594,7 @@ identity_cb (void *cls, static void phone_ego_create_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { (void) cls; diff --git a/src/datacache/plugin_datacache_postgres.c b/src/datacache/plugin_datacache_postgres.c index c21be9219..724324ca4 100644 --- a/src/datacache/plugin_datacache_postgres.c +++ b/src/datacache/plugin_datacache_postgres.c @@ -67,14 +67,19 @@ static int init_connection (struct Plugin *plugin) { struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_try_execute ("CREATE TEMPORARY SEQUENCE IF NOT EXISTS gn011dc_oid_seq"), GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS gn011dc (" + " oid OID NOT NULL DEFAULT nextval('gn011dc_oid_seq')," " type INTEGER NOT NULL," " prox INTEGER NOT NULL," " discard_time BIGINT NOT NULL," " key BYTEA NOT NULL," " value BYTEA NOT NULL," - " path BYTEA DEFAULT NULL)" - "WITH OIDS"), + " path BYTEA DEFAULT NULL)"), + GNUNET_PQ_make_try_execute ( + "ALTER SEQUENCE gnu011dc_oid_seq OWNED BY gn011dc.oid"), + GNUNET_PQ_make_try_execute ( + "CREATE INDEX IF NOT EXISTS idx_oid ON gn011dc (oid)"), GNUNET_PQ_make_try_execute ( "CREATE INDEX IF NOT EXISTS idx_key ON gn011dc (key)"), GNUNET_PQ_make_try_execute ( diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 4537f6efe..bd7a612ed 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c @@ -994,8 +994,8 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h, } LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to put %u bytes of data under key `%s' for %s\n", - size, + "Asked to put %lu bytes of data under key `%s' for %s\n", + (unsigned long) size, GNUNET_h2s (key), GNUNET_STRINGS_relative_time_to_string ( GNUNET_TIME_absolute_get_remaining (expiration), @@ -1205,8 +1205,8 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h, if (NULL == cont) cont = &drop_status_cont; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to remove %u bytes under key `%s'\n", - size, + "Asked to remove %lu bytes under key `%s'\n", + (unsigned long) size, GNUNET_h2s (key)); env = GNUNET_MQ_msg_extra (dm, size, diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c index 88ceb1b0a..6a5d45832 100644 --- a/src/datastore/plugin_datastore_postgres.c +++ b/src/datastore/plugin_datastore_postgres.c @@ -72,8 +72,10 @@ init_connection (struct Plugin *plugin) * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel * we do math or inequality tests, so we can't handle the entire range of uint32_t. * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC. - * PostgreSQL also recommends against using WITH OIDS. - */GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS gn090 (" + */ + GNUNET_PQ_make_try_execute ( + "CREATE SEQUENCE IF NOT EXISTS gn090_oid_seq"), + GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS gn090 (" " repl INTEGER NOT NULL DEFAULT 0," " type INTEGER NOT NULL DEFAULT 0," " prio INTEGER NOT NULL DEFAULT 0," @@ -82,8 +84,12 @@ init_connection (struct Plugin *plugin) " rvalue BIGINT NOT NULL DEFAULT 0," " hash BYTEA NOT NULL DEFAULT ''," " vhash BYTEA NOT NULL DEFAULT ''," - " value BYTEA NOT NULL DEFAULT '')" - "WITH OIDS"), + " value BYTEA NOT NULL DEFAULT ''," + " oid OID NOT NULL DEFAULT nextval('gn090_oid_seq'))"), + GNUNET_PQ_make_try_execute ( + "ALTER SEQUENCE gn090_oid_seq OWNED BY gn090.oid"), + GNUNET_PQ_make_try_execute ( + "CREATE INDEX IF NOT EXISTS oid_hash ON gn090 (oid)"), GNUNET_PQ_make_try_execute ( "CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)"), GNUNET_PQ_make_try_execute ( diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index 1e44c1fad..5eb3115f4 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c @@ -488,8 +488,8 @@ handle_dht_local_put (void *cls, GNUNET_h2s_full (&dht_msg->key)); /* give to local clients */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Handling local PUT of %u-bytes for query %s\n", - size - sizeof(struct GNUNET_DHT_ClientPutMessage), + "Handling local PUT of %lu-bytes for query %s\n", + (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)), GNUNET_h2s (&dht_msg->key)); GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), &dht_msg->key, @@ -619,7 +619,7 @@ handle_dht_local_get (void *cls, "Received GET request for %s from local client %p, xq: %.*s\n", GNUNET_h2s (&get->key), ch->client, - xquery_size, + (int) xquery_size, xquery); LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "CLIENT-GET %s\n", diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 41b7a3a2b..7eded2152 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c @@ -94,9 +94,9 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, put_path_length, put_path); LOG (GNUNET_ERROR_TYPE_DEBUG, - "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", + "DATACACHE PUT for key %s [%lu] completed (%d) after %u hops\n", GNUNET_h2s (key), - data_size, + (unsigned long) data_size, r, put_path_length); } diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index b211fca6b..88b0c5d92 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -2212,8 +2212,8 @@ handle_dht_p2p_get (void *cls, bg, peer_bf); GDS_CLIENTS_process_get (options - | (GNUNET_OK == forwarded) - ? GNUNET_DHT_RO_LAST_HOP : 0, + | ((GNUNET_OK == forwarded) + ? GNUNET_DHT_RO_LAST_HOP : 0), type, ntohl (get->hop_count), ntohl (get->desired_replication_level), diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index f213433ed..a9f336240 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c @@ -195,7 +195,7 @@ block_plugin_dht_get_key (void *cls, { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "block-dht", - _ ("Size mismatch for block\n"), + _ ("Size mismatch for block with type %u\n"), GNUNET_BLOCK_TYPE_DHT_HELLO); return GNUNET_NO; } diff --git a/src/dns/gnunet-dns-monitor.c b/src/dns/gnunet-dns-monitor.c index d9830baa4..836d65c79 100644 --- a/src/dns/gnunet-dns-monitor.c +++ b/src/dns/gnunet-dns-monitor.c @@ -203,7 +203,7 @@ display_record (const struct GNUNET_DNSPARSER_Record *record) else { GNUNET_asprintf (&tmp, - "priority %u, weight = %s, port = %u, target = %s", + "priority %u, weight = %u, port = %u, target = %s", (unsigned int) record->data.srv->priority, (unsigned int) record->data.srv->weight, (unsigned int) record->data.srv->port, diff --git a/src/fragmentation/fragmentation.c b/src/fragmentation/fragmentation.c index 3a7da37e8..36e1c33f4 100644 --- a/src/fragmentation/fragmentation.c +++ b/src/fragmentation/fragmentation.c @@ -158,7 +158,7 @@ GNUNET_FRAGMENT_print_ack (const struct GNUNET_MessageHeader *ack) sizeof(buf), "%u-%llX", ntohl (fa->fragment_id), - GNUNET_ntohll (fa->bits)); + (unsigned long long) GNUNET_ntohll (fa->bits)); return buf; } diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 6154e8be0..d4677b794 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -1050,7 +1050,7 @@ process_result_with_request (void *cls, GNUNET_asprintf ( &dc->emsg, _ ( - "Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"), + "Internal error or bogus download URI (expected %lu bytes at depth %u and offset %llu/%llu, got %lu bytes)"), bs, dr->depth, (unsigned long long) dr->offset, diff --git a/src/fs/gnunet-daemon-fsprofiler.c b/src/fs/gnunet-daemon-fsprofiler.c index 829906461..fbb7c6028 100644 --- a/src/fs/gnunet-daemon-fsprofiler.c +++ b/src/fs/gnunet-daemon-fsprofiler.c @@ -592,14 +592,14 @@ run (void *cls, char *const *args GNUNET_UNUSED, &replication_level)) replication_level = 1; GNUNET_snprintf (myoptname, sizeof(myoptname), - "DOWNLOAD-PATTERN-%u", my_peerid); + "DOWNLOAD-PATTERN-%llu", my_peerid); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "FSPROFILER", myoptname, &download_pattern)) download_pattern = GNUNET_strdup (""); GNUNET_snprintf (myoptname, sizeof(myoptname), - "PUBLISH-PATTERN-%u", my_peerid); + "PUBLISH-PATTERN-%llu", my_peerid); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "FSPROFILER", myoptname, diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index 91fcd8f8a..dea467669 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c @@ -475,6 +475,7 @@ uri_ksk_continuation (void *cls, const char *emsg) { const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv; + const struct GNUNET_IDENTITY_PrivateKey *pk; if (NULL != emsg) { @@ -486,7 +487,10 @@ uri_ksk_continuation (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - priv = GNUNET_IDENTITY_ego_get_private_key (namespace); + pk = GNUNET_IDENTITY_ego_get_private_key (namespace); + if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (pk->type)) + return; + priv = &pk->ecdsa_key; GNUNET_FS_publish_sks (ctx, priv, this_id, @@ -569,6 +573,7 @@ directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result) { struct GNUNET_FS_FileInformation *fi; const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv; + const struct GNUNET_IDENTITY_PrivateKey *pk; fi = get_file_information (directory_scan_result); GNUNET_FS_share_tree_free (directory_scan_result); @@ -586,10 +591,13 @@ directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result) GNUNET_SCHEDULER_shutdown (); return; } - if (NULL == namespace) - priv = NULL; - else - priv = GNUNET_IDENTITY_ego_get_private_key (namespace); + priv = NULL; + if (NULL != namespace) + { + pk = GNUNET_IDENTITY_ego_get_private_key (namespace); + GNUNET_assert (GNUNET_IDENTITY_TYPE_ECDSA == ntohl (pk->type)); + priv = &pk->ecdsa_key; + } pc = GNUNET_FS_publish_start (ctx, fi, priv, diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 5a9c70997..744ba66ec 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -109,6 +109,7 @@ libgnunet_plugin_rest_gns_la_SOURCES = \ plugin_rest_gns.c libgnunet_plugin_rest_gns_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecordjson.la \ libgnunetgns.la \ $(top_builddir)/src/rest/libgnunetrest.la \ $(top_builddir)/src/identity/libgnunetidentity.la \ @@ -124,6 +125,7 @@ libgnunet_plugin_gnsrecord_gns_la_SOURCES = \ plugin_gnsrecord_gns.c libgnunet_plugin_gnsrecord_gns_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(LTLIBINTL) libgnunet_plugin_gnsrecord_gns_la_LDFLAGS = \ @@ -135,6 +137,7 @@ gnunet_gns_SOURCES = \ gnunet_gns_LDADD = \ libgnunetgns.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(LIBIDN) $(LIBIDN2) \ $(GN_LIBINTL) @@ -144,6 +147,7 @@ gnunet_gns_benchmark_SOURCES = \ gnunet_gns_benchmark_LDADD = \ libgnunetgns.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) @@ -247,6 +251,7 @@ libgnunet_plugin_block_gns_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/block/libgnunetblock.la \ $(top_builddir)/src/block/libgnunetblockgroup.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la libgnunet_plugin_block_gns_la_LDFLAGS = \ $(GN_LIBINTL) \ diff --git a/src/gns/gns.h b/src/gns/gns.h index a193632b7..d824742ad 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h @@ -48,7 +48,7 @@ struct LookupMessage /** * Zone that is to be used for lookup */ - struct GNUNET_CRYPTO_EcdsaPublicKey zone; + struct GNUNET_IDENTITY_PublicKey zone; /** * Local options for where to look for results diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index bf95bf340..841a0d240 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -343,7 +343,7 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle, const char *name, - const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, + const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, uint16_t recursion_depth_limit, @@ -411,7 +411,7 @@ GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle, struct GNUNET_GNS_LookupRequest* GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, const char *name, - const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, + const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c index 3ebf07db6..b883662ad 100644 --- a/src/gns/gns_tld_api.c +++ b/src/gns/gns_tld_api.c @@ -167,7 +167,7 @@ process_lookup_result (void *cls, */ static void lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr, - const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) + const struct GNUNET_IDENTITY_PublicKey *pkey) { ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle, ltr->name, @@ -190,11 +190,11 @@ lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr, */ static void identity_zone_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + const struct GNUNET_IDENTITY_PrivateKey *priv, const char *ego_name) { struct GNUNET_GNS_LookupWithTldRequest *ltr = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; ltr->id_co = NULL; if (NULL == priv) @@ -219,7 +219,7 @@ identity_zone_cb (void *cls, ltr->options = GNUNET_GNS_LO_NO_DHT; else ltr->options = GNUNET_GNS_LO_LOCAL_MASTER; - GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pkey); + GNUNET_IDENTITY_key_get_public (priv, &pkey); lookup_with_public_key (ltr, &pkey); } @@ -249,7 +249,7 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, const char *tld; char *dot_tld; char *zonestr; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; ltr = GNUNET_new (struct GNUNET_GNS_LookupWithTldRequest); ltr->gns_handle = handle; @@ -261,8 +261,10 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, /* start with trivial case: TLD is zkey */ tld = get_tld (ltr->name); if (GNUNET_OK == - GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, strlen (tld), &pkey)) + GNUNET_IDENTITY_public_key_from_string (tld, &pkey)) { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "`%s' seems to be a valid zone key\n", tld); eat_tld (ltr->name, tld); lookup_with_public_key (ltr, &pkey); return ltr; @@ -281,9 +283,8 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, &zonestr)) { if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr, - strlen (zonestr), - &pkey)) + GNUNET_IDENTITY_public_key_from_string (zonestr, + &pkey)) { GNUNET_log_config_invalid ( GNUNET_ERROR_TYPE_ERROR, @@ -304,6 +305,8 @@ GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, } GNUNET_free (dot_tld); } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "`%s' should be a valid ego\n", ltr->name); ltr->id_co = GNUNET_IDENTITY_ego_lookup_by_suffix (ltr->gns_handle->cfg, ltr->name, diff --git a/src/gns/gnunet-gns-import.c b/src/gns/gnunet-gns-import.c index 78db28cab..972fb49cd 100644 --- a/src/gns/gnunet-gns-import.c +++ b/src/gns/gnunet-gns-import.c @@ -168,12 +168,17 @@ check_pkey (unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, char *pk, int *found_rec) { int i; + struct GNUNET_IDENTITY_PublicKey pubkey; for (i = 0; i < rd_len; i++) { char *s; - if ((GNUNET_GNSRECORD_TYPE_PKEY != rd[i].record_type) || - (rd[i].data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) + if (sizeof (uint32_t) > rd[i].data_size) + continue; + if (GNUNET_OK != GNUNET_GNSRECORD_identity_from_data (rd[i].data, + rd[i].data_size, + rd[i].record_type, + &pubkey)) continue; s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, rd[i].data, diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 8c5b2d6c4..52300ae3b 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c @@ -123,7 +123,7 @@ struct GNS_TopLevelDomain /** * Public key associated with the @a tld. */ - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; /** * Top-level domain as a string, including leading ".". @@ -177,7 +177,7 @@ static struct GNS_TopLevelDomain *tld_tail; */ int GNS_find_tld (const char *tld_str, - struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) + struct GNUNET_IDENTITY_PublicKey *pkey) { if ('\0' == *tld_str) return GNUNET_NO; @@ -485,7 +485,7 @@ read_service_conf (void *cls, const char *option, const char *value) { - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; struct GNS_TopLevelDomain *tld; (void) cls; diff --git a/src/gns/gnunet-service-gns.h b/src/gns/gnunet-service-gns.h index 2a432f8aa..d4fb9ec9f 100644 --- a/src/gns/gnunet-service-gns.h +++ b/src/gns/gnunet-service-gns.h @@ -26,6 +26,7 @@ #ifndef GNUNET_SERVICE_GNS_H #define GNUNET_SERVICE_GNS_H +#include "gnunet_identity_service.h" /** * Find GNS zone belonging to TLD @a tld. @@ -36,7 +37,7 @@ */ int GNS_find_tld (const char *tld_str, - struct GNUNET_CRYPTO_EcdsaPublicKey *pkey); + struct GNUNET_IDENTITY_PublicKey *pkey); /** diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c index 19416a506..b53f4af6b 100644 --- a/src/gns/gnunet-service-gns_interceptor.c +++ b/src/gns/gnunet-service-gns_interceptor.c @@ -314,7 +314,7 @@ handle_dns_request (void *cls, { struct GNUNET_DNSPARSER_Packet *p; struct InterceptLookupHandle *ilh; - struct GNUNET_CRYPTO_EcdsaPublicKey zone; + struct GNUNET_IDENTITY_PublicKey zone; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hijacked a DNS request. Processing.\n"); diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index cb75b23c7..d9d0d3099 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -173,7 +173,7 @@ struct AuthorityChain /** * The zone of the GNS authority */ - struct GNUNET_CRYPTO_EcdsaPublicKey gns_authority; + struct GNUNET_IDENTITY_PublicKey gns_authority; struct { @@ -305,7 +305,7 @@ struct GNS_ResolverHandle /** * The top-level GNS authoritative zone to query */ - struct GNUNET_CRYPTO_EcdsaPublicKey authority_zone; + struct GNUNET_IDENTITY_PublicKey authority_zone; /** * called when resolution phase finishes @@ -1251,7 +1251,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, const char *tld; struct AuthorityChain *ac; int af; - struct GNUNET_CRYPTO_EcdsaPublicKey zone; + struct GNUNET_IDENTITY_PublicKey zone; nlen = strlen (cname); tld = GNS_get_tld (cname); @@ -1296,7 +1296,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, { GNUNET_asprintf (&res, "%.*s", - strlen (cname) - (strlen (tld) + 1), + (int) (strlen (cname) - (strlen (tld) + 1)), cname); } else @@ -1305,7 +1305,7 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh, "%.*s.%.*s", (int) rh->name_resolution_pos, rh->name, - (int) strlen (cname) - (strlen (tld) + 1), + (int) (strlen (cname) - (strlen (tld) + 1)), cname); } rh->name_resolution_pos = strlen (res); @@ -1696,10 +1696,13 @@ recursive_pkey_resolution (struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd) { struct AuthorityChain *ac; + struct GNUNET_IDENTITY_PublicKey auth; /* delegation to another zone */ - if (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) != - rd->data_size) + if (GNUNET_OK != GNUNET_GNSRECORD_identity_from_data (rd->data, + rd->data_size, + rd->record_type, + &auth)) { GNUNET_break_op (0); fail_resolution (rh); @@ -1709,9 +1712,7 @@ recursive_pkey_resolution (struct GNS_ResolverHandle *rh, ac = GNUNET_new (struct AuthorityChain); ac->rh = rh; ac->gns_authority = GNUNET_YES; - GNUNET_memcpy (&ac->authority_info.gns_authority, - rd->data, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + ac->authority_info.gns_authority = auth; ac->label = resolver_lookup_get_next_label (rh); /* add AC to tail */ GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, @@ -1754,7 +1755,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh, char *n; size_t off; struct Gns2DnsPending *gp; - struct GNUNET_CRYPTO_EcdsaPublicKey zone; + struct GNUNET_IDENTITY_PublicKey zone; struct sockaddr_in v4; struct sockaddr_in6 v6; @@ -2257,19 +2258,25 @@ handle_gns_resolution_result (void *cls, break; case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: { - struct GNUNET_CRYPTO_EcdsaPublicKey pub; - - if (rd[i].data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) + struct GNUNET_IDENTITY_PublicKey pubkey; + if (rd[i].data_size < sizeof(uint32_t)) + { + GNUNET_break_op (0); + break; + } + if (GNUNET_OK != + GNUNET_GNSRECORD_identity_from_data (rd[i].data, + rd[i].data_size, + rd[i].record_type, + &pubkey)) { GNUNET_break_op (0); break; } - GNUNET_memcpy (&pub, - rd[i].data, - rd[i].data_size); rd_off++; - if (GNUNET_GNSRECORD_TYPE_PKEY != rh->record_type) + if (rd[i].record_type != rh->record_type) { /* try to resolve "@" */ struct AuthorityChain *ac; @@ -2277,7 +2284,7 @@ handle_gns_resolution_result (void *cls, ac = GNUNET_new (struct AuthorityChain); ac->rh = rh; ac->gns_authority = GNUNET_YES; - ac->authority_info.gns_authority = pub; + ac->authority_info.gns_authority = pubkey; ac->label = GNUNET_strdup (GNUNET_GNS_EMPTY_LABEL_AT); GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, rh->ac_tail, @@ -2367,6 +2374,7 @@ handle_gns_resolution_result (void *cls, return; case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: GNUNET_break_op (1 == rd_count); /* PKEY should be unique */ recursive_pkey_resolution (rh, &rd[0]); @@ -2469,10 +2477,7 @@ handle_dht_response (void *cls, return; } block = data; - if (size != - ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) + if (size != GNUNET_GNSRECORD_block_get_size (block)) { /* how did this pass DHT block validation!? */ GNUNET_break (0); @@ -2480,8 +2485,8 @@ handle_dht_response (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Decrypting DHT block of size %u for `%s', expires %s\n", - ntohl (block->purpose.size), + "Decrypting DHT block of size %lu for `%s', expires %s\n", + GNUNET_GNSRECORD_block_get_size (block), rh->name, GNUNET_STRINGS_absolute_time_to_string (exp)); if (GNUNET_OK != @@ -2495,8 +2500,8 @@ handle_dht_response (void *cls, fail_resolution (rh); return; } - if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh ( - block->expiration_time)). + if (0 == GNUNET_TIME_absolute_get_remaining ( + GNUNET_GNSRECORD_block_get_expiration (block)). rel_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -2594,7 +2599,7 @@ handle_namecache_block_response (void *cls, struct GNS_ResolverHandle *rh = cls; struct AuthorityChain *ac = rh->ac_tail; const char *label = ac->label; - const struct GNUNET_CRYPTO_EcdsaPublicKey *auth = + const struct GNUNET_IDENTITY_PublicKey *auth = &ac->authority_info.gns_authority; struct GNUNET_HashCode query; @@ -2604,8 +2609,8 @@ handle_namecache_block_response (void *cls, ((GNUNET_GNS_LO_LOCAL_MASTER == rh->options) && (ac != rh->ac_head))) && ((NULL == block) || - (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh ( - block->expiration_time)). + (0 == GNUNET_TIME_absolute_get_remaining ( + GNUNET_GNSRECORD_block_get_expiration (block)). rel_value_us))) { /* namecache knows nothing; try DHT lookup */ @@ -2622,8 +2627,8 @@ handle_namecache_block_response (void *cls, } if ((NULL == block) || - (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh ( - block->expiration_time)). + (0 == GNUNET_TIME_absolute_get_remaining ( + GNUNET_GNSRECORD_block_get_expiration (block)). rel_value_us)) { /* DHT not permitted and no local result, fail */ @@ -2857,7 +2862,7 @@ start_resolver_lookup (void *cls) * @return handle to cancel operation */ struct GNS_ResolverHandle * -GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, +GNS_resolver_lookup (const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t record_type, const char *name, enum GNUNET_GNS_LocalOptions options, diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index 3dab3c91a..b099c5d65 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h @@ -86,7 +86,7 @@ typedef void * @return handle to cancel operation */ struct GNS_ResolverHandle * -GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, +GNS_resolver_lookup (const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t record_type, const char *name, enum GNUNET_GNS_LocalOptions options, diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index aabedcaac..9b58c9034 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c @@ -145,17 +145,13 @@ block_plugin_gns_evaluate (void *cls, return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } block = reply_block; - if (ntohl (block->purpose.size) + sizeof(struct - GNUNET_CRYPTO_EcdsaSignature) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) != - reply_block_size) + if (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - GNUNET_CRYPTO_hash (&block->derived_key, - sizeof(block->derived_key), - &h); + GNUNET_GNSRECORD_query_from_block (block, + &h); if (0 != GNUNET_memcmp (&h, query)) { GNUNET_break_op (0); @@ -206,9 +202,8 @@ block_plugin_gns_get_key (void *cls, return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } block = reply_block; - GNUNET_CRYPTO_hash (&block->derived_key, - sizeof(block->derived_key), - key); + GNUNET_GNSRECORD_query_from_block (block, + key); return GNUNET_OK; } diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 81f2b9eff..a2ad0b905 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c @@ -50,13 +50,18 @@ gns_value_to_string (void *cls, size_t data_size) { const char *cdata; + struct GNUNET_IDENTITY_PublicKey pk; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: - if (data_size != sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) + case GNUNET_GNSRECORD_TYPE_EDKEY: + if (GNUNET_OK != GNUNET_GNSRECORD_identity_from_data (data, + data_size, + type, + &pk)) return NULL; - return GNUNET_CRYPTO_ecdsa_public_key_to_string (data); + return GNUNET_IDENTITY_public_key_to_string (&pk); case GNUNET_GNSRECORD_TYPE_NICK: return GNUNET_strndup (data, data_size); @@ -153,24 +158,35 @@ gns_string_to_value (void *cls, void **data, size_t *data_size) { - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pk; + uint32_t record_type; if (NULL == s) return GNUNET_SYSERR; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) + GNUNET_IDENTITY_public_key_from_string (s, &pk)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Unable to parse PKEY record `%s'\n"), + _ ("Unable to parse zone key record `%s'\n"), s); return GNUNET_SYSERR; } - *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); - GNUNET_memcpy (*data, &pkey, sizeof(pkey)); - *data_size = sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey); + *data_size = GNUNET_IDENTITY_key_get_length (&pk); + if (GNUNET_OK != GNUNET_GNSRECORD_data_from_identity (&pk, + (char **) data, + data_size, + &record_type)) + return GNUNET_SYSERR; + if (record_type != type) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Record type does not match parsed record type\n")); + return GNUNET_SYSERR; + } return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_NICK: @@ -301,6 +317,7 @@ static struct const char *name; uint32_t number; } gns_name_map[] = { { "PKEY", GNUNET_GNSRECORD_TYPE_PKEY }, + { "EDKEY", GNUNET_GNSRECORD_TYPE_PKEY }, { "NICK", GNUNET_GNSRECORD_TYPE_NICK }, { "LEHO", GNUNET_GNSRECORD_TYPE_LEHO }, { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c index 6ec921f70..2ccb5be2b 100644 --- a/src/gns/plugin_rest_gns.c +++ b/src/gns/plugin_rest_gns.c @@ -28,6 +28,7 @@ #include "gnunet_rest_lib.h" #include "gnunet_json_lib.h" #include "gnunet_gnsrecord_lib.h" +#include "gnunet_gnsrecord_json_lib.h" #include "gnunet_gns_service.h" #include "microhttpd.h" #include @@ -264,7 +265,7 @@ handle_gns_response (void *cls, return; } - result_obj = GNUNET_JSON_from_gnsrecord (handle->name, rd, rd_count); + result_obj = GNUNET_GNSRECORD_JSON_from_gnsrecord (handle->name, rd, rd_count); result = json_dumps (result_obj, 0); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result); diff --git a/src/gns/test_gns_dht_lookup.sh b/src/gns/test_gns_dht_lookup.sh index d5516fd03..8d446c507 100755 --- a/src/gns/test_gns_dht_lookup.sh +++ b/src/gns/test_gns_dht_lookup.sh @@ -26,6 +26,7 @@ gnunet-arm -i datastore -c test_gns_lookup.conf gnunet-identity -C $OTHER_EGO -c test_gns_lookup.conf DELEGATED_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep $OTHER_EGO | awk '{print $3}') gnunet-identity -C $MY_EGO -c test_gns_lookup.conf +echo "MYEGO: $MY_EGO OTHER_EGO: $DELEGATED_PKEY" gnunet-namestore -p -z $MY_EGO -a -n b -t PKEY -V $DELEGATED_PKEY -e never -c test_gns_lookup.conf #This works gnunet-namestore -p -z $OTHER_EGO -a -n www -t A -V $TEST_IP -e never -c test_gns_lookup.conf diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am index 2e6eca7ba..ab604eb92 100644 --- a/src/gnsrecord/Makefile.am +++ b/src/gnsrecord/Makefile.am @@ -1,5 +1,5 @@ # This Makefile.am is in the public domain -AM_CPPFLAGS = -I$(top_srcdir)/src/include +AM_CPPFLAGS = -I$(top_srcdir)/src/include ${MHD_CFLAGS} plugindir = $(libdir)/gnunet @@ -30,12 +30,14 @@ TESTS = \ endif lib_LTLIBRARIES = \ - libgnunetgnsrecord.la + libgnunetgnsrecord.la \ + libgnunetgnsrecordjson.la gnunet_gnsrecord_tvg_SOURCES = \ gnunet-gnsrecord-tvg.c gnunet_gnsrecord_tvg_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetgnsrecord.la \ $(GN_LIBINTL) @@ -47,11 +49,26 @@ libgnunetgnsrecord_la_SOURCES = \ gnsrecord_misc.c libgnunetgnsrecord_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + $(LIBGCRYPT_LIBS) \ $(GN_LIBINTL) +libgnunetgnsrecord_la_DEPENDENCIES = \ + $(top_builddir)/src/identity/libgnunetidentity.la libgnunetgnsrecord_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ -version-info 0:0:0 +libgnunetgnsrecordjson_la_SOURCES = \ + json_gnsrecord.c +libgnunetgnsrecordjson_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + libgnunetgnsrecord.la \ + -ljansson \ + $(GN_LIBINTL) +libgnunetgnsrecordjson_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 plugin_LTLIBRARIES = \ libgnunet_plugin_gnsrecord_dns.la diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index c8919760a..9c551a936 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c @@ -37,6 +37,61 @@ #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) +ssize_t +ecdsa_symmetric_decrypt ( + const void *block, + size_t size, + const unsigned char *key, + const unsigned char *ctr, + void *result) +{ + gcry_cipher_hd_t handle; + int rc; + + GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_CTR, 0)); + rc = gcry_cipher_setkey (handle, + key, + GNUNET_CRYPTO_AES_KEY_LENGTH); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + rc = gcry_cipher_setctr (handle, + ctr, + GNUNET_CRYPTO_AES_KEY_LENGTH / 2); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + GNUNET_assert (0 == gcry_cipher_decrypt (handle, result, size, block, size)); + gcry_cipher_close (handle); + return size; +} + + + +ssize_t +ecdsa_symmetric_encrypt ( + const void *block, + size_t size, + const unsigned char *key, + const unsigned char *ctr, + void *result) +{ + gcry_cipher_hd_t handle; + int rc; + + GNUNET_assert (0 == gcry_cipher_open (&handle, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_CTR, 0)); + rc = gcry_cipher_setkey (handle, + key, + GNUNET_CRYPTO_AES_KEY_LENGTH); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + rc = gcry_cipher_setctr (handle, + ctr, + GNUNET_CRYPTO_AES_KEY_LENGTH / 2); + GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); + GNUNET_assert (0 == gcry_cipher_encrypt (handle, result, size, block, size)); + gcry_cipher_close (handle); + return size; +} + + /** * Derive session key and iv from label and public key. @@ -47,25 +102,31 @@ * @param pub public key to use for KDF */ static void -derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, - struct GNUNET_CRYPTO_SymmetricSessionKey *skey, +derive_block_aes_key (unsigned char *ctr, + unsigned char *key, const char *label, + uint64_t exp, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) { static const char ctx_key[] = "gns-aes-ctx-key"; static const char ctx_iv[] = "gns-aes-ctx-iv"; - GNUNET_CRYPTO_kdf (skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), + GNUNET_CRYPTO_kdf (key, GNUNET_CRYPTO_AES_KEY_LENGTH, ctx_key, strlen (ctx_key), pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), label, strlen (label), NULL, 0); - GNUNET_CRYPTO_kdf (iv, sizeof(struct - GNUNET_CRYPTO_SymmetricInitializationVector), + memset (ctr, 0, GNUNET_CRYPTO_AES_KEY_LENGTH / 2); + /** 4 byte nonce **/ + GNUNET_CRYPTO_kdf (ctr, 4, ctx_iv, strlen (ctx_iv), pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), label, strlen (label), NULL, 0); + /** Expiration time 64 bit. **/ + memcpy (ctr + 4, &exp, sizeof (exp)); + /** Set counter part to 1 **/ + ctr[15] |= 0x01; } @@ -81,19 +142,20 @@ derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, * @return NULL on error (block too large) */ static struct GNUNET_GNSRECORD_Block * -block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, - struct GNUNET_TIME_Absolute expire, - const char *label, - const struct GNUNET_GNSRECORD_Data *rd, - unsigned int rd_count) +block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, + struct GNUNET_TIME_Absolute expire, + const char *label, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count) { ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); struct GNUNET_GNSRECORD_Block *block; + struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_CRYPTO_SymmetricSessionKey skey; + unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; + unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; uint32_t rd_count_nbo; struct GNUNET_TIME_Absolute now; @@ -140,35 +202,38 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) + sizeof(uint32_t) + payload_len); - block->purpose.size = htonl (sizeof(uint32_t) - + payload_len - + sizeof(struct - GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_TIME_AbsoluteNBO)); - block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); - block->expiration_time = GNUNET_TIME_absolute_hton (expire); + ecblock = &block->ecdsa_block; + block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + ecblock->purpose.size = htonl (sizeof(uint32_t) + + payload_len + + sizeof(struct + GNUNET_CRYPTO_EccSignaturePurpose) + + sizeof(struct GNUNET_TIME_AbsoluteNBO)); + ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire); /* encrypt and sign */ dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, label, "gns"); GNUNET_CRYPTO_ecdsa_key_get_public (dkey, - &block->derived_key); - derive_block_aes_key (&iv, - &skey, + &ecblock->derived_key); + derive_block_aes_key (ctr, + skey, label, + ecblock->expiration_time.abs_value_us__, pkey); GNUNET_break (payload_len + sizeof(uint32_t) == - GNUNET_CRYPTO_symmetric_encrypt (payload, - payload_len - + sizeof(uint32_t), - &skey, - &iv, - &block[1])); + ecdsa_symmetric_encrypt (payload, + payload_len + + sizeof(uint32_t), + skey, + ctr, + &ecblock[1])); } if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign_ (dkey, - &block->purpose, - &block->signature)) + &ecblock->purpose, + &ecblock->signature)) { GNUNET_break (0); GNUNET_free (dkey); @@ -191,7 +256,7 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, * @return NULL on error (block too large) */ struct GNUNET_GNSRECORD_Block * -GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, @@ -199,14 +264,21 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, { struct GNUNET_CRYPTO_EcdsaPublicKey pkey; - GNUNET_CRYPTO_ecdsa_key_get_public (key, - &pkey); - return block_create (key, - &pkey, - expire, - label, - rd, - rd_count); + switch (ntohl (key->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + GNUNET_CRYPTO_ecdsa_key_get_public (&key->ecdsa_key, + &pkey); + return block_create_ecdsa (&key->ecdsa_key, + &pkey, + expire, + label, + rd, + rd_count); + default: + GNUNET_assert (0); + } + return NULL; } @@ -240,12 +312,19 @@ struct KeyCacheLine * @return NULL on error (block too large) */ struct GNUNET_GNSRECORD_Block * -GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count) { + const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; + + if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (pkey->type)) + { + return NULL; // FIXME + } + key = &pkey->ecdsa_key; #define CSIZE 64 static struct KeyCacheLine cache[CSIZE]; struct KeyCacheLine *line; @@ -261,12 +340,12 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, &line->pkey); } #undef CSIZE - return block_create (key, - &line->pkey, - expire, - label, - rd, - rd_count); + return block_create_ecdsa (key, + &line->pkey, + expire, + label, + rd, + rd_count); } @@ -277,40 +356,40 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, * @param block block to verify * @return #GNUNET_OK if the signature is valid */ -int +enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) { + const struct GNUNET_CRYPTO_EcdsaPublicKey *key; + const struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; + + if (GNUNET_GNSRECORD_TYPE_PKEY != ntohl (block->type)) + { + GNUNET_break (0); + return GNUNET_NO; + } + ecblock = &block->ecdsa_block; + key = &ecblock->derived_key; + return GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, - &block->purpose, - &block->signature, - &block->derived_key); + &ecblock->purpose, + &ecblock->signature, + key); } -/** - * Decrypt block. - * - * @param block block to decrypt - * @param zone_key public key of the zone - * @param label the name for the records - * @param proc function to call with the result - * @param proc_cls closure for proc - * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was - * not well-formed - */ -int -GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, - const struct - GNUNET_CRYPTO_EcdsaPublicKey *zone_key, - const char *label, - GNUNET_GNSRECORD_RecordCallback proc, - void *proc_cls) +enum GNUNET_GenericReturnValue +block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block, + const struct + GNUNET_CRYPTO_EcdsaPublicKey *zone_key, + const char *label, + GNUNET_GNSRECORD_RecordCallback proc, + void *proc_cls) { size_t payload_len = ntohl (block->purpose.size) - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - sizeof(struct GNUNET_TIME_AbsoluteNBO); - struct GNUNET_CRYPTO_SymmetricInitializationVector iv; - struct GNUNET_CRYPTO_SymmetricSessionKey skey; + unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; + unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH]; if (ntohl (block->purpose.size) < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) @@ -319,18 +398,19 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, GNUNET_break_op (0); return GNUNET_SYSERR; } - derive_block_aes_key (&iv, - &skey, + derive_block_aes_key (ctr, + key, label, + block->expiration_time.abs_value_us__, zone_key); { char payload[payload_len]; uint32_t rd_count; GNUNET_break (payload_len == - GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, - &skey, &iv, - payload)); + ecdsa_symmetric_decrypt (&block[1], payload_len, + key, ctr, + payload)); GNUNET_memcpy (&rd_count, payload, sizeof(uint32_t)); @@ -425,6 +505,39 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, } +/** + * Decrypt block. + * + * @param block block to decrypt + * @param zone_key public key of the zone + * @param label the name for the records + * @param proc function to call with the result + * @param proc_cls closure for proc + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was + * not well-formed + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, + const struct + GNUNET_IDENTITY_PublicKey *zone_key, + const char *label, + GNUNET_GNSRECORD_RecordCallback proc, + void *proc_cls) +{ + const struct GNUNET_CRYPTO_EcdsaPublicKey *key; + + if (GNUNET_IDENTITY_TYPE_ECDSA != ntohl (zone_key->type)) + { + return GNUNET_NO; + } + key = &zone_key->ecdsa_key; + + return block_decrypt_ecdsa (&block->ecdsa_block, + key, label, proc, proc_cls); + +} + + /** * Calculate the DHT query for a given @a label in a given @a zone. * @@ -434,17 +547,24 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, */ void GNUNET_GNSRECORD_query_from_private_key (const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, const char *label, struct GNUNET_HashCode *query) { - struct GNUNET_CRYPTO_EcdsaPublicKey pub; - - GNUNET_CRYPTO_ecdsa_key_get_public (zone, - &pub); - GNUNET_GNSRECORD_query_from_public_key (&pub, - label, - query); + struct GNUNET_IDENTITY_PublicKey pub; + switch (ntohl (zone->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + + GNUNET_IDENTITY_key_get_public (zone, + &pub); + GNUNET_GNSRECORD_query_from_public_key (&pub, + label, + query); + break; + default: + GNUNET_assert (0); + } } @@ -457,18 +577,27 @@ GNUNET_GNSRECORD_query_from_private_key (const struct */ void GNUNET_GNSRECORD_query_from_public_key (const struct - GNUNET_CRYPTO_EcdsaPublicKey *pub, + GNUNET_IDENTITY_PublicKey *pub, const char *label, struct GNUNET_HashCode *query) { - struct GNUNET_CRYPTO_EcdsaPublicKey pd; - GNUNET_CRYPTO_ecdsa_public_key_derive (pub, - label, - "gns", - &pd); - GNUNET_CRYPTO_hash (&pd, - sizeof(pd), - query); + struct GNUNET_IDENTITY_PublicKey pd; + + switch (ntohl (pub->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + pd.type = pub->type; + GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key, + label, + "gns", + &pd.ecdsa_key); + GNUNET_CRYPTO_hash (&pd.ecdsa_key, + sizeof (pd.ecdsa_key), + query); + break; + default: + GNUNET_assert (0); + } } diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c index 5061f8493..82c38f19a 100644 --- a/src/gnsrecord/gnsrecord_misc.c +++ b/src/gnsrecord/gnsrecord_misc.c @@ -62,14 +62,14 @@ GNUNET_GNSRECORD_string_to_lowercase (const char *src) * @return string form; will be overwritten by next call to #GNUNET_GNSRECORD_z2s */ const char * -GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z) +GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z) { - static char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) * 8]; + static char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) * 8]; char *end; end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey), + GNUNET_IDENTITY_PublicKey), buf, sizeof(buf)); if (NULL == end) { @@ -99,7 +99,7 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, if (a->record_type != b->record_type) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Record type %lu != %lu\n", a->record_type, b->record_type); + "Record type %u != %u\n", a->record_type, b->record_type); return GNUNET_NO; } if ((a->expiration_time != b->expiration_time) && @@ -107,15 +107,15 @@ GNUNET_GNSRECORD_records_cmp (const struct GNUNET_GNSRECORD_Data *a, { LOG (GNUNET_ERROR_TYPE_DEBUG, "Expiration time %llu != %llu\n", - a->expiration_time, - b->expiration_time); + (unsigned long long) a->expiration_time, + (unsigned long long) b->expiration_time); return GNUNET_NO; } if ((a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS) != (b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS)) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Flags %lu (%lu) != %lu (%lu)\n", a->flags, + "Flags %u (%u) != %u (%u)\n", a->flags, a->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS, b->flags, b->flags & GNUNET_GNSRECORD_RF_RCMP_FLAGS); return GNUNET_NO; @@ -236,12 +236,12 @@ GNUNET_GNSRECORD_is_expired (const struct GNUNET_GNSRECORD_Data *rd) * key in an encoding suitable for DNS labels. */ const char * -GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) +GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey) { static char ret[128]; char *pkeys; - pkeys = GNUNET_CRYPTO_ecdsa_public_key_to_string (pkey); + pkeys = GNUNET_IDENTITY_public_key_to_string (pkey); GNUNET_snprintf (ret, sizeof(ret), "%s", @@ -262,15 +262,140 @@ GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) */ int GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, - struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) + struct GNUNET_IDENTITY_PublicKey *pkey) { if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (zkey, - strlen (zkey), - pkey)) + GNUNET_IDENTITY_public_key_from_string (zkey, + pkey)) return GNUNET_SYSERR; return GNUNET_OK; } +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_identity_from_data (const char *data, + size_t data_size, + uint32_t type, + struct GNUNET_IDENTITY_PublicKey *key) +{ + if (GNUNET_NO == GNUNET_GNSRECORD_is_zonekey_type (type)) + return GNUNET_SYSERR; + if (data_size > sizeof (struct GNUNET_IDENTITY_PublicKey)) + return GNUNET_SYSERR; + return (GNUNET_IDENTITY_read_key_from_buffer (key, data, data_size) == + data_size? + GNUNET_OK : + GNUNET_SYSERR); +} + + +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_data_from_identity (const struct + GNUNET_IDENTITY_PublicKey *key, + char **data, + size_t *data_size, + uint32_t *type) +{ + *type = ntohl (key->type); + *data_size = GNUNET_IDENTITY_key_get_length (key); + if (0 == *data_size) + return GNUNET_SYSERR; + *data = GNUNET_malloc (*data_size); + return (GNUNET_IDENTITY_write_key_to_buffer (key, *data, *data_size) == + *data_size? + GNUNET_OK : + GNUNET_SYSERR); +} + + +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_is_zonekey_type (uint32_t type) +{ + switch (type) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: + return GNUNET_YES; + default: + return GNUNET_NO; + } +} + + +size_t +GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block) +{ + switch (ntohl (block->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + return sizeof (uint32_t) /* zone type */ + + sizeof (block->ecdsa_block) /* EcdsaBlock */ + + ntohl (block->ecdsa_block.purpose.size) /* Length of signed data */ + - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */ + break; + default: + return 0; + } + return 0; +} + + +struct GNUNET_TIME_Absolute +GNUNET_GNSRECORD_block_get_expiration (const struct + GNUNET_GNSRECORD_Block *block) +{ + + switch (ntohl (block->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + return GNUNET_TIME_absolute_ntoh (block->ecdsa_block.expiration_time); + default: + return GNUNET_TIME_absolute_get_zero_ (); + } + return GNUNET_TIME_absolute_get_zero_ (); + +} + + +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block, + struct GNUNET_HashCode *query) +{ + switch (ntohl (block->type)) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + GNUNET_CRYPTO_hash (&block->ecdsa_block.derived_key, + sizeof (block->ecdsa_block.derived_key), + query); + return GNUNET_OK; + default: + return GNUNET_SYSERR; + } + return GNUNET_SYSERR; + +} + + +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd, + struct GNUNET_IDENTITY_PublicKey *key) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got record of type %u\n", + rd->record_type); + switch (rd->record_type) + { + case GNUNET_GNSRECORD_TYPE_PKEY: + key->type = htonl (rd->record_type); + memcpy (&key->ecdsa_key, rd->data, sizeof (key->ecdsa_key)); + return GNUNET_OK; + default: + return GNUNET_SYSERR; + } + return GNUNET_SYSERR; + + +} + + /* end of gnsrecord_misc.c */ diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c index 789ff8aa3..47b13bdab 100644 --- a/src/gnsrecord/gnunet-gnsrecord-tvg.c +++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c @@ -90,28 +90,38 @@ run (void *cls, struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get (); struct GNUNET_GNSRECORD_Block *rrblock; char *bdata; - struct GNUNET_CRYPTO_EcdsaPrivateKey id_priv; - struct GNUNET_CRYPTO_EcdsaPublicKey id_pub; - struct GNUNET_CRYPTO_EcdsaPrivateKey pkey_data_p; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey_data; + struct GNUNET_IDENTITY_PrivateKey id_priv; + struct GNUNET_IDENTITY_PublicKey id_pub; + struct GNUNET_IDENTITY_PrivateKey pkey_data_p; + struct GNUNET_IDENTITY_PublicKey pkey_data; void *data; size_t data_size; char *rdata; size_t rdata_size; - - GNUNET_CRYPTO_ecdsa_key_create (&id_priv); - GNUNET_CRYPTO_ecdsa_key_get_public (&id_priv, - &id_pub); - fprintf (stdout, "Zone private key (d, little-endian scalar):\n"); - print_bytes (&id_priv, sizeof(id_priv), 0); + char ztld[128]; + + id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&id_priv, + &id_pub); + fprintf (stdout, "Zone private key (d, little-endian, with ztype prepended):\n"); + print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 8); //FIXME length for privkey? + fprintf (stdout, "\n"); + fprintf (stdout, "Zone identifier (zid):\n"); + print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); + GNUNET_STRINGS_data_to_string (&id_pub, + GNUNET_IDENTITY_key_get_length (&id_pub), + ztld, + sizeof (ztld)); fprintf (stdout, "\n"); - fprintf (stdout, "Zone public key (zk):\n"); - print_bytes (&id_pub, sizeof(id_pub), 0); + fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n"); + fprintf (stdout, "%s\n", ztld); fprintf (stdout, "\n"); - GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p); - GNUNET_CRYPTO_ecdsa_key_get_public (&pkey_data_p, - &pkey_data); + pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&pkey_data_p, + &pkey_data); fprintf (stdout, "Label: %s\nRRCOUNT: %d\n\n", TEST_RECORD_LABEL, TEST_RRCOUNT); memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * 2); @@ -147,19 +157,20 @@ run (void *cls, TEST_RECORD_LABEL, rd, TEST_RRCOUNT); - size_t bdata_size = ntohl (rrblock->purpose.size) + size_t bdata_size = ntohl (rrblock->ecdsa_block.purpose.size) - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - sizeof(struct GNUNET_TIME_AbsoluteNBO); - size_t rrblock_size = ntohl (rrblock->purpose.size) + size_t ecblock_size = ntohl (rrblock->ecdsa_block.purpose.size) + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); + size_t block_size = ecblock_size + sizeof (uint32_t); - bdata = (char*) &rrblock[1]; + bdata = (char*) &(&rrblock->ecdsa_block)[1]; fprintf (stdout, "BDATA:\n"); print_bytes (bdata, bdata_size, 8); fprintf (stdout, "\n"); fprintf (stdout, "RRBLOCK:\n"); - print_bytes (rrblock, rrblock_size, 8); + print_bytes (rrblock, block_size, 8); fprintf (stdout, "\n"); } diff --git a/src/gnsrecord/json_gnsrecord.c b/src/gnsrecord/json_gnsrecord.c new file mode 100644 index 000000000..068ff48c1 --- /dev/null +++ b/src/gnsrecord/json_gnsrecord.c @@ -0,0 +1,391 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @file json/json_gnsrecord.c + * @brief JSON handling of GNS record data + * @author Philippe Buschmann + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_json_lib.h" +#include "gnunet_gnsrecord_lib.h" + +#define GNUNET_JSON_GNSRECORD_VALUE "value" +#define GNUNET_JSON_GNSRECORD_RECORD_DATA "data" +#define GNUNET_JSON_GNSRECORD_TYPE "record_type" +#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time" +#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE "private" +#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL "supplemental" +#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE "relative_expiration" +#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW "shadow" +#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name" +#define GNUNET_JSON_GNSRECORD_NEVER "never" + +struct GnsRecordInfo +{ + char **name; + + unsigned int *rd_count; + + struct GNUNET_GNSRECORD_Data **rd; +}; + + +static void +cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info) +{ + char *tmp; + + if (NULL != *(gnsrecord_info->rd)) + { + for (int i = 0; i < *(gnsrecord_info->rd_count); i++) + { + tmp = (char*) (*(gnsrecord_info->rd))[i].data; + if (NULL != tmp) + GNUNET_free (tmp); + } + GNUNET_free (*(gnsrecord_info->rd)); + *(gnsrecord_info->rd) = NULL; + } + if (NULL != *(gnsrecord_info->name)) + GNUNET_free (*(gnsrecord_info->name)); + *(gnsrecord_info->name) = NULL; +} + + +/** + * Parse given JSON object to gns record + * + * @param cls closure, NULL + * @param root the json object representing data + * @param spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_record (json_t *data, struct GNUNET_GNSRECORD_Data *rd) +{ + struct GNUNET_TIME_Absolute abs_expiration_time; + struct GNUNET_TIME_Relative rel_expiration_time; + const char *value; + const char *record_type; + const char *expiration_time; + int private; + int supplemental; + int rel_exp; + int shadow; + int unpack_state = 0; + + // interpret single gns record + unpack_state = json_unpack (data, + "{s:s, s:s, s:s, s:b, s:b, s:b, s:b}", + GNUNET_JSON_GNSRECORD_VALUE, + &value, + GNUNET_JSON_GNSRECORD_TYPE, + &record_type, + GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, + &expiration_time, + GNUNET_JSON_GNSRECORD_FLAG_PRIVATE, + &private, + GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL, + &supplemental, + GNUNET_JSON_GNSRECORD_FLAG_RELATIVE, + &rel_exp, + GNUNET_JSON_GNSRECORD_FLAG_SHADOW, + &shadow); + if (0 != unpack_state) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error gnsdata object has a wrong format!\n"); + return GNUNET_SYSERR; + } + rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type); + if (UINT32_MAX == rd->record_type) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n"); + return GNUNET_SYSERR; + } + if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type, + value, + (void **) &rd->data, + &rd->data_size)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n"); + return GNUNET_SYSERR; + } + + if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER)) + { + rd->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; + } + else if ((1 != rel_exp) && + (GNUNET_OK == + GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, + &abs_expiration_time))) + { + rd->expiration_time = abs_expiration_time.abs_value_us; + } + else if (GNUNET_OK == + GNUNET_STRINGS_fancy_time_to_relative (expiration_time, + &rel_expiration_time)) + { + rd->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; + rd->expiration_time = rel_expiration_time.rel_value_us; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration time invalid\n"); + return GNUNET_SYSERR; + } + if (1 == private) + rd->flags |= GNUNET_GNSRECORD_RF_PRIVATE; + if (1 == supplemental) + rd->flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL; + if (1 == shadow) + rd->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; + return GNUNET_OK; +} + + +/** + * Parse given JSON object to gns record + * + * @param cls closure, NULL + * @param root the json object representing data + * @param spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data) +{ + GNUNET_assert (NULL != data); + if (! json_is_array (data)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error gns record data JSON is not an array!\n"); + return GNUNET_SYSERR; + } + *(gnsrecord_info->rd_count) = json_array_size (data); + *(gnsrecord_info->rd) = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Data) + * json_array_size (data)); + size_t index; + json_t *value; + json_array_foreach (data, index, value) + { + if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index])) + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +static int +parse_gnsrecordobject (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GnsRecordInfo *gnsrecord_info; + int unpack_state = 0; + const char *name; + json_t *data; + + GNUNET_assert (NULL != root); + if (! json_is_object (root)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error record JSON is not an object!\n"); + return GNUNET_SYSERR; + } + // interpret single gns record + unpack_state = json_unpack (root, + "{s:s, s:o!}", + GNUNET_JSON_GNSRECORD_RECORD_NAME, + &name, + GNUNET_JSON_GNSRECORD_RECORD_DATA, + &data); + if (0 != unpack_state) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error namestore records object has a wrong format!\n"); + return GNUNET_SYSERR; + } + gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; + *(gnsrecord_info->name) = GNUNET_strdup (name); + if (GNUNET_OK != parse_record_data (gnsrecord_info, data)) + { + cleanup_recordinfo (gnsrecord_info); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Cleanup data left from parsing the record. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) +{ + struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; + + GNUNET_free (gnsrecord_info); +} + + +/** + * JSON Specification for GNS Records. + * + * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_GNSRECORD_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, + unsigned int *rd_count, + char **name) +{ + struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo); + + gnsrecord_info->rd = rd; + gnsrecord_info->name = name; + gnsrecord_info->rd_count = rd_count; + struct GNUNET_JSON_Specification ret = { .parser = &parse_gnsrecordobject, + .cleaner = &clean_gnsrecordobject, + .cls = NULL, + .field = NULL, + .ptr = (struct GnsRecordInfo *) + gnsrecord_info, + .ptr_size = 0, + .size_ptr = NULL }; + return ret; +} + + +/** + * Convert GNS record to JSON. + * + * @param rname name of record + * @param rd record data + * @return corresponding JSON encoding + */ +json_t * +GNUNET_GNSRECORD_JSON_from_gnsrecord (const char*rname, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count) +{ + struct GNUNET_TIME_Absolute abs_exp; + struct GNUNET_TIME_Relative rel_exp; + const char *expiration_time_str; + const char *record_type_str; + char *value_str; + json_t *data; + json_t *record; + json_t *records; + + data = json_object (); + if (NULL == data) + { + GNUNET_break (0); + return NULL; + } + if (0 != + json_object_set_new (data, + "record_name", + json_string (rname))) + { + GNUNET_break (0); + json_decref (data); + return NULL; + } + records = json_array (); + if (NULL == records) + { + GNUNET_break (0); + json_decref (data); + return NULL; + } + for (int i = 0; i < rd_count; i++) + { + value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, + rd[i].data, + rd[i].data_size); + if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd[i].flags) + { + rel_exp.rel_value_us = rd[i].expiration_time; + expiration_time_str = GNUNET_STRINGS_relative_time_to_string (rel_exp, + GNUNET_NO); + } + else + { + abs_exp.abs_value_us = rd[i].expiration_time; + expiration_time_str = GNUNET_STRINGS_absolute_time_to_string (abs_exp); + } + record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Packing %s %s %s %d\n", + value_str, record_type_str, expiration_time_str, rd[i].flags); + record = json_pack ("{s:s,s:s,s:s,s:b,s:b,s:b,s:b}", + "value", + value_str, + "record_type", + record_type_str, + "expiration_time", + expiration_time_str, + "private", + rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE, + "relative_expiration", + rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, + "supplemental", + rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL, + "shadow", + rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD); + GNUNET_free (value_str); + if (NULL == record) + { + GNUNET_break (0); + json_decref (records); + json_decref (data); + return NULL; + } + if (0 != + json_array_append_new (records, + record)) + { + GNUNET_break (0); + json_decref (records); + json_decref (data); + return NULL; + } + } + if (0 != + json_object_set_new (data, + "data", + records)) + { + GNUNET_break (0); + json_decref (data); + return NULL; + } + return data; +} + + diff --git a/src/gnsrecord/perf_gnsrecord_crypto.c b/src/gnsrecord/perf_gnsrecord_crypto.c index eb4633f75..d9a3c20cf 100644 --- a/src/gnsrecord/perf_gnsrecord_crypto.c +++ b/src/gnsrecord/perf_gnsrecord_crypto.c @@ -73,7 +73,7 @@ run (void *cls, struct GNUNET_GNSRECORD_Data *s_rd; const char *s_name; struct GNUNET_TIME_Absolute start_time; - struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; + struct GNUNET_IDENTITY_PrivateKey privkey; struct GNUNET_TIME_Absolute expire; (void) cls; @@ -81,7 +81,8 @@ run (void *cls, (void) cfgfile; (void) cfg; expire = GNUNET_TIME_absolute_get (); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); /* test block creation */ s_name = "DUMMY.dummy.gnunet"; diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c index 9ac6fb9e6..bde9944e2 100644 --- a/src/gnsrecord/plugin_gnsrecord_dns.c +++ b/src/gnsrecord/plugin_gnsrecord_dns.c @@ -100,7 +100,7 @@ dns_value_to_string (void *cls, return NULL; } GNUNET_asprintf (&result, - "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", + "rname=%s mname=%s %u,%u,%u,%u,%u", soa->rname, soa->mname, soa->serial, diff --git a/src/gnsrecord/test_gnsrecord_crypto.c b/src/gnsrecord/test_gnsrecord_crypto.c index b67e9a123..d541f3076 100644 --- a/src/gnsrecord/test_gnsrecord_crypto.c +++ b/src/gnsrecord/test_gnsrecord_crypto.c @@ -100,17 +100,18 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_GNSRECORD_Block *block; - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; + struct GNUNET_IDENTITY_PublicKey pubkey; struct GNUNET_HashCode query_pub; struct GNUNET_HashCode query_priv; struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get (); - struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; + struct GNUNET_IDENTITY_PrivateKey privkey; - GNUNET_CRYPTO_ecdsa_key_create (&privkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); /* get public key */ - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); /* test query derivation */ GNUNET_GNSRECORD_query_from_private_key (&privkey, diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c index d0f5546f3..a01cd1ed7 100644 --- a/src/identity/gnunet-identity.c +++ b/src/identity/gnunet-identity.c @@ -65,6 +65,11 @@ static unsigned int verbose; */ static int quiet; +/** + * Was "eddsa" specified? + */ +static int type_eddsa; + /** * -C option */ @@ -108,7 +113,7 @@ static struct GNUNET_IDENTITY_Operation *delete_op; /** * Private key from command line option, or NULL. */ -struct GNUNET_CRYPTO_EcdsaPrivateKey pk; +struct GNUNET_IDENTITY_PrivateKey pk; /** * Value to return from #main(). @@ -197,7 +202,7 @@ delete_finished (void *cls, */ static void create_finished (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { struct GNUNET_IDENTITY_Operation **op = cls; @@ -212,16 +217,16 @@ create_finished (void *cls, } else if (verbose) { - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; char *pubs; - GNUNET_CRYPTO_ecdsa_key_get_public (pk, &pub); - pubs = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pub); + GNUNET_IDENTITY_key_get_public (pk, &pub); + pubs = GNUNET_IDENTITY_public_key_to_string (&pub); if (private_keys) { char *privs; - privs = GNUNET_CRYPTO_ecdsa_private_key_to_string (pk); + privs = GNUNET_IDENTITY_private_key_to_string (pk); fprintf (stdout, "%s - %s\n", pubs, privs); GNUNET_free (privs); } @@ -293,7 +298,7 @@ print_ego (void *cls, void **ctx, const char *identifier) { - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; char *s; char *privs; @@ -342,8 +347,8 @@ print_ego (void *cls, set_ego)) ) return; GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); - privs = GNUNET_CRYPTO_ecdsa_private_key_to_string ( + s = GNUNET_IDENTITY_public_key_to_string (&pk); + privs = GNUNET_IDENTITY_private_key_to_string ( GNUNET_IDENTITY_ego_get_private_key (ego)); if ((monitor) || (NULL != identifier)) { @@ -357,9 +362,16 @@ print_ego (void *cls, else { if (private_keys) - fprintf (stdout, "%s - %s - %s\n", identifier, s, privs); + fprintf (stdout, "%s - %s - %s - %s\n", + identifier, s, privs, + (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ? + "ECDSA" : "EdDSA"); else - fprintf (stdout, "%s - %s\n", identifier, s); + fprintf (stdout, "%s - %s - %s\n", + identifier, s, + (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ? + "ECDSA" : "EdDSA"); + } } GNUNET_free (privs); @@ -407,11 +419,12 @@ run (void *cls, strlen (privkey_ego), &pk, sizeof(struct - GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_IDENTITY_PrivateKey)); create_op = GNUNET_IDENTITY_create (sh, create_ego, &pk, + 0, // Ignored &create_finished, &create_op); } @@ -420,6 +433,9 @@ run (void *cls, GNUNET_IDENTITY_create (sh, create_ego, NULL, + (type_eddsa) ? + GNUNET_IDENTITY_TYPE_EDDSA : + GNUNET_IDENTITY_TYPE_ECDSA, &create_finished, &create_op); } @@ -456,6 +472,11 @@ main (int argc, char *const *argv) gettext_noop ( "set the private key for the identity to PRIVATE_KEY (use together with -C)"), &privkey_ego), + GNUNET_GETOPT_option_flag ('X', + "eddsa", + gettext_noop ( + "generate an EdDSA identity. (use together with -C) EXPERIMENTAL"), + &type_eddsa), GNUNET_GETOPT_option_flag ('d', "display", gettext_noop ("display all egos"), diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c index bdacf3ba0..6cdb1c2f7 100644 --- a/src/identity/gnunet-service-identity.c +++ b/src/identity/gnunet-service-identity.c @@ -57,7 +57,7 @@ struct Ego /** * Private key of the ego. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey pk; + struct GNUNET_IDENTITY_PrivateKey pk; /** * String identifier for the ego. @@ -538,8 +538,8 @@ handle_get_default_message (void *cls, * @return 0 if the keys are equal */ static int -key_cmp (const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk1, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2) +key_cmp (const struct GNUNET_IDENTITY_PrivateKey *pk1, + const struct GNUNET_IDENTITY_PrivateKey *pk2) { return GNUNET_memcmp (pk1, pk2); } @@ -738,10 +738,10 @@ handle_create_message (void *cls, send_result_code (client, 0, NULL); fn = get_ego_filename (ego); (void) GNUNET_DISK_directory_create_for_file (fn); - if (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey) != + if (sizeof(struct GNUNET_IDENTITY_PrivateKey) != GNUNET_DISK_fn_write (fn, &crm->private_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey), + sizeof(struct GNUNET_IDENTITY_PrivateKey), GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); @@ -1038,6 +1038,67 @@ handle_delete_message (void *cls, const struct DeleteMessage *dm) } +static int +read_from_file (const char *filename, + void *buf, + size_t buf_size) +{ + int fd; + struct stat sb; + + fd = open (filename, + O_RDONLY); + if (-1 == fd) + { + memset (buf, + 0, + buf_size); + return GNUNET_SYSERR; + } + if (0 != fstat (fd, + &sb)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "stat", + filename); + GNUNET_assert (0 == close (fd)); + memset (buf, + 0, + buf_size); + return GNUNET_SYSERR; + } + if (sb.st_size != buf_size) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "File `%s' has wrong size (%llu), expected %llu bytes\n", + filename, + (unsigned long long) sb.st_size, + (unsigned long long) buf_size); + GNUNET_assert (0 == close (fd)); + memset (buf, + 0, + buf_size); + return GNUNET_SYSERR; + } + if (buf_size != + read (fd, + buf, + buf_size)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "read", + filename); + GNUNET_assert (0 == close (fd)); + memset (buf, + 0, + buf_size); + return GNUNET_SYSERR; + } + GNUNET_assert (0 == close (fd)); + return GNUNET_OK; +} + + /** * Process the given file from the "EGODIR". Parses the file * and creates the respective 'struct Ego' in memory. @@ -1063,9 +1124,9 @@ process_ego_file (void *cls, } ego = GNUNET_new (struct Ego); if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_key_from_file (filename, - GNUNET_NO, - &ego->pk)) + read_from_file (filename, + &ego->pk, + sizeof (ego->pk))) { GNUNET_free (ego); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, diff --git a/src/identity/identity.h b/src/identity/identity.h index ef638fa36..11c5883bc 100644 --- a/src/identity/identity.h +++ b/src/identity/identity.h @@ -30,6 +30,44 @@ #include "gnunet_common.h" +/** + * Handle for an ego. + */ +struct GNUNET_IDENTITY_Ego +{ + /** + * Hash of the private key of this ego. + */ + struct GNUNET_HashCode id; + + /** + * The identity key pair + */ + struct GNUNET_IDENTITY_PublicKey pub; + + /** + * The identity key pair + */ + struct GNUNET_IDENTITY_PrivateKey pk; + + /** + * Current name associated with this ego. + */ + char *name; + + /** + * Client context associated with this ego. + */ + void *ctx; + + /** + * Set to true once @e pub was initialized + */ + bool pub_initialized; +}; + + + GNUNET_NETWORK_STRUCT_BEGIN @@ -95,7 +133,7 @@ struct UpdateMessage /** * The private key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by 0-terminated ego name */ }; @@ -151,7 +189,7 @@ struct SetDefaultMessage /** * The private key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by 0-terminated service name */ }; @@ -181,7 +219,7 @@ struct CreateRequestMessage /** * The private key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by 0-terminated identity name */ }; @@ -239,42 +277,5 @@ struct DeleteMessage GNUNET_NETWORK_STRUCT_END -/** - * Handle for an ego. - */ -struct GNUNET_IDENTITY_Ego -{ - /** - * Hash of the private key of this ego. - */ - struct GNUNET_HashCode id; - - /** - * Private key associated with this ego. - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey pk; - - /** - * Public key associated with this ego. Initialized on demand. - * Always use #GNUNET_IDENTITY_ego_get_public_key() to obtain. - */ - struct GNUNET_CRYPTO_EcdsaPublicKey pub; - - /** - * Current name associated with this ego. - */ - char *name; - - /** - * Client context associated with this ego. - */ - void *ctx; - - /** - * Set to true once @e pub was initialized - */ - bool pub_initialized; -}; - #endif diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c index f7aca1655..64c088923 100644 --- a/src/identity/identity_api.c +++ b/src/identity/identity_api.c @@ -74,7 +74,7 @@ struct GNUNET_IDENTITY_Operation /** * Private key to return to @e create_cont, or NULL. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey pk; + struct GNUNET_IDENTITY_PrivateKey pk; /** * Continuation to invoke with the result of the transmission for @@ -157,13 +157,12 @@ GNUNET_IDENTITY_ego_get_anonymous () { static struct GNUNET_IDENTITY_Ego anon; static int setup; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; if (setup) return &anon; - anon.pk = *GNUNET_CRYPTO_ecdsa_key_get_anonymous (); - GNUNET_CRYPTO_ecdsa_key_get_public (&anon.pk, - &pub); + anon.pk.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA); + anon.pub.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA); + anon.pk.ecdsa_key = *GNUNET_CRYPTO_ecdsa_key_get_anonymous (); GNUNET_CRYPTO_hash (&anon.pk, sizeof(anon.pk), &anon.id); @@ -172,6 +171,51 @@ GNUNET_IDENTITY_ego_get_anonymous () } +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_key_get_public (const struct + GNUNET_IDENTITY_PrivateKey *privkey, + struct GNUNET_IDENTITY_PublicKey *key) +{ + key->type = privkey->type; + switch (ntohl (privkey->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + GNUNET_CRYPTO_ecdsa_key_get_public (&privkey->ecdsa_key, + &key->ecdsa_key); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + GNUNET_CRYPTO_eddsa_key_get_public (&privkey->eddsa_key, + &key->eddsa_key); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +static int +private_key_create (enum GNUNET_IDENTITY_KeyType ktype, + struct GNUNET_IDENTITY_PrivateKey *key) +{ + key->type = htonl (ktype); + switch (ktype) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + GNUNET_CRYPTO_ecdsa_key_create (&key->ecdsa_key); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + GNUNET_CRYPTO_eddsa_key_create (&key->eddsa_key); + break; + default: + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + /** * Try again to connect to the identity service. * @@ -591,7 +635,7 @@ GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param ego the ego * @return associated ECC key, valid as long as the ego is valid */ -const struct GNUNET_CRYPTO_EcdsaPrivateKey * +const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego) { return &ego->pk; @@ -606,12 +650,11 @@ GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego) */ void GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, - struct GNUNET_CRYPTO_EcdsaPublicKey *pk) + struct GNUNET_IDENTITY_PublicKey *pk) { if (GNUNET_NO == ego->pub_initialized) { - GNUNET_CRYPTO_ecdsa_key_get_public (&ego->pk, - &ego->pub); + GNUNET_IDENTITY_key_get_public (&ego->pk, &ego->pub); ego->pub_initialized = GNUNET_YES; } *pk = ego->pub; @@ -710,20 +753,11 @@ GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *h, } -/** - * Create a new identity with the given name. - * - * @param h identity service to use - * @param name desired name - * @param privkey desired private key or NULL to create one - * @param cont function to call with the result (will only be called once) - * @param cont_cls closure for @a cont - * @return handle to abort the operation - */ struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h, const char *name, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey, + const struct GNUNET_IDENTITY_PrivateKey *privkey, + enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls) { @@ -749,7 +783,10 @@ GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h, crm->name_len = htons (slen); crm->reserved = htons (0); if (NULL == privkey) - GNUNET_CRYPTO_ecdsa_key_create (&crm->private_key); + { + GNUNET_assert (GNUNET_OK == + private_key_create (ktype, &crm->private_key)); + } else crm->private_key = *privkey; op->pk = crm->private_key; @@ -917,4 +954,316 @@ GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h) } +ssize_t +private_key_get_length (const struct GNUNET_IDENTITY_PrivateKey *key) +{ + switch (ntohl (key->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + return sizeof (key->type) + sizeof (key->ecdsa_key); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + return sizeof (key->type) + sizeof (key->eddsa_key); + break; + default: + GNUNET_break (0); + } + return -1; +} + + +ssize_t +GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key) +{ + switch (ntohl (key->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + return sizeof (key->type) + sizeof (key->ecdsa_key); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + return sizeof (key->type) + sizeof (key->eddsa_key); + break; + default: + GNUNET_break (0); + } + return -1; +} + + +ssize_t +GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key, + const void*buffer, + size_t len) +{ + if (len < sizeof (key->type)) + return -1; + GNUNET_memcpy (&(key->type), buffer, sizeof (key->type)); + const ssize_t length = GNUNET_IDENTITY_key_get_length (key); + if (len < length) + return -1; + if (length < 0) + return -2; + GNUNET_memcpy (&(key->ecdsa_key), buffer + sizeof (key->type), length + - sizeof (key->type)); + return length; +} + + +ssize_t +GNUNET_IDENTITY_write_key_to_buffer (const struct + GNUNET_IDENTITY_PublicKey *key, + void*buffer, + size_t len) +{ + const ssize_t length = GNUNET_IDENTITY_key_get_length (key); + if (len < length) + return -1; + if (length < 0) + return -2; + GNUNET_memcpy (buffer, key, length); + return length; +} + + +ssize_t +GNUNET_IDENTITY_signature_get_length (const struct + GNUNET_IDENTITY_Signature *sig) +{ + switch (ntohl (sig->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + return sizeof (sig->type) + sizeof (sig->ecdsa_signature); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + return sizeof (sig->type) + sizeof (sig->eddsa_signature); + break; + default: + GNUNET_break (0); + } + return -1; +} + + +ssize_t +GNUNET_IDENTITY_read_signature_from_buffer (struct + GNUNET_IDENTITY_Signature *sig, + const void*buffer, + size_t len) +{ + if (len < sizeof (sig->type)) + return -1; + GNUNET_memcpy (&(sig->type), buffer, sizeof (sig->type)); + const ssize_t length = GNUNET_IDENTITY_signature_get_length (sig); + if (len < length) + return -1; + if (length < 0) + return -2; + GNUNET_memcpy (&(sig->ecdsa_signature), buffer + sizeof (sig->type), length + - sizeof (sig->type)); + return length; +} + + +ssize_t +GNUNET_IDENTITY_write_signature_to_buffer (const struct + GNUNET_IDENTITY_Signature *sig, + void*buffer, + size_t len) +{ + const ssize_t length = GNUNET_IDENTITY_signature_get_length (sig); + if (len < length) + return -1; + if (length < 0) + return -2; + GNUNET_memcpy (buffer, &(sig->type), sizeof (sig->type)); + GNUNET_memcpy (buffer + sizeof (sig->type), &(sig->ecdsa_signature), length + - sizeof (sig->type)); + return length; +} + + +int +GNUNET_IDENTITY_sign_ (const struct + GNUNET_IDENTITY_PrivateKey *priv, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_IDENTITY_Signature *sig) +{ + sig->type = priv->type; + switch (ntohl (priv->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + return GNUNET_CRYPTO_ecdsa_sign_ (&(priv->ecdsa_key), purpose, + &(sig->ecdsa_signature)); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + return GNUNET_CRYPTO_eddsa_sign_ (&(priv->eddsa_key), purpose, + &(sig->eddsa_signature)); + break; + default: + GNUNET_break (0); + } + + return GNUNET_SYSERR; +} + + +int +GNUNET_IDENTITY_signature_verify_ (uint32_t purpose, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_IDENTITY_Signature *sig, + const struct GNUNET_IDENTITY_PublicKey *pub) +{ + /* check type matching of 'sig' and 'pub' */ + GNUNET_assert (ntohl (pub->type) == ntohl (sig->type)); + switch (ntohl (pub->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + return GNUNET_CRYPTO_ecdsa_verify_ (purpose, validate, + &(sig->ecdsa_signature), + &(pub->ecdsa_key)); + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + return GNUNET_CRYPTO_eddsa_verify_ (purpose, validate, + &(sig->eddsa_signature), + &(pub->eddsa_key)); + break; + default: + GNUNET_break (0); + } + + return GNUNET_SYSERR; +} + + +ssize_t +GNUNET_IDENTITY_encrypt (const void *block, + size_t size, + const struct GNUNET_IDENTITY_PublicKey *pub, + struct GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result) +{ + struct GNUNET_CRYPTO_EcdhePrivateKey pk; + GNUNET_CRYPTO_ecdhe_key_create (&pk); + struct GNUNET_HashCode hash; + switch (ntohl (pub->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdh_ecdsa (&pk, &(pub->ecdsa_key), + &hash)) + return -1; + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdh_eddsa (&pk, &(pub->eddsa_key), + &hash)) + return -1; + break; + default: + return -1; + } + GNUNET_CRYPTO_ecdhe_key_get_public (&pk, ecc); + GNUNET_CRYPTO_ecdhe_key_clear (&pk); + struct GNUNET_CRYPTO_SymmetricSessionKey key; + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + GNUNET_CRYPTO_hash_to_aes_key (&hash, &key, &iv); + GNUNET_CRYPTO_zero_keys (&hash, sizeof(hash)); + const ssize_t encrypted = GNUNET_CRYPTO_symmetric_encrypt (block, size, &key, + &iv, result); + GNUNET_CRYPTO_zero_keys (&key, sizeof(key)); + GNUNET_CRYPTO_zero_keys (&iv, sizeof(iv)); + return encrypted; +} + + +ssize_t +GNUNET_IDENTITY_decrypt (const void *block, + size_t size, + const struct GNUNET_IDENTITY_PrivateKey *priv, + const struct GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result) +{ + struct GNUNET_HashCode hash; + switch (ntohl (priv->type)) + { + case GNUNET_IDENTITY_TYPE_ECDSA: + if (GNUNET_SYSERR == GNUNET_CRYPTO_ecdsa_ecdh (&(priv->ecdsa_key), ecc, + &hash)) + return -1; + break; + case GNUNET_IDENTITY_TYPE_EDDSA: + if (GNUNET_SYSERR == GNUNET_CRYPTO_eddsa_ecdh (&(priv->eddsa_key), ecc, + &hash)) + return -1; + break; + default: + return -1; + } + struct GNUNET_CRYPTO_SymmetricSessionKey key; + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + GNUNET_CRYPTO_hash_to_aes_key (&hash, &key, &iv); + GNUNET_CRYPTO_zero_keys (&hash, sizeof(hash)); + const ssize_t decrypted = GNUNET_CRYPTO_symmetric_decrypt (block, size, &key, + &iv, result); + GNUNET_CRYPTO_zero_keys (&key, sizeof(key)); + GNUNET_CRYPTO_zero_keys (&iv, sizeof(iv)); + return decrypted; +} + + +char * +GNUNET_IDENTITY_public_key_to_string (const struct + GNUNET_IDENTITY_PublicKey *key) +{ + size_t size = GNUNET_IDENTITY_key_get_length (key); + return GNUNET_STRINGS_data_to_string_alloc (key, + size); +} + + +char * +GNUNET_IDENTITY_private_key_to_string (const struct + GNUNET_IDENTITY_PrivateKey *key) +{ + size_t size = private_key_get_length (key); + return GNUNET_STRINGS_data_to_string_alloc (key, + size); +} + + +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_public_key_from_string (const char *str, + struct GNUNET_IDENTITY_PublicKey *key) +{ + enum GNUNET_GenericReturnValue ret; + enum GNUNET_IDENTITY_KeyType ktype; + ret = GNUNET_STRINGS_string_to_data (str, + strlen (str), + key, + sizeof (*key)); + if (GNUNET_OK != ret) + return GNUNET_SYSERR; + ktype = ntohl (key->type); + return (GNUNET_IDENTITY_TYPE_ECDSA == ktype) ? GNUNET_OK : GNUNET_SYSERR; // FIXME other keys, cleaner way? + +} + + +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_private_key_from_string (const char *str, + struct GNUNET_IDENTITY_PrivateKey *key) +{ + enum GNUNET_GenericReturnValue ret; + enum GNUNET_IDENTITY_KeyType ktype; + ret = GNUNET_STRINGS_string_to_data (str, + strlen (str), + key, + sizeof (*key)); + if (GNUNET_OK != ret) + return GNUNET_SYSERR; + ktype = ntohl (key->type); + return (GNUNET_IDENTITY_TYPE_ECDSA == ktype) ? GNUNET_OK : GNUNET_SYSERR; // FIXME other keys, cleaner way? +} + + /* end of identity_api.c */ diff --git a/src/identity/identity_api_lookup.c b/src/identity/identity_api_lookup.c index 26b1eacd7..51afb2515 100644 --- a/src/identity/identity_api_lookup.c +++ b/src/identity/identity_api_lookup.c @@ -127,14 +127,12 @@ handle_identity_update (void *cls, const struct UpdateMessage *um) struct GNUNET_IDENTITY_EgoLookup *el = cls; uint16_t name_len = ntohs (um->name_len); const char *str = (0 == name_len) ? NULL : (const char *) &um[1]; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; struct GNUNET_HashCode id; struct GNUNET_IDENTITY_Ego ego; memset (&ego, 0, sizeof (ego)); GNUNET_break (GNUNET_YES != ntohs (um->end_of_list)); - GNUNET_CRYPTO_ecdsa_key_get_public (&um->private_key, &pub); - GNUNET_CRYPTO_hash (&pub, sizeof(pub), &id); + GNUNET_CRYPTO_hash (&um->private_key, sizeof(um->private_key), &id); ego.pk = um->private_key; ego.name = (char *) str; ego.id = id; diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c index d86d29e36..dba1d478d 100644 --- a/src/identity/plugin_rest_identity.c +++ b/src/identity/plugin_rest_identity.c @@ -384,7 +384,7 @@ ego_get_for_subsystem (void *cls, { struct RequestHandle *handle = cls; struct MHD_Response *resp; - struct GNUNET_CRYPTO_EcdsaPublicKey public_key; + struct GNUNET_IDENTITY_PublicKey public_key; json_t *json_root; char *result_str; char *public_key_string; @@ -398,7 +398,7 @@ ego_get_for_subsystem (void *cls, } GNUNET_IDENTITY_ego_get_public_key (ego, &public_key); - public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string (&public_key); + public_key_string = GNUNET_IDENTITY_public_key_to_string (&public_key); // create json with subsystem identity json_root = json_object (); @@ -496,7 +496,7 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_CONTAINER_multihashmap_contains ( handle->rest_handle->url_param_map, &key)) { - privkey_str = GNUNET_CRYPTO_ecdsa_private_key_to_string ( + privkey_str = GNUNET_IDENTITY_private_key_to_string ( GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego)); json_object_set_new (json_ego, GNUNET_REST_IDENTITY_PARAM_PRIVKEY, @@ -549,7 +549,7 @@ ego_get_response (struct RequestHandle *handle, struct EgoEntry *ego_entry) GNUNET_CONTAINER_multihashmap_contains ( handle->rest_handle->url_param_map, &key)) { - privkey_str = GNUNET_CRYPTO_ecdsa_private_key_to_string ( + privkey_str = GNUNET_IDENTITY_private_key_to_string ( GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego)); json_object_set_new (json_ego, GNUNET_REST_IDENTITY_PARAM_PRIVKEY, @@ -686,7 +686,7 @@ do_finished (void *cls, const char *emsg) */ static void do_finished_create (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { struct RequestHandle *handle = cls; @@ -999,8 +999,8 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, json_error_t err; char *egoname; char *privkey; - struct GNUNET_CRYPTO_EcdsaPrivateKey pk; - struct GNUNET_CRYPTO_EcdsaPrivateKey *pk_ptr; + struct GNUNET_IDENTITY_PrivateKey pk; + struct GNUNET_IDENTITY_PrivateKey *pk_ptr; int json_unpack_state; char term_data[handle->data_size + 1]; @@ -1074,7 +1074,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, strlen (privkey), &pk, sizeof(struct - GNUNET_CRYPTO_EcdsaPrivateKey)); + GNUNET_IDENTITY_PrivateKey)); pk_ptr = &pk; } else @@ -1084,6 +1084,7 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, handle->op = GNUNET_IDENTITY_create (identity_handle, handle->name, pk_ptr, + GNUNET_IDENTITY_TYPE_ECDSA, &do_finished_create, handle); } @@ -1208,7 +1209,7 @@ list_ego (void *cls, const char *identifier) { struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { @@ -1219,7 +1220,7 @@ list_ego (void *cls, { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, @@ -1245,7 +1246,7 @@ list_ego (void *cls, /* Add */ ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, diff --git a/src/identity/test_identity.c b/src/identity/test_identity.c index 37eeab238..4954fe7be 100644 --- a/src/identity/test_identity.c +++ b/src/identity/test_identity.c @@ -253,7 +253,7 @@ success_rename_cont (void *cls, const char *emsg) */ static void create_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { CHECK (NULL != pk); @@ -279,7 +279,11 @@ run (void *cls, GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); h = GNUNET_IDENTITY_connect (cfg, ¬ification_cb, NULL); CHECK (NULL != h); - op = GNUNET_IDENTITY_create (h, "test-id", NULL, &create_cb, NULL); + op = GNUNET_IDENTITY_create (h, + "test-id", + NULL, + GNUNET_IDENTITY_TYPE_ECDSA, + &create_cb, NULL); } diff --git a/src/identity/test_identity_defaults.c b/src/identity/test_identity_defaults.c index 53eec1252..2d5244d1b 100644 --- a/src/identity/test_identity_defaults.c +++ b/src/identity/test_identity_defaults.c @@ -241,7 +241,7 @@ notification_cb (void *cls, */ static void create_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { CHECK (NULL == emsg); @@ -266,7 +266,11 @@ run_set (void *cls, GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); h = GNUNET_IDENTITY_connect (cfg, ¬ification_cb, NULL); CHECK (NULL != h); - op = GNUNET_IDENTITY_create (h, "test-id", NULL, &create_cb, NULL); + op = GNUNET_IDENTITY_create (h, + "test-id", + NULL, + GNUNET_IDENTITY_TYPE_ECDSA, + &create_cb, NULL); } diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 202abb7ac..fc3d745a6 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -62,6 +62,7 @@ gnunetinclude_HEADERS = \ gnunet_json_lib.h \ gnunet_load_lib.h \ gnunet_cadet_service.h \ + gnunet_messenger_service.h \ gnunet_mhd_compat.h \ gnunet_microphone_lib.h \ gnunet_mst_lib.h \ diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h index 0c566df75..7239eccfb 100644 --- a/src/include/gnunet_buffer_lib.h +++ b/src/include/gnunet_buffer_lib.h @@ -147,7 +147,8 @@ GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str); * @param ... format arguments */ void -GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...); +GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...) +__attribute__ ((format (printf, 2, 3))); /** diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index fcaae1026..21b87b0f5 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h @@ -488,7 +488,8 @@ void GNUNET_log_from_nocheck (enum GNUNET_ErrorType kind, const char *comp, const char *message, - ...); + ...) +__attribute__ ((format (printf, 3, 4))); #if ! defined(GNUNET_CULL_LOGGING) #define GNUNET_log_from(kind, comp, ...) \ @@ -1445,6 +1446,7 @@ GNUNET_is_zero_ (const void *a, memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \ } while (0) + /** * @ingroup memory * Like snprintf, just aborts if the buffer is of insufficient size. @@ -1456,7 +1458,11 @@ GNUNET_is_zero_ (const void *a, * @return number of bytes written to buf or negative value on error */ int -GNUNET_snprintf (char *buf, size_t size, const char *format, ...); +GNUNET_snprintf (char *buf, + size_t size, + const char *format, + ...) +__attribute__ ((format (printf, 3, 4))); /** @@ -1469,7 +1475,10 @@ GNUNET_snprintf (char *buf, size_t size, const char *format, ...); * @return number of bytes in "*buf" excluding 0-termination */ int -GNUNET_asprintf (char **buf, const char *format, ...); +GNUNET_asprintf (char **buf, + const char *format, + ...) +__attribute__ ((format (printf, 2, 3))); /* ************** internal implementations, use macros above! ************** */ diff --git a/src/include/gnunet_conversation_service.h b/src/include/gnunet_conversation_service.h index 4566caad0..be5a81cfb 100644 --- a/src/include/gnunet_conversation_service.h +++ b/src/include/gnunet_conversation_service.h @@ -147,7 +147,7 @@ typedef void struct GNUNET_CONVERSATION_Caller * caller, const struct - GNUNET_CRYPTO_EcdsaPublicKey *caller_id); + GNUNET_IDENTITY_PublicKey *caller_id); /** diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 03fb16a43..2bbf2b1e7 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -1700,7 +1700,7 @@ GNUNET_CRYPTO_eddsa_sign_ ( */ #define GNUNET_CRYPTO_eddsa_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ - GNUNET_assert (htonl ((ps)->purpose.size) == sizeof (*ps)); \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ @@ -1747,7 +1747,7 @@ GNUNET_CRYPTO_ecdsa_sign_ ( */ #define GNUNET_CRYPTO_ecdsa_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ - GNUNET_assert (htonl ((ps)->purpose.size) == sizeof (*(ps))); \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ @@ -1853,7 +1853,7 @@ GNUNET_CRYPTO_ecdsa_verify_ ( */ #define GNUNET_CRYPTO_ecdsa_verify(purp,ps,sig,pub) ({ \ /* check size is set correctly */ \ - GNUNET_assert (htonl ((ps)->purpose.size) == sizeof (*(ps))); \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index ef81e9a88..3f6c9b9aa 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h @@ -36,6 +36,7 @@ #include "gnunet_util_lib.h" #include "gnunet_dnsparser_lib.h" +#include "gnunet_identity_service.h" #include "gnunet_namestore_service.h" #ifdef __cplusplus @@ -139,7 +140,7 @@ enum GNUNET_GNS_LocalOptions struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, const char *name, - const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, + const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, @@ -163,7 +164,7 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup_limited (struct GNUNET_GNS_Handle *handle, const char *name, - const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, + const struct GNUNET_IDENTITY_PublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, uint16_t recursion_depth_limit, diff --git a/src/include/gnunet_gnsrecord_json_lib.h b/src/include/gnunet_gnsrecord_json_lib.h new file mode 100644 index 000000000..966461705 --- /dev/null +++ b/src/include/gnunet_gnsrecord_json_lib.h @@ -0,0 +1,73 @@ +/* + This file is part of GNUnet + Copyright (C) 2012, 2013 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @author Martin Schanzenbach + * + * @file + * API that can be used to manipulate JSON GNS record data + * + * @defgroup gnsrecord GNS Record library + * Manipulate GNS record data + * + * @see [Documentation](https://gnunet.org/gns-plugins) + * + * @{ + */ +#ifndef GNUNET_GNSRECORD_JSON_LIB_H +#define GNUNET_GNSRECORD_JSON_LIB_H + +#include "gnunet_gnsrecord_lib.h" +#include "gnunet_json_lib.h" + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + + +/** + * JSON Specification for GNS Records. + * + * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_GNSRECORD_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, + unsigned int *rd_count, + char **name); + + +/** + * Convert GNS record to JSON. + * + * @param rname name of record + * @param rd record data + * @return corresponding JSON encoding + */ +json_t * +GNUNET_GNSRECORD_JSON_from_gnsrecord (const char*rname, + const struct GNUNET_GNSRECORD_Data *rd, + unsigned int rd_count); + + +#endif diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index 960203fb1..0bf2ceed7 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -34,6 +34,8 @@ #ifndef GNUNET_GNSRECORD_LIB_H #define GNUNET_GNSRECORD_LIB_H +#include "gnunet_identity_service.h" + #ifdef __cplusplus extern "C" { #if 0 /* keep Emacsens' auto-indent happy */ @@ -55,7 +57,7 @@ extern "C" { /** * Record type for GNS zone transfer ("PKEY"). */ -#define GNUNET_GNSRECORD_TYPE_PKEY 65536 +#define GNUNET_GNSRECORD_TYPE_PKEY GNUNET_IDENTITY_TYPE_ECDSA /** * Record type for GNS nick names ("NICK"). @@ -151,6 +153,11 @@ extern "C" { */ #define GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION 65555 +/** + * Record type for EDKEY delegations. + */ +#define GNUNET_GNSRECORD_TYPE_EDKEY GNUNET_IDENTITY_TYPE_EDDSA + /** * Flags that can be set for a record. @@ -261,21 +268,20 @@ struct GNUNET_GNSRECORD_PlaceData /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */ }; - /** * Information we have in an encrypted block with record data (i.e. in the DHT). */ -struct GNUNET_GNSRECORD_Block +struct GNUNET_GNSRECORD_EcdsaBlock { /** - * Signature of the block. + * Derived key used for signing; hash of this is the query. */ - struct GNUNET_CRYPTO_EcdsaSignature signature; + struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; /** - * Derived key used for signing; hash of this is the query. + * Signature of the block. */ - struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; + struct GNUNET_CRYPTO_EcdsaSignature signature; /** * Number of bytes signed; also specifies the number of bytes @@ -291,6 +297,17 @@ struct GNUNET_GNSRECORD_Block /* followed by encrypted data */ }; +struct GNUNET_GNSRECORD_Block +{ + uint32_t type; + + union + { + struct GNUNET_GNSRECORD_EcdsaBlock ecdsa_block; + //struct GNUNET_GNSRECORD_EddsaBlock eddsa_block; + }; +}; + /** * Record type used to box up SRV and TLSA records. For example, a @@ -335,7 +352,7 @@ struct GNUNET_GNSRECORD_ReverseRecord /** * The public key of the namespace the is delegating to our namespace */ - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; /** * The expiration time of the delegation @@ -488,7 +505,7 @@ GNUNET_GNSRECORD_string_to_lowercase (const char *src); * #GNUNET_GNSRECORD_z2s. */ const char * -GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z); +GNUNET_GNSRECORD_z2s (const struct GNUNET_IDENTITY_PublicKey *z); /** @@ -502,7 +519,7 @@ GNUNET_GNSRECORD_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z); * key in an encoding suitable for DNS labels. */ const char * -GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey); +GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_IDENTITY_PublicKey *pkey); /** @@ -516,7 +533,7 @@ GNUNET_GNSRECORD_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey); */ int GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, - struct GNUNET_CRYPTO_EcdsaPublicKey *pkey); + struct GNUNET_IDENTITY_PublicKey *pkey); /** @@ -528,7 +545,7 @@ GNUNET_GNSRECORD_zkey_to_pkey (const char *zkey, */ void GNUNET_GNSRECORD_query_from_private_key ( - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, struct GNUNET_HashCode *query); @@ -541,7 +558,7 @@ GNUNET_GNSRECORD_query_from_private_key ( */ void GNUNET_GNSRECORD_query_from_public_key ( - const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, + const struct GNUNET_IDENTITY_PublicKey *pub, const char *label, struct GNUNET_HashCode *query); @@ -555,7 +572,7 @@ GNUNET_GNSRECORD_query_from_public_key ( * @param rd_count number of records in @a rd */ struct GNUNET_GNSRECORD_Block * -GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, @@ -574,7 +591,7 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, * @param rd_count number of records in @a rd */ struct GNUNET_GNSRECORD_Block * -GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, @@ -606,7 +623,7 @@ GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block); int GNUNET_GNSRECORD_block_decrypt ( const struct GNUNET_GNSRECORD_Block *block, - const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, + const struct GNUNET_IDENTITY_PublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls); @@ -636,6 +653,82 @@ GNUNET_GNSRECORD_record_get_expiration_time ( unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); +/** + * Returns the length of this block in bytes. + * Block length strongly depends on the zone type. + * + * @param block the block. + * @return the length of this block in bytes + */ +size_t +GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block); + +/** + * Returns the expiration of a block. + * + * @param block the block. + * @return the block expiration. + */ +struct GNUNET_TIME_Absolute +GNUNET_GNSRECORD_block_get_expiration (const struct GNUNET_GNSRECORD_Block *block); + + +/** + * Builds the query hash from a block. + * + * @param block the block. + * @param query where to write the query hash. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_query_from_block (const struct GNUNET_GNSRECORD_Block *block, + struct GNUNET_HashCode *query); + + +/** + * Build a #GNUNET_GNSRECORD_PublicKey from + * zone delegation resource record data. + * + * @param data the record data- + * @param data_size the data size. + * @param type the record type + * @param key the identity key to store the data in (must be allocated). + * @return GNUNET_OK if successful. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_identity_from_data (const char *data, + size_t data_size, + uint32_t type, + struct GNUNET_IDENTITY_PublicKey *key); + + +/** + * Create record data and size from an identity key. + * + * @param key the identity key to use. + * @param data the record data (will be allocated) + * @param data_size the allocated data size. + * @param type the resulting record type + * @return GNUNET_OK if successful. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_data_from_identity (const struct GNUNET_IDENTITY_PublicKey *key, + char **data, + size_t *data_size, + uint32_t *type); + + +/** + * Check if this type is one of the supported GNS zone + * types. + * + * @param type the type to check + * @return GNUNET_YES if it is one of the supported types. + */ +enum GNUNET_GenericReturnValue +GNUNET_GNSRECORD_is_zonekey_type (uint32_t type); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h index 94127248e..2974568db 100644 --- a/src/include/gnunet_identity_service.h +++ b/src/include/gnunet_identity_service.h @@ -57,6 +57,21 @@ extern "C" { */ #define GNUNET_IDENTITY_VERSION 0x00000100 +enum GNUNET_IDENTITY_KeyType +{ + /** + * The identity type. The value is the same as the + * PKEY record type. + */ + GNUNET_IDENTITY_TYPE_ECDSA = 65536, + + /** + * EDDSA identity. The value is the same as the EDKEY + * record type. + */ + GNUNET_IDENTITY_TYPE_EDDSA = 65556 +}; + /** * Handle to access the identity service. */ @@ -67,6 +82,88 @@ struct GNUNET_IDENTITY_Handle; */ struct GNUNET_IDENTITY_Ego; + +/** + * A private key for an identity as per LSD0001. + */ +struct GNUNET_IDENTITY_PrivateKey +{ + /** + * Type of public key. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA identity key. + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_key; + + /** + * AN EdDSA identtiy key + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key; + }; +}; + + +/** + * An identity key as per LSD0001. + */ +struct GNUNET_IDENTITY_PublicKey +{ + /** + * Type of public key. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA identity key. + */ + struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_key; + + /** + * AN EdDSA identtiy key + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_key; + }; +}; + + +/** + * An identity signature as per LSD0001. + */ +struct GNUNET_IDENTITY_Signature +{ + /** + * Type of signature. + * Defined by the GNS zone type value. + * In NBO. + */ + uint32_t type; + + union + { + /** + * An ECDSA signature + */ + struct GNUNET_CRYPTO_EcdsaSignature ecdsa_signature; + + /** + * AN EdDSA signature + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; + }; +}; + + /** * Handle for an operation with the identity service. */ @@ -79,7 +176,7 @@ struct GNUNET_IDENTITY_Operation; * @param ego the ego * @return associated ECC key, valid as long as the ego is valid */ -const struct GNUNET_CRYPTO_EcdsaPrivateKey * +const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego); @@ -100,7 +197,7 @@ GNUNET_IDENTITY_ego_get_anonymous (void); */ void GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, - struct GNUNET_CRYPTO_EcdsaPublicKey *pk); + struct GNUNET_IDENTITY_PublicKey *pk); /** @@ -224,7 +321,7 @@ GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h); typedef void (*GNUNET_IDENTITY_CreateContinuation) ( void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg); @@ -234,6 +331,7 @@ typedef void * @param id identity service to use * @param name desired name * @param privkey desired private key or NULL to create one + * @param ktype the type of key to create. Ignored if privkey != NULL. * @param cont function to call with the result (will only be called once) * @param cont_cls closure for @a cont * @return handle to abort the operation @@ -241,7 +339,8 @@ typedef void struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id, const char *name, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey, + const struct GNUNET_IDENTITY_PrivateKey *privkey, + enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls); @@ -292,6 +391,319 @@ void GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op); +/** + * Get the compacted length of a #GNUNET_IDENTITY_PublicKey. + * Compacted means that it returns the minimum number of bytes this + * key is long, as opposed to the union structure inside + * #GNUNET_IDENTITY_PublicKey. + * Useful for compact serializations. + * + * @param key the key. + * @return -1 on error, else the compacted length of the key. + */ +ssize_t +GNUNET_IDENTITY_key_get_length (const struct GNUNET_IDENTITY_PublicKey *key); + + +/** + * Reads a #GNUNET_IDENTITY_PublicKey from a compact buffer. + * The buffer has to contain at least the compacted length of + * a #GNUNET_IDENTITY_PublicKey in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the buffer does not contain a valid key, it returns -2 as error. + * + * @param key the key + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes read from the buffer + */ +ssize_t +GNUNET_IDENTITY_read_key_from_buffer (struct GNUNET_IDENTITY_PublicKey *key, + const void*buffer, + size_t len); + + +/** + * Writes a #GNUNET_IDENTITY_PublicKey to a compact buffer. + * The buffer requires space for at least the compacted length of + * a #GNUNET_IDENTITY_PublicKey in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the key is not valid, it returns -2 as error. + * + * @param key the key + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes written to the buffer + */ +ssize_t +GNUNET_IDENTITY_write_key_to_buffer (const struct + GNUNET_IDENTITY_PublicKey *key, + void*buffer, + size_t len); + + +/** + * Get the compacted length of a #GNUNET_IDENTITY_Signature. + * Compacted means that it returns the minimum number of bytes this + * signature is long, as opposed to the union structure inside + * #GNUNET_IDENTITY_Signature. + * Useful for compact serializations. + * + * @param sig the signature. + * @return -1 on error, else the compacted length of the signature. + */ +ssize_t +GNUNET_IDENTITY_signature_get_length (const struct + GNUNET_IDENTITY_Signature *sig); + + +/** + * Reads a #GNUNET_IDENTITY_Signature from a compact buffer. + * The buffer has to contain at least the compacted length of + * a #GNUNET_IDENTITY_Signature in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the buffer does not contain a valid key, it returns -2 as error. + * + * @param sig the signature + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes read from the buffer + */ +ssize_t +GNUNET_IDENTITY_read_signature_from_buffer (struct + GNUNET_IDENTITY_Signature *sig, + const void*buffer, + size_t len); + + +/** + * Writes a #GNUNET_IDENTITY_Signature to a compact buffer. + * The buffer requires space for at least the compacted length of + * a #GNUNET_IDENTITY_Signature in bytes. + * If the buffer is too small, the function returns -1 as error. + * If the key is not valid, it returns -2 as error. + * + * @param sig the signature + * @param buffer the buffer + * @param len the length of buffer + * @return -1 or -2 on error, else the amount of bytes written to the buffer + */ +ssize_t +GNUNET_IDENTITY_write_signature_to_buffer (const struct + GNUNET_IDENTITY_Signature *sig, + void*buffer, + size_t len); + + +/** + * @brief Sign a given block. + * + * The @a purpose data is the beginning of the data of which the signature is + * to be created. The `size` field in @a purpose must correctly indicate the + * number of bytes of the data structure, including its header. If possible, + * use #GNUNET_IDENTITY_sign() instead of this function. + * + * @param priv private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param[out] sig where to write the signature + * @return #GNUNET_SYSERR on error, #GNUNET_OK on success + */ +int +GNUNET_IDENTITY_sign_ (const struct + GNUNET_IDENTITY_PrivateKey *priv, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_IDENTITY_Signature *sig); + + +/** + * @brief Sign a given block with #GNUNET_IDENTITY_PrivateKey. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param priv private key to use for the signing + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param[out] sig where to write the signature + */ +#define GNUNET_IDENTITY_sign(priv,ps,sig) do { \ + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)); \ + GNUNET_assert (GNUNET_OK == \ + GNUNET_IDENTITY_sign_ (priv, \ + &(ps)->purpose, \ + sig)); \ +} while (0) + + +/** + * @brief Verify a given signature. + * + * The @a validate data is the beginning of the data of which the signature + * is to be verified. The `size` field in @a validate must correctly indicate + * the number of bytes of the data structure, including its header. If @a + * purpose does not match the purpose given in @a validate (the latter must be + * in big endian), signature verification fails. If possible, + * use #GNUNET_IDENTITY_signature_verify() instead of this function (only if @a validate + * is not fixed-size, you must use this function directly). + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param pub public key of the signer + * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid + */ +int +GNUNET_IDENTITY_signature_verify_ (uint32_t purpose, + const struct + GNUNET_CRYPTO_EccSignaturePurpose *validate, + const struct GNUNET_IDENTITY_Signature *sig, + const struct + GNUNET_IDENTITY_PublicKey *pub); + + +/** + * @brief Verify a given signature with #GNUNET_IDENTITY_PublicKey. + * + * The @a ps data must be a fixed-size struct for which the signature is to be + * created. The `size` field in @a ps->purpose must correctly indicate the + * number of bytes of the data structure, including its header. + * + * @param purp purpose of the signature, must match 'ps->purpose.purpose' + * (except in host byte order) + * @param ps packed struct with what to sign, MUST begin with a purpose + * @param sig where to read the signature from + * @param pub public key to use for the verifying + */ +#define GNUNET_IDENTITY_signature_verify(purp,ps,sig,pub) ({ \ + /* check size is set correctly */ \ + GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ + /* check 'ps' begins with the purpose */ \ + GNUNET_static_assert (((void*) (ps)) == \ + ((void*) &(ps)->purpose)); \ + GNUNET_IDENTITY_signature_verify_ (purp, \ + &(ps)->purpose, \ + sig, \ + pub); \ + }) + + +/** + * Encrypt a block with #GNUNET_IDENTITY_PublicKey and derives a + * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption + * using ecdh to derive a symmetric key. + * + * @param block the block to encrypt + * @param size the size of the @a block + * @param pub public key to use for ecdh + * @param ecc where to write the ecc public key + * @param result the output parameter in which to store the encrypted result + * can be the same or overlap with @c block + * @returns the size of the encrypted block, -1 for errors. + * Due to the use of CFB and therefore an effective stream cipher, + * this size should be the same as @c len. + */ +ssize_t +GNUNET_IDENTITY_encrypt (const void *block, + size_t size, + const struct GNUNET_IDENTITY_PublicKey *pub, + struct GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result); + + +/** + * Decrypt a given block with #GNUNET_IDENTITY_PrivateKey and a given + * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key. + * + * @param block the data to decrypt, encoded as returned by encrypt + * @param size the size of the @a block to decrypt + * @param priv private key to use for ecdh + * @param ecc the ecc public key + * @param result address to store the result at + * can be the same or overlap with @c block + * @return -1 on failure, size of decrypted block on success. + * Due to the use of CFB and therefore an effective stream cipher, + * this size should be the same as @c size. + */ +ssize_t +GNUNET_IDENTITY_decrypt (const void *block, + size_t size, + const struct + GNUNET_IDENTITY_PrivateKey *priv, + const struct + GNUNET_CRYPTO_EcdhePublicKey *ecc, + void *result); + + +/** + * Creates a (Base32) string representation of the public key. + * The resulting string encodes a compacted representation of the key. + * See also #GNUNET_IDENTITY_key_get_length. + * + * @param key the key. + * @return the string representation of the key, or NULL on error. + */ +char * +GNUNET_IDENTITY_public_key_to_string (const struct + GNUNET_IDENTITY_PublicKey *key); + + +/** + * Creates a (Base32) string representation of the private key. + * The resulting string encodes a compacted representation of the key. + * See also #GNUNET_IDENTITY_key_get_length. + * + * @param key the key. + * @return the string representation of the key, or NULL on error. + */ +char * +GNUNET_IDENTITY_private_key_to_string (const struct + GNUNET_IDENTITY_PrivateKey *key); + + +/** + * Parses a (Base32) string representation of the public key. + * See also #GNUNET_IDENTITY_public_key_to_string. + * + * @param str the encoded key. + * @param key where to write the key. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_public_key_from_string (const char*str, + struct GNUNET_IDENTITY_PublicKey *key); + + +/** + * Parses a (Base32) string representation of the private key. + * See also #GNUNET_IDENTITY_private_key_to_string. + * + * @param str the encoded key. + * @param key where to write the key. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_private_key_from_string (const char*str, + struct GNUNET_IDENTITY_PrivateKey *key); + + +/** + * Retrieves the public key representation of a private key. + * + * @param privkey the private key. + * @param key the public key result. + * @return GNUNET_SYSERR on error. + */ +enum GNUNET_GenericReturnValue +GNUNET_IDENTITY_key_get_public (const struct + GNUNET_IDENTITY_PrivateKey *privkey, + struct GNUNET_IDENTITY_PublicKey *key); + + /* ************* convenience API to lookup an ego ***************** */ /** @@ -344,7 +756,7 @@ GNUNET_IDENTITY_ego_lookup_cancel (struct GNUNET_IDENTITY_EgoLookup *el); typedef void (*GNUNET_IDENTITY_EgoSuffixCallback) ( void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, + const struct GNUNET_IDENTITY_PrivateKey *priv, const char *ego_name); diff --git a/src/include/gnunet_json_lib.h b/src/include/gnunet_json_lib.h index 07a14d329..3dc79105e 100644 --- a/src/include/gnunet_json_lib.h +++ b/src/include/gnunet_json_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -28,7 +28,6 @@ #define GNUNET_JSON_LIB_H #include "gnunet_util_lib.h" -#include "gnunet_gnsrecord_lib.h" #include #include @@ -359,18 +358,6 @@ GNUNET_JSON_spec_rsa_signature (const char *name, struct GNUNET_CRYPTO_RsaSignature **sig); -/** - * JSON Specification for GNS Records. - * - * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill - * @return JSON Specification - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, - unsigned int *rd_count, - char **name); - - /* ****************** Generic generator interface ******************* */ @@ -446,18 +433,6 @@ GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk); json_t * GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig); -/** - * Convert Gns record to JSON. - * - * @param rname name of record - * @param rd record data - * @return corresponding JSON encoding - */ -json_t * -GNUNET_JSON_from_gnsrecord (const char *rname, - const struct GNUNET_GNSRECORD_Data *rd, - unsigned int rd_count); - /* ******************* Helpers for MHD upload handling ******************* */ /** diff --git a/src/include/gnunet_messenger_service.h b/src/include/gnunet_messenger_service.h new file mode 100644 index 000000000..8f5315c30 --- /dev/null +++ b/src/include/gnunet_messenger_service.h @@ -0,0 +1,436 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * + * @file + * MESSENGER service; manages decentralized chat groups + * + * @defgroup messenger MESSENGER service + * Instant messaging based on the CADET subsystem + * + * @{ + */ + +#ifndef GNUNET_MESSENGER_SERVICE_H +#define GNUNET_MESSENGER_SERVICE_H + +#ifdef __cplusplus +extern "C" { +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "platform.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_mq_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_scheduler_lib.h" +#include "gnunet_time_lib.h" + +#define GNUNET_MESSENGER_SERVICE_NAME "messenger" + +/** + * Opaque handle to the messenger + */ +struct GNUNET_MESSENGER_Handle; + +/** + * Opaque handle to a room + */ +struct GNUNET_MESSENGER_Room; + +/** + * Opaque handle to a contact + */ +struct GNUNET_MESSENGER_Contact; + +/** + * Enum for the different supported kinds of messages + */ +enum GNUNET_MESSENGER_MessageKind +{ + GNUNET_MESSENGER_KIND_INFO = 1, + + GNUNET_MESSENGER_KIND_JOIN = 2, + GNUNET_MESSENGER_KIND_LEAVE = 3, + + GNUNET_MESSENGER_KIND_NAME = 4, + GNUNET_MESSENGER_KIND_KEY = 5, + GNUNET_MESSENGER_KIND_PEER = 6, + GNUNET_MESSENGER_KIND_ID = 7, + + GNUNET_MESSENGER_KIND_MISS = 8, + GNUNET_MESSENGER_KIND_MERGE = 9, + GNUNET_MESSENGER_KIND_REQUEST = 10, + + GNUNET_MESSENGER_KIND_INVITE = 11, + GNUNET_MESSENGER_KIND_TEXT = 12, + GNUNET_MESSENGER_KIND_FILE = 13, + + GNUNET_MESSENGER_KIND_PRIVATE = 14, + + GNUNET_MESSENGER_KIND_UNKNOWN = 0 +}__attribute__((__packed__)); + +/** + * Get the name of a message kind. + * + * @param kind Kind of a message + * @return Name of that kind + */ +const char* +GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind); + +struct GNUNET_MESSENGER_MessageHeader +{ + struct GNUNET_IDENTITY_Signature signature; + + struct GNUNET_TIME_AbsoluteNBO timestamp; + + struct GNUNET_ShortHashCode sender_id; + struct GNUNET_HashCode previous; + + enum GNUNET_MESSENGER_MessageKind kind; +}; + +struct GNUNET_MESSENGER_MessageInfo +{ + struct GNUNET_IDENTITY_PublicKey host_key; + struct GNUNET_ShortHashCode unique_id; +}; + +struct GNUNET_MESSENGER_MessageJoin +{ + struct GNUNET_IDENTITY_PublicKey key; +}; + +struct GNUNET_MESSENGER_MessageLeave +{ +}; + +struct GNUNET_MESSENGER_MessageName +{ + char *name; +}; + +struct GNUNET_MESSENGER_MessageKey +{ + struct GNUNET_IDENTITY_PublicKey key; +}; + +struct GNUNET_MESSENGER_MessagePeer +{ + struct GNUNET_PeerIdentity peer; +}; + +struct GNUNET_MESSENGER_MessageId +{ + struct GNUNET_ShortHashCode id; +}; + +struct GNUNET_MESSENGER_MessageMiss +{ + struct GNUNET_PeerIdentity peer; +}; + +struct GNUNET_MESSENGER_MessageMerge +{ + struct GNUNET_HashCode previous; +}; + +struct GNUNET_MESSENGER_MessageRequest +{ + struct GNUNET_HashCode hash; +}; + +struct GNUNET_MESSENGER_MessageInvite +{ + struct GNUNET_PeerIdentity door; + struct GNUNET_HashCode key; +}; + +struct GNUNET_MESSENGER_MessageText +{ + char *text; +}; + +struct GNUNET_MESSENGER_MessageFile +{ + struct GNUNET_CRYPTO_SymmetricSessionKey key; + struct GNUNET_HashCode hash; + char name[NAME_MAX]; + char *uri; +}; + +struct GNUNET_MESSENGER_MessagePrivate +{ + struct GNUNET_CRYPTO_EcdhePublicKey key; + + uint16_t length; + char *data; +}; + +struct GNUNET_MESSENGER_MessageBody +{ + union + { + struct GNUNET_MESSENGER_MessageInfo info; + + struct GNUNET_MESSENGER_MessageJoin join; + struct GNUNET_MESSENGER_MessageLeave leave; + + struct GNUNET_MESSENGER_MessageName name; + struct GNUNET_MESSENGER_MessageKey key; + struct GNUNET_MESSENGER_MessagePeer peer; + struct GNUNET_MESSENGER_MessageId id; + + struct GNUNET_MESSENGER_MessageMiss miss; + struct GNUNET_MESSENGER_MessageMerge merge; + struct GNUNET_MESSENGER_MessageRequest request; + + struct GNUNET_MESSENGER_MessageInvite invite; + struct GNUNET_MESSENGER_MessageText text; + struct GNUNET_MESSENGER_MessageFile file; + + struct GNUNET_MESSENGER_MessagePrivate private; + }; +}; + +/** + * Struct to a message + */ +struct GNUNET_MESSENGER_Message +{ + struct GNUNET_MESSENGER_MessageHeader header; + struct GNUNET_MESSENGER_MessageBody body; +}; + +/** + * Method called whenever the EGO of a handle changes or if the first connection fails + * to load a valid EGO and the anonymous keypair will be used instead. + * + * @param cls Closure from GNUNET_MESSENGER_connect + * @param handle Messenger handle + */ +typedef void +(*GNUNET_MESSENGER_IdentityCallback) (void *cls, struct GNUNET_MESSENGER_Handle *handle); + +/** + * Method called whenever a message is sent or received from a room. + * + * @param cls Closure from GNUNET_MESSENGER_connect + * @param room Room handle + * @param message Newly received or sent message + * @param hash Hash identifying the message + */ +typedef void +(*GNUNET_MESSENGER_MessageCallback) (void *cls, const struct GNUNET_MESSENGER_Room *room, + const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Set up a handle for the messenger related functions and connects to all necessary services. It will look up the ego + * key identified by its name and use it for signing all messages from the handle. + * + * @param cfg Configuration to use + * @param name Name to look up an ego or NULL to stay anonymous + * @param identity_callback Function called when the EGO of the handle changes + * @param identity_cls Closure for the identity_callback handler + * @param msg_callback Function called when a new message is sent or received + * @param msg_cls Closure for the msg_callback handler + * @return Messenger handle to use, NULL on error + */ +struct GNUNET_MESSENGER_Handle* +GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, + GNUNET_MESSENGER_IdentityCallback identity_callback, void *identity_cls, + GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls); + +/** + * Update a handle of the messenger to use a different ego key and replace the old one with a newly generated one. All + * participated rooms get informed about the key renewal. The handle requires a set name for this function to work and + * it needs to be unused by other egos. + * + * Keep in mind that this will fully delete the old ego key (if any is used) even if any other service wants to use it + * as default. + * + * @param handle Messenger handle to use + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle); + +/** + * Disconnect all of the messengers used services and clears up its used memory. + * + * @param handle Messenger handle to use + */ +void +GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle); + +/** + * Get the name (if specified, otherwise NULL) used by the messenger. + * + * @param handle Messenger handle to use + * @return Name used by the messenger or NULL + */ +const char* +GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle); + +/** + * Set the name for the messenger. This will rename the currently used ego and move all stored files related to the current + * name to its new directory. If anything fails during this process the function returns GNUNET_NO and the name for + * the messenger won't change as specified. + * + * @param handle Messenger handle to use + * @param name Name for the messenger to change to + * @return GNUNET_YES on success, GNUNET_NO on failure and GNUNET_SYSERR if handle is NULL + */ +int +GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, const char *name); + +/** + * Get the public key used by the messenger. + * + * @param handle Messenger handle to use + * @return Used ego's public key + */ +const struct GNUNET_IDENTITY_PublicKey* +GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle); + +/** + * Open a room to send and receive messages. The room will use the specified key as port for the underlying cadet + * service. Opening a room results in opening the port for incoming connections as possible door. + * + * Notice that there can only be one room related to a specific key. So trying to open two rooms with the same + * key will result in opening the room once but returning the handle both times because the room stays open. + * + * You can also open a room after entering it through a door using GNUNET_MESSENGER_entry_room(...). This + * will notify all entered doors to list you as new door. + * + * ( All doors form a ring structured network to shorten the latency sending and receiving messages. ) + * + * @param handle Messenger handle to use + * @param key Hash identifying the port + * @return Room handle, NULL on error + */ +struct GNUNET_MESSENGER_Room* +GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key); + +/** + * Enter a room to send and receive messages through a door opened using GNUNET_MESSENGER_open_room(...). + * + * Notice that there can only be one room related to a specific key. So trying to enter two rooms with the same + * key will result in entering the room once but returning the handle both times because the room stays entered. + * You can however enter a room through multiple doors in parallel which results in connecting both ends. But + * entering the room through the same door won't have any effect after the first time. + * + * You can also enter a room through a door after opening it using GNUNET_MESSENGER_open_room(...). But the + * door may not be your own peer identity. + * + * ( All doors form a ring structured network to shorten the latency sending and receiving messages. ) + * + * @param handle Messenger handle to use + * @param door Peer identity of an open door + * @param key Hash identifying the port + * @return Room handle, NULL on error + */ +struct GNUNET_MESSENGER_Room* +GNUNET_MESSENGER_entry_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key); + +/** + * Close a room which was entered, opened or both in various order and variety. Closing a room will destroy all connections + * from your peer to another and the other way around. + * + * ( After a member closes a door, all members entered through that specific door have to use another one + * or open the room on their own. ) + * + * @param room Room handle + */ +void +GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room); + +/** + * Get the contact of a member in a room identified by their id. + * + * Notice that contacts are independent of rooms but will be removed if all rooms containing these contacts get closed. + * + * @param room Room handle + * @param id Hash identifying a member + * @return Contact handle, NULL if id is not in use + */ +struct GNUNET_MESSENGER_Contact* +GNUNET_MESSENGER_get_member (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_ShortHashCode *id); + +/** + * Get the name used by the contact. + * + * @param contact Contact handle + * @return Name of contact or NULL + */ +const char* +GNUNET_MESSENGER_contact_get_name (const struct GNUNET_MESSENGER_Contact *contact); + +/** + * Get the public key used by the contact. + * + * @param contact Contact handle + * @return Public key of the ego used by contact + */ +const struct GNUNET_IDENTITY_PublicKey* +GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact); + +/** + * Send a message into a room. If you opened the room all entered members will receive the + * message. If you entered the room through a door all so entered doors will receive the + * message as well. All members receiving the message will also propagate this message recursively + * as long as the message is unknown to them. + * + * Notice that all messages sent and received are also stored and can be propagated to new members entering the room. + * + * @param room Room handle + * @param message New message to send + */ +void +GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message); + +/** + * Get the message in a room identified by its hash. + * + * @param room Room handle + * @param hash Hash identifying a message + * @return Message struct or NULL if no message with that hash is known + */ +const struct GNUNET_MESSENGER_Message* +GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +#endif //GNUNET_MESSENGER_SERVICE_H + +/** @} *//* end of group */ diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h index 443c9e451..9cc8abc6e 100644 --- a/src/include/gnunet_namestore_plugin.h +++ b/src/include/gnunet_namestore_plugin.h @@ -58,7 +58,7 @@ typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls, uint64_t serial, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *private_key, + GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); @@ -87,7 +87,7 @@ struct GNUNET_NAMESTORE_PluginFunctions */ int (*store_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); @@ -104,7 +104,7 @@ struct GNUNET_NAMESTORE_PluginFunctions */ int (*lookup_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); @@ -126,7 +126,7 @@ struct GNUNET_NAMESTORE_PluginFunctions */ int (*iterate_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, @@ -146,8 +146,8 @@ struct GNUNET_NAMESTORE_PluginFunctions */ int (*zone_to_name) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, + const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); }; diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index bf42c8d34..ca4d2cb52 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h @@ -41,6 +41,7 @@ #include "gnunet_util_lib.h" #include "gnunet_block_lib.h" #include "gnunet_gnsrecord_lib.h" +#include "gnunet_identity_service.h" #ifdef __cplusplus extern "C" @@ -127,7 +128,7 @@ typedef void struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + GNUNET_IDENTITY_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, @@ -147,7 +148,7 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h, typedef void (*GNUNET_NAMESTORE_RecordMonitor) (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd); @@ -170,7 +171,7 @@ typedef void struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, @@ -197,9 +198,9 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h, */ struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const struct - GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, @@ -246,7 +247,7 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe); struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, @@ -316,7 +317,7 @@ struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index ca549f77c..de717526c 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2016, 2017 GNUnet e.V. + Copyright (C) 2016, 2017, 2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -87,6 +87,7 @@ struct GNUNET_PQ_QueryParam * Number of parameters eaten by this operation. */ unsigned int num_params; + }; @@ -99,21 +100,33 @@ struct GNUNET_PQ_QueryParam } +/** + * Generate query parameter to create a NULL value. + * + * @return query parameter to use to insert NULL into DB + */ +struct GNUNET_PQ_QueryParam +GNUNET_PQ_query_param_null (void); + + /** * Generate query parameter for a buffer @a ptr of * @a ptr_size bytes. * * @param ptr pointer to the query parameter to pass * @oaran ptr_size number of bytes in @a ptr + * @return query parameter to use */ struct GNUNET_PQ_QueryParam -GNUNET_PQ_query_param_fixed_size (const void *ptr, size_t ptr_size); +GNUNET_PQ_query_param_fixed_size (const void *ptr, + size_t ptr_size); /** * Generate query parameter for a string. * * @param ptr pointer to the string query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_string (const char *ptr); @@ -124,6 +137,7 @@ GNUNET_PQ_query_param_string (const char *ptr); * by variable type. * * @param x pointer to the query parameter to pass. + * @return query parameter to use */ #define GNUNET_PQ_query_param_auto_from_type(x) \ GNUNET_PQ_query_param_fixed_size ((x), sizeof(*(x))) @@ -134,6 +148,7 @@ GNUNET_PQ_query_param_string (const char *ptr); * database must contain a BLOB type in the respective position. * * @param x the query parameter to pass. + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_rsa_public_key ( @@ -145,6 +160,7 @@ GNUNET_PQ_query_param_rsa_public_key ( * database must contain a BLOB type in the respective position. * * @param x the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_rsa_signature ( @@ -156,6 +172,7 @@ GNUNET_PQ_query_param_rsa_signature ( * The database must store a 64-bit integer. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x); @@ -166,6 +183,7 @@ GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x); * The database must store a 64-bit integer. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); @@ -176,6 +194,7 @@ GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); * The database must store a 64-bit integer. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time_nbo ( @@ -186,6 +205,7 @@ GNUNET_PQ_query_param_absolute_time_nbo ( * Generate query parameter for an uint16_t in host byte order. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint16 (const uint16_t *x); @@ -195,6 +215,7 @@ GNUNET_PQ_query_param_uint16 (const uint16_t *x); * Generate query parameter for an uint32_t in host byte order. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint32 (const uint32_t *x); @@ -204,6 +225,7 @@ GNUNET_PQ_query_param_uint32 (const uint32_t *x); * Generate query parameter for an uint16_t in host byte order. * * @param x pointer to the query parameter to pass + * @return query parameter to use */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint64 (const uint64_t *x); @@ -288,6 +310,20 @@ struct GNUNET_PQ_ResultSpec * Where to store actual size of the result. */ size_t *result_size; + + /** + * True if NULL is allowed for a value in the database. + */ + bool is_nullable; + + /** + * Points to a location where we should store + * "true" if the result found is NULL, and + * otherwise "false". Only used if @e is_nullable + * is true. + */ + bool *is_null; + }; @@ -302,6 +338,21 @@ struct GNUNET_PQ_ResultSpec } +/** + * Allow NULL value to be found in the database + * for the given value. + * + * @param rs result spec entry to modify + * @param[out] is_null location set to 'true' if the + * value was indeed NULL, set to 'false' if the + * value was non-NULL + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +GNUNET_PQ_result_spec_allow_null (struct GNUNET_PQ_ResultSpec rs, + bool *is_null); + + /** * Variable-size result expected. * diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index d9821ffe8..3bdebeb50 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2001--2018 GNUnet e.V. + Copyright (C) 2001--2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -20,6 +20,7 @@ /** * @author Christian Grothoff + * @author Tobias Frisch * * @file * Constants for network protocols @@ -3518,6 +3519,46 @@ extern "C" { #define GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_RESULT 1501 +/*********************************************************************************/ +/********************************** MESSENGER **********************************/ +/*********************************************************************************/ +/* MESSENGER: message types 1600-1629 + * 1600-1609 Connection-level Messages + * 1610-1619 Room-level Messages + */ + +/********************************* Connection **********************************/ + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE 1600 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE 1601 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY 1602 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME 1603 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME 1604 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY 1605 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID 1606 + +/************************************ Room *************************************/ + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN 1610 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY 1611 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE 1612 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE 1614 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE 1615 + +#define GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE 1616 + +/*********************************************************************************/ + /** * Type used to match 'all' message types. */ diff --git a/src/include/gnunet_reclaim_service.h b/src/include/gnunet_reclaim_service.h index 368058f56..8549081a1 100644 --- a/src/include/gnunet_reclaim_service.h +++ b/src/include/gnunet_reclaim_service.h @@ -38,6 +38,7 @@ extern "C" { #endif #endif +#include "gnunet_identity_service.h" #include "gnunet_reclaim_lib.h" #include "gnunet_util_lib.h" @@ -69,12 +70,12 @@ struct GNUNET_RECLAIM_Ticket /** * The ticket issuer (= the user) */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; + struct GNUNET_IDENTITY_PublicKey identity; /** * The ticket audience (= relying party) */ - struct GNUNET_CRYPTO_EcdsaPublicKey audience; + struct GNUNET_IDENTITY_PublicKey audience; /** * The ticket random identifier @@ -129,7 +130,7 @@ typedef void (*GNUNET_RECLAIM_ContinuationWithStatus) (void *cls, * @param attr The attribute */ typedef void (*GNUNET_RECLAIM_AttributeResult) ( - void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + void *cls, const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr); /** @@ -141,7 +142,7 @@ typedef void (*GNUNET_RECLAIM_AttributeResult) ( * @param presentation The presentation for the credential (may be NULL) */ typedef void (*GNUNET_RECLAIM_AttributeTicketResult) ( - void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + void *cls, const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *presentation); @@ -155,7 +156,7 @@ typedef void (*GNUNET_RECLAIM_AttributeTicketResult) ( * @param attributes the parsed attributes */ typedef void (*GNUNET_RECLAIM_CredentialResult) ( - void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + void *cls, const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Credential *credential); @@ -184,7 +185,7 @@ GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_store ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_TIME_Relative *exp_interval, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); @@ -205,7 +206,7 @@ GNUNET_RECLAIM_attribute_store ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_credential_store ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Credential *credential, const struct GNUNET_TIME_Relative *exp_interval, GNUNET_RECLAIM_ContinuationWithStatus cont, @@ -226,7 +227,7 @@ GNUNET_RECLAIM_credential_store ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_delete ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Attribute *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); @@ -244,7 +245,7 @@ GNUNET_RECLAIM_attribute_delete ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_credential_delete ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Credential *cred, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls); @@ -276,7 +277,7 @@ GNUNET_RECLAIM_credential_delete ( struct GNUNET_RECLAIM_AttributeIterator * GNUNET_RECLAIM_get_attributes_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_AttributeResult proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls); @@ -332,7 +333,7 @@ GNUNET_RECLAIM_get_attributes_stop ( struct GNUNET_RECLAIM_CredentialIterator * GNUNET_RECLAIM_get_credentials_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_CredentialResult proc, @@ -380,8 +381,8 @@ GNUNET_RECLAIM_get_credentials_stop ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, - const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, + const struct GNUNET_IDENTITY_PrivateKey *iss, + const struct GNUNET_IDENTITY_PublicKey *rp, const struct GNUNET_RECLAIM_AttributeList *attrs, GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls); @@ -402,7 +403,7 @@ GNUNET_RECLAIM_ticket_issue ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_revoke ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_ContinuationWithStatus cb, void *cb_cls); @@ -422,7 +423,7 @@ GNUNET_RECLAIM_ticket_revoke ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls); @@ -447,7 +448,7 @@ GNUNET_RECLAIM_ticket_consume ( struct GNUNET_RECLAIM_TicketIterator * GNUNET_RECLAIM_ticket_iteration_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_TicketCallback proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls); diff --git a/src/include/gnunet_revocation_service.h b/src/include/gnunet_revocation_service.h index 105bb1149..d56116914 100644 --- a/src/include/gnunet_revocation_service.h +++ b/src/include/gnunet_revocation_service.h @@ -21,6 +21,8 @@ #ifndef GNUNET_REVOCATION_SERVICE_H_ #define GNUNET_REVOCATION_SERVICE_H_ +#include "gnunet_identity_service.h" + /** * @author Christian Grothoff * @@ -50,6 +52,13 @@ extern "C" */ #define GNUNET_REVOCATION_VERSION 0x00000001 +/** + * Maximum length of a revocation + */ +#define GNUNET_REVOCATION_MAX_PROOF_SIZE sizeof(struct GNUNET_REVOCATION_PowP) +\ + sizeof(struct GNUNET_IDENTITY_PublicKey) +\ + 1024 //FIXME max sig_len + /** * The proof-of-work narrowing factor. * The number of PoWs that are calculates as part of revocation. @@ -79,15 +88,7 @@ struct GNUNET_REVOCATION_PowP */ uint64_t pow[POW_COUNT] GNUNET_PACKED; - /** - * The signature - */ - struct GNUNET_CRYPTO_EcdsaSignature signature; - - /** - * The revoked public key - */ - struct GNUNET_CRYPTO_EcdsaPublicKey key; + /** followed by the public key type, the key and a signature **/ }; @@ -101,15 +102,12 @@ struct GNUNET_REVOCATION_SignaturePurposePS */ struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - /** - * The revoked public key - */ - struct GNUNET_CRYPTO_EcdsaPublicKey key; - /** * The timestamp of the revocation */ struct GNUNET_TIME_AbsoluteNBO timestamp; + + /** Followed by the zone public key type and key **/ }; GNUNET_NETWORK_STRUCT_END @@ -150,7 +148,7 @@ typedef void (*GNUNET_REVOCATION_Callback) (void *cls, */ struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_CRYPTO_EcdsaPublicKey *key, + const struct GNUNET_IDENTITY_PublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls); @@ -217,7 +215,7 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, * @param pow the pow object to work with in the calculation. */ void -GNUNET_REVOCATION_pow_init (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +GNUNET_REVOCATION_pow_init (const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_REVOCATION_PowP *pow); @@ -256,6 +254,10 @@ GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc); void GNUNET_REVOCATION_pow_stop (struct GNUNET_REVOCATION_PowCalculationHandle *pc); +size_t +GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/include/gnunet_uri_lib.h b/src/include/gnunet_uri_lib.h index d428bdd9a..57c9e9316 100644 --- a/src/include/gnunet_uri_lib.h +++ b/src/include/gnunet_uri_lib.h @@ -26,12 +26,13 @@ /** * The struct where the parsed values will be stored: * - * scheme ":" [ "//" ] [ username ":" password "@" ] host [ ":" port ] [ "/" ] [ path ] [ "?" query ] + * scheme ":" [ "//" ] [ username ":" password "@" ] host [ ":" port ] [ "/" ] [ path ] [ "?" query ] [ "#" fragment ] * * Note: to make sure that no strings are copied, the first slash "/" in the * path will be used to null terminate the hostname if no port is supplied. */ -struct GNUNET_Uri { +struct GNUNET_Uri +{ char *scheme; /* scheme, without ":" and "//" */ char *username; /* username, default: NULL */ char *password; /* password, default: NULL */ @@ -44,7 +45,8 @@ struct GNUNET_Uri { /* A struct to hold the query string parameter values. */ -struct GNUNET_UriParam { +struct GNUNET_UriParam +{ char *key; char *val; }; diff --git a/src/json/Makefile.am b/src/json/Makefile.am index 2ed05c35a..d4ea38adf 100644 --- a/src/json/Makefile.am +++ b/src/json/Makefile.am @@ -18,18 +18,15 @@ libgnunetjson_la_SOURCES = \ json.c \ json_mhd.c \ json_generator.c \ - json_helper.c \ - json_gnsrecord.c + json_helper.c libgnunetjson_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ -ljansson \ $(MHD_LIBS) \ $(XLIB) \ $(Z_LIBS) libgnunetjson_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la + $(top_builddir)/src/util/libgnunetutil.la check_PROGRAMS = \ diff --git a/src/json/json.c b/src/json/json.c index 0631c51bb..503702962 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -56,11 +56,17 @@ GNUNET_JSON_parse (const json_t *root, if (NULL == spec[i].field) pos = (json_t *) root; else - pos = json_object_get (root, spec[i].field); - if ((NULL == pos) && (spec[i].is_optional)) + pos = json_object_get (root, + spec[i].field); + if ( ( (NULL == pos) || + (json_is_null (pos) ) ) && + (spec[i].is_optional) ) continue; - if ((NULL == pos) || - (GNUNET_OK != spec[i].parser (spec[i].cls, pos, &spec[i]))) + if ( (NULL == pos) || + (GNUNET_OK != + spec[i].parser (spec[i].cls, + pos, + &spec[i])) ) { if (NULL != error_json_name) *error_json_name = spec[i].field; diff --git a/src/json/json_generator.c b/src/json/json_generator.c index 3f82a5f17..5806eb174 100644 --- a/src/json/json_generator.c +++ b/src/json/json_generator.c @@ -201,113 +201,5 @@ GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig) } -/** - * Convert GNS record to JSON. - * - * @param rname name of record - * @param rd record data - * @return corresponding JSON encoding - */ -json_t * -GNUNET_JSON_from_gnsrecord (const char*rname, - const struct GNUNET_GNSRECORD_Data *rd, - unsigned int rd_count) -{ - struct GNUNET_TIME_Absolute abs_exp; - struct GNUNET_TIME_Relative rel_exp; - const char *expiration_time_str; - const char *record_type_str; - char *value_str; - json_t *data; - json_t *record; - json_t *records; - - data = json_object (); - if (NULL == data) - { - GNUNET_break (0); - return NULL; - } - if (0 != - json_object_set_new (data, - "record_name", - json_string (rname))) - { - GNUNET_break (0); - json_decref (data); - return NULL; - } - records = json_array (); - if (NULL == records) - { - GNUNET_break (0); - json_decref (data); - return NULL; - } - for (int i = 0; i < rd_count; i++) - { - value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, - rd[i].data, - rd[i].data_size); - if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd[i].flags) - { - rel_exp.rel_value_us = rd[i].expiration_time; - expiration_time_str = GNUNET_STRINGS_relative_time_to_string (rel_exp, - GNUNET_NO); - } - else - { - abs_exp.abs_value_us = rd[i].expiration_time; - expiration_time_str = GNUNET_STRINGS_absolute_time_to_string (abs_exp); - } - record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Packing %s %s %s %d\n", - value_str, record_type_str, expiration_time_str, rd[i].flags); - record = json_pack ("{s:s,s:s,s:s,s:b,s:b,s:b,s:b}", - "value", - value_str, - "record_type", - record_type_str, - "expiration_time", - expiration_time_str, - "private", - rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE, - "relative_expiration", - rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, - "supplemental", - rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL, - "shadow", - rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD); - GNUNET_free (value_str); - if (NULL == record) - { - GNUNET_break (0); - json_decref (records); - json_decref (data); - return NULL; - } - if (0 != - json_array_append_new (records, - record)) - { - GNUNET_break (0); - json_decref (records); - json_decref (data); - return NULL; - } - } - if (0 != - json_object_set_new (data, - "data", - records)) - { - GNUNET_break (0); - json_decref (data); - return NULL; - } - return data; -} - /* End of json/json_generator.c */ diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c deleted file mode 100644 index 7e11aba94..000000000 --- a/src/json/json_gnsrecord.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009-2013 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ - -/** - * @file json/json_gnsrecord.c - * @brief JSON handling of GNS record data - * @author Philippe Buschmann - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_json_lib.h" - -#define GNUNET_JSON_GNSRECORD_VALUE "value" -#define GNUNET_JSON_GNSRECORD_RECORD_DATA "data" -#define GNUNET_JSON_GNSRECORD_TYPE "record_type" -#define GNUNET_JSON_GNSRECORD_EXPIRATION_TIME "expiration_time" -#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE "private" -#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL "supplemental" -#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE "relative_expiration" -#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW "shadow" -#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name" -#define GNUNET_JSON_GNSRECORD_NEVER "never" - -struct GnsRecordInfo -{ - char **name; - - unsigned int *rd_count; - - struct GNUNET_GNSRECORD_Data **rd; -}; - - -static void -cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info) -{ - char *tmp; - - if (NULL != *(gnsrecord_info->rd)) - { - for (int i = 0; i < *(gnsrecord_info->rd_count); i++) - { - tmp = (char*) (*(gnsrecord_info->rd))[i].data; - if (NULL != tmp) - GNUNET_free (tmp); - } - GNUNET_free (*(gnsrecord_info->rd)); - *(gnsrecord_info->rd) = NULL; - } - if (NULL != *(gnsrecord_info->name)) - GNUNET_free (*(gnsrecord_info->name)); - *(gnsrecord_info->name) = NULL; -} - - -/** - * Parse given JSON object to gns record - * - * @param cls closure, NULL - * @param root the json object representing data - * @param spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_record (json_t *data, struct GNUNET_GNSRECORD_Data *rd) -{ - struct GNUNET_TIME_Absolute abs_expiration_time; - struct GNUNET_TIME_Relative rel_expiration_time; - const char *value; - const char *record_type; - const char *expiration_time; - int private; - int supplemental; - int rel_exp; - int shadow; - int unpack_state = 0; - - // interpret single gns record - unpack_state = json_unpack (data, - "{s:s, s:s, s:s, s:b, s:b, s:b, s:b}", - GNUNET_JSON_GNSRECORD_VALUE, - &value, - GNUNET_JSON_GNSRECORD_TYPE, - &record_type, - GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, - &expiration_time, - GNUNET_JSON_GNSRECORD_FLAG_PRIVATE, - &private, - GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL, - &supplemental, - GNUNET_JSON_GNSRECORD_FLAG_RELATIVE, - &rel_exp, - GNUNET_JSON_GNSRECORD_FLAG_SHADOW, - &shadow); - if (0 != unpack_state) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error gnsdata object has a wrong format!\n"); - return GNUNET_SYSERR; - } - rd->record_type = GNUNET_GNSRECORD_typename_to_number (record_type); - if (UINT32_MAX == rd->record_type) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n"); - return GNUNET_SYSERR; - } - if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (rd->record_type, - value, - (void **) &rd->data, - &rd->data_size)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n"); - return GNUNET_SYSERR; - } - - if (0 == strcmp (expiration_time, GNUNET_JSON_GNSRECORD_NEVER)) - { - rd->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; - } - else if ((1 != rel_exp) && - (GNUNET_OK == - GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, - &abs_expiration_time))) - { - rd->expiration_time = abs_expiration_time.abs_value_us; - } - else if (GNUNET_OK == - GNUNET_STRINGS_fancy_time_to_relative (expiration_time, - &rel_expiration_time)) - { - rd->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; - rd->expiration_time = rel_expiration_time.rel_value_us; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration time invalid\n"); - return GNUNET_SYSERR; - } - if (1 == private) - rd->flags |= GNUNET_GNSRECORD_RF_PRIVATE; - if (1 == supplemental) - rd->flags |= GNUNET_GNSRECORD_RF_SUPPLEMENTAL; - if (1 == shadow) - rd->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; - return GNUNET_OK; -} - - -/** - * Parse given JSON object to gns record - * - * @param cls closure, NULL - * @param root the json object representing data - * @param spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data) -{ - GNUNET_assert (NULL != data); - if (! json_is_array (data)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error gns record data JSON is not an array!\n"); - return GNUNET_SYSERR; - } - *(gnsrecord_info->rd_count) = json_array_size (data); - *(gnsrecord_info->rd) = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Data) - * json_array_size (data)); - size_t index; - json_t *value; - json_array_foreach (data, index, value) - { - if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index])) - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -static int -parse_gnsrecordobject (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct GnsRecordInfo *gnsrecord_info; - int unpack_state = 0; - const char *name; - json_t *data; - - GNUNET_assert (NULL != root); - if (! json_is_object (root)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error record JSON is not an object!\n"); - return GNUNET_SYSERR; - } - // interpret single gns record - unpack_state = json_unpack (root, - "{s:s, s:o!}", - GNUNET_JSON_GNSRECORD_RECORD_NAME, - &name, - GNUNET_JSON_GNSRECORD_RECORD_DATA, - &data); - if (0 != unpack_state) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error namestore records object has a wrong format!\n"); - return GNUNET_SYSERR; - } - gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; - *(gnsrecord_info->name) = GNUNET_strdup (name); - if (GNUNET_OK != parse_record_data (gnsrecord_info, data)) - { - cleanup_recordinfo (gnsrecord_info); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing the record. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_gnsrecordobject (void *cls, struct GNUNET_JSON_Specification *spec) -{ - struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr; - - GNUNET_free (gnsrecord_info); -} - - -/** - * JSON Specification for GNS Records. - * - * @param gnsrecord_object struct of GNUNET_GNSRECORD_Data to fill - * @return JSON Specification - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_gnsrecord (struct GNUNET_GNSRECORD_Data **rd, - unsigned int *rd_count, - char **name) -{ - struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo); - - gnsrecord_info->rd = rd; - gnsrecord_info->name = name; - gnsrecord_info->rd_count = rd_count; - struct GNUNET_JSON_Specification ret = { .parser = &parse_gnsrecordobject, - .cleaner = &clean_gnsrecordobject, - .cls = NULL, - .field = NULL, - .ptr = (struct GnsRecordInfo *) - gnsrecord_info, - .ptr_size = 0, - .size_ptr = NULL }; - return ret; -} diff --git a/src/messenger/.gitignore b/src/messenger/.gitignore new file mode 100644 index 000000000..9de3fb304 --- /dev/null +++ b/src/messenger/.gitignore @@ -0,0 +1,4 @@ +gnunet-service-messenger +gnunet-messenger +test_messenger_api +test_messenger_anonymous diff --git a/src/messenger/Makefile.am b/src/messenger/Makefile.am new file mode 100644 index 000000000..ebe08290e --- /dev/null +++ b/src/messenger/Makefile.am @@ -0,0 +1,131 @@ +# This Makefile.am is in the public domain +AM_CPPFLAGS = -I$(top_srcdir)/src/include + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 + XLIB = -lgcov +endif + +pkgcfgdir= $(pkgdatadir)/config.d/ + +libexecdir= $(pkglibdir)/libexec/ + +pkgcfg_DATA = \ + messenger.conf + +plugindir = $(libdir)/gnunet + +AM_CLFAGS = -g + +libexec_PROGRAMS = \ + gnunet-service-messenger \ + $(EXP_LIBEXEC) + +bin_PROGRAMS = \ + gnunet-messenger + +lib_LTLIBRARIES = \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(EXP_LIB) + +libgnunetmessenger_common_la_SOURCES = \ + messenger_api_ego.h \ + messenger_api_message.c messenger_api_message.h \ + messenger_api_list_tunnels.c messenger_api_list_tunnels.h +libgnunetmessenger_common_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + $(XLIB) \ + $(LTLIBINTL) +libgnunetmessenger_common_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +libgnunetmessenger_la_SOURCES = \ + messenger_api.c \ + messenger_api_contact.c messenger_api_contact.h \ + messenger_api_handle.c messenger_api_handle.h \ + messenger_api_room.c messenger_api_room.h +libgnunetmessenger_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + libgnunetmessenger_common.la \ + $(XLIB) \ + $(LTLIBINTL) +libgnunetmessenger_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) \ + -version-info 0:0:0 + +gnunet_messenger_SOURCES = \ + gnunet-messenger.c +gnunet_messenger_LDADD = \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(top_builddir)/src/util/libgnunetutil.la +gnunet_messenger_LDFLAGS = \ + $(GN_LIBINTL) + +gnunet_service_messenger_SOURCES = \ + gnunet-service-messenger.c gnunet-service-messenger.h \ + gnunet-service-messenger_service.c gnunet-service-messenger_service.h \ + gnunet-service-messenger_list_handles.c gnunet-service-messenger_list_handles.h \ + gnunet-service-messenger_list_messages.c gnunet-service-messenger_list_messages.h \ + gnunet-service-messenger_message_handle.c gnunet-service-messenger_message_handle.h \ + gnunet-service-messenger_message_kind.c gnunet-service-messenger_message_kind.h \ + gnunet-service-messenger_message_recv.c gnunet-service-messenger_message_recv.h \ + gnunet-service-messenger_message_send.c gnunet-service-messenger_message_send.h \ + gnunet-service-messenger_message_store.c gnunet-service-messenger_message_store.h \ + gnunet-service-messenger_basement.c gnunet-service-messenger_basement.h \ + gnunet-service-messenger_contact.c gnunet-service-messenger_contact.h \ + gnunet-service-messenger_handle.c gnunet-service-messenger_handle.h \ + gnunet-service-messenger_room.c gnunet-service-messenger_room.h \ + gnunet-service-messenger_tunnel.c gnunet-service-messenger_tunnel.h \ + gnunet-service-messenger_util.c gnunet-service-messenger_util.h +gnunet_service_messenger_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/cadet/libgnunetcadet.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(GN_LIBINTL) + +check_PROGRAMS = \ + test_messenger_api \ + test_messenger_anonymous \ + test_messenger_comm0 + +if ENABLE_TEST_RUN +AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; +TESTS = \ + $(check_PROGRAMS) +endif + +test_messenger_api_SOURCES = \ + test_messenger.c +test_messenger_api_LDADD = \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_messenger_anonymous_SOURCES = \ + test_messenger_anonymous.c +test_messenger_anonymous_LDADD = \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_messenger_comm0_SOURCES = \ + test_messenger_comm0.c +test_messenger_comm0_LDADD = \ + libgnunetmessenger_common.la \ + libgnunetmessenger.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/testbed-logger/libgnunettestbedlogger.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/util/libgnunetutil.la + +EXTRA_DIST = \ + test_messenger_api.conf diff --git a/src/messenger/gnunet-messenger.c b/src/messenger/gnunet-messenger.c new file mode 100644 index 000000000..579e5c3ad --- /dev/null +++ b/src/messenger/gnunet-messenger.c @@ -0,0 +1,306 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-messenger.c + * @brief Print information about messenger groups. + */ + +#include + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_messenger_service.h" + +struct GNUNET_MESSENGER_Handle *messenger; + +/** + * Function called whenever a message is received or sent. + * + * @param cls Closure + * @param room Room + * @param message Message + * @param hash Hash of message + */ +void +on_message (void *cls, const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Contact *sender = GNUNET_MESSENGER_get_member (room, &(message->header.sender_id)); + + const char *sender_name = GNUNET_MESSENGER_contact_get_name (sender); + + if (!sender_name) + sender_name = "anonymous"; + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_JOIN: + { + printf ("* '%s' joined the room! [ %u %u %u %u ]\n", sender_name, message->body.join.key.ecdsa_key.q_y[0], + message->body.join.key.ecdsa_key.q_y[1], message->body.join.key.ecdsa_key.q_y[2], + message->body.join.key.ecdsa_key.q_y[3]); + break; + } + case GNUNET_MESSENGER_KIND_LEAVE: + { + printf ("* '%s' leaves the room!\n", sender_name); + break; + } + case GNUNET_MESSENGER_KIND_PEER: + { + printf ("* '%s' opened the room on: %s\n", sender_name, GNUNET_i2s_full (&(message->body.peer.peer))); + break; + } + case GNUNET_MESSENGER_KIND_TEXT: + { + printf ("* '%s' says: \"%s\"\n", sender_name, message->body.text.text); + break; + } + default: + { + break; + } + } +} + +struct GNUNET_SCHEDULER_Task *read_task; + +/** + * Task to shut down this application. + * + * @param cls Closure + */ +static void +shutdown_hook (void *cls) +{ + struct GNUNET_MESSENGER_Room *room = cls; + + if (read_task) + GNUNET_SCHEDULER_cancel (read_task); + + if (room) + GNUNET_MESSENGER_close_room (room); + + if (messenger) + GNUNET_MESSENGER_disconnect (messenger); +} + +static void +listen_stdio (void *cls); + +#define MAX_BUFFER_SIZE 60000 + +/** + * Task run in stdio mode, after some data is available at stdin. + * + * @param cls Closure + */ +static void +read_stdio (void *cls) +{ + read_task = NULL; + + char buffer[MAX_BUFFER_SIZE]; + ssize_t length; + + length = read (0, buffer, MAX_BUFFER_SIZE); + + if ((length <= 0) || (length >= MAX_BUFFER_SIZE)) + { + GNUNET_SCHEDULER_shutdown (); + return; + } + + if (buffer[length - 1] == '\n') + buffer[length - 1] = '\0'; + else + buffer[length] = '\0'; + + struct GNUNET_MESSENGER_Room *room = cls; + + struct GNUNET_MESSENGER_Message message; + message.header.kind = GNUNET_MESSENGER_KIND_TEXT; + message.body.text.text = buffer; + + GNUNET_MESSENGER_send_message (room, &message); + + read_task = GNUNET_SCHEDULER_add_now (listen_stdio, cls); +} + +/** + * Wait for input on STDIO and send it out over the #ch. + * + * @param cls Closure + */ +static void +listen_stdio (void *cls) +{ + read_task = NULL; + + struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create (); + + GNUNET_NETWORK_fdset_set_native (rs, 0); + + read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_TIME_UNIT_FOREVER_REL, + rs, + NULL, + &read_stdio, cls); + + GNUNET_NETWORK_fdset_destroy (rs); +} + +/** + * Initial task to startup application. + * + * @param cls Closure + */ +static void +idle (void *cls) +{ + struct GNUNET_MESSENGER_Room *room = cls; + + printf ("* You joined the room.\n"); + + read_task = GNUNET_SCHEDULER_add_now (listen_stdio, room); +} + +char *door_id; +char *ego_name; +char *room_key; + +struct GNUNET_SCHEDULER_Task *shutdown_task; + +/** + * Function called when an identity is retrieved. + * + * @param cls Closure + * @param handle Handle of messenger service + */ +static void +on_identity (void *cls, struct GNUNET_MESSENGER_Handle *handle) +{ + struct GNUNET_HashCode key; + memset (&key, 0, sizeof(key)); + + if (room_key) + GNUNET_CRYPTO_hash (room_key, strlen (room_key), &key); + + struct GNUNET_PeerIdentity *door = NULL; + + if (door_id) + { + door = GNUNET_new(struct GNUNET_PeerIdentity); + + if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (door_id, strlen (door_id), &(door->public_key))) + { + GNUNET_free(door); + door = NULL; + } + } + + const char *name = GNUNET_MESSENGER_get_name (handle); + + if (!name) + name = "anonymous"; + + printf ("* Welcome to the messenger, '%s'!\n", name); + + struct GNUNET_MESSENGER_Room *room; + + if (door) + { + printf ("* You try to entry a room...\n"); + + room = GNUNET_MESSENGER_entry_room (messenger, door, &key); + } + else + { + printf ("* You try to open a room...\n"); + + room = GNUNET_MESSENGER_open_room (messenger, &key); + } + + GNUNET_SCHEDULER_cancel (shutdown_task); + + shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, room); + + if (!room) + GNUNET_SCHEDULER_shutdown (); + else + GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_zero_ (), GNUNET_SCHEDULER_PRIORITY_IDLE, idle, + room); +} + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const*args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + messenger = GNUNET_MESSENGER_connect (cfg, ego_name, &on_identity, NULL, &on_message, NULL); + + shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, NULL); +} + +/** + * The main function to obtain messenger information. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char **argv) +{ + const char *description = "Open and connect to rooms using the MESSENGER to chat."; + + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('d', + "door", + "PEERIDENTITY", + "peer identity to entry into the room", + &door_id), + GNUNET_GETOPT_option_string ('e', + "ego", + "IDENTITY", + "identity to use for messaging", + &ego_name), + GNUNET_GETOPT_option_string ('r', + "room", + "ROOMKEY", + "key of the room to connect to", + &room_key), + GNUNET_GETOPT_OPTION_END }; + + return (GNUNET_OK == GNUNET_PROGRAM_run (argc, + argv, + "gnunet-messenger\0", + gettext_noop(description), + options, + &run, + NULL) ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/src/messenger/gnunet-service-messenger.c b/src/messenger/gnunet-service-messenger.c new file mode 100644 index 000000000..2c92305c4 --- /dev/null +++ b/src/messenger/gnunet-service-messenger.c @@ -0,0 +1,306 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger.h" + +#include "gnunet-service-messenger_service.h" +#include "messenger_api_message.h" + +struct GNUNET_MESSENGER_Client +{ + struct GNUNET_SERVICE_Client *client; + struct GNUNET_MESSENGER_SrvHandle *handle; +}; + +struct GNUNET_MESSENGER_Service *messenger; + +static int +check_create (void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg) +{ + GNUNET_MQ_check_zero_termination(msg); + return GNUNET_OK; +} + +static void +handle_create (void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + const char *name = ((const char*) msg) + sizeof(*msg); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle created with name: %s\n", name); + + setup_handle_name (msg_client->handle, strlen (name) > 0? name : NULL); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_update (void *cls, const struct GNUNET_MESSENGER_UpdateMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + if (GNUNET_OK != update_handle (msg_client->handle)) + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Name is required to update key!\n"); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_destroy (void *cls, const struct GNUNET_MESSENGER_DestroyMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + GNUNET_SERVICE_client_drop (msg_client->client); +} + +static int +check_set_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) +{ + GNUNET_MQ_check_zero_termination(msg); + return GNUNET_OK; +} + +static void +handle_set_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + const char *name = ((const char*) msg) + sizeof(*msg); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handles name is now: %s\n", name); + + if (GNUNET_YES != set_handle_name (msg_client->handle, name)) + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No valid name: %s\n", name); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_room_open (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room: %s\n", + GNUNET_h2s (&(msg->key))); + + if (GNUNET_YES == open_handle_room (msg_client->handle, &(msg->key))) + { + const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room with member id: %s\n", + GNUNET_sh2s (member_id)); + + struct GNUNET_MESSENGER_RoomMessage *response; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); + GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); + GNUNET_MQ_send (msg_client->handle->mq, env); + } + else + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Opening room failed: %s\n", + GNUNET_h2s (&(msg->key))); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_room_entry (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room: %s, %s\n", + GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door))); + + if (GNUNET_YES == entry_handle_room (msg_client->handle, &(msg->door), &(msg->key))) + { + const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room with member id: %s\n", + GNUNET_sh2s (member_id)); + + struct GNUNET_MESSENGER_RoomMessage *response; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); + GNUNET_memcpy(&(response->door), &(msg->door), sizeof(msg->door)); + GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); + GNUNET_MQ_send (msg_client->handle->mq, env); + } + else + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Entrance into room failed: %s, %s\n", + GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door))); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_room_close (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room: %s\n", GNUNET_h2s (&(msg->key))); + + if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key))) + { + const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room with member id: %s\n", + GNUNET_sh2s (member_id)); + + struct GNUNET_MESSENGER_RoomMessage *response; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); + GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); + GNUNET_MQ_send (msg_client->handle->mq, env); + } + else + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Closing room failed: %s\n", GNUNET_h2s (&(msg->key))); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static int +check_send_message (void *cls, const struct GNUNET_MESSENGER_SendMessage *msg) +{ + const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header); + + if (full_length < sizeof(msg->key)) + return GNUNET_NO; + + const uint16_t length = full_length - sizeof(msg->key); + const char *buffer = ((const char*) msg) + sizeof(*msg); + + struct GNUNET_MESSENGER_Message message; + + if (GNUNET_YES != decode_message (&message, length, buffer)) + return GNUNET_NO; + + return GNUNET_OK; +} + +static void +handle_send_message (void *cls, const struct GNUNET_MESSENGER_SendMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + const struct GNUNET_HashCode *key = &(msg->key); + const char *buffer = ((const char*) msg) + sizeof(*msg); + + const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); + + struct GNUNET_MESSENGER_Message message; + decode_message (&message, length, buffer); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s\n", + GNUNET_MESSENGER_name_of_kind (message.header.kind), + GNUNET_h2s (key)); + + if (GNUNET_YES != send_handle_message (msg_client->handle, key, &message)) + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message failed: %s to %s\n", + GNUNET_MESSENGER_name_of_kind (message.header.kind), + GNUNET_h2s (key)); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void +handle_get_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg) +{ + struct GNUNET_MESSENGER_Client *msg_client = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Requesting message from room: %s\n", + GNUNET_h2s (&(msg->key))); + + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (messenger, &(msg->key)); + + if (room) + get_room_message (room, msg_client->handle, &(msg->hash), GNUNET_YES); + else + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Room not found: %s\n", + GNUNET_h2s (&(msg->key))); + + GNUNET_SERVICE_client_continue (msg_client->client); +} + +static void* +callback_client_connect (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq) +{ + struct GNUNET_MESSENGER_Client *msg_client = GNUNET_new(struct GNUNET_MESSENGER_Client); + + msg_client->client = client; + msg_client->handle = add_service_handle (messenger, mq); + + return msg_client; +} + +static void +callback_client_disconnect (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls) +{ + struct GNUNET_MESSENGER_Client *msg_client = internal_cls; + + remove_service_handle (messenger, msg_client->handle); + + GNUNET_free(msg_client); +} + +/** + * Setup MESSENGER internals. + * + * @param cls closure + * @param config configuration to use + * @param service the initialized service + */ +static void +run (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service) +{ + messenger = create_service (config, service); + + if ((!messenger) || (!messenger->cadet) || (!messenger->identity)) + GNUNET_SCHEDULER_shutdown (); +} + +/** + * Define "main" method using service macro. + */ +GNUNET_SERVICE_MAIN( + GNUNET_MESSENGER_SERVICE_NAME, + GNUNET_SERVICE_OPTION_NONE, + &run, + &callback_client_connect, + &callback_client_disconnect, + NULL, + GNUNET_MQ_hd_var_size( create, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE, struct GNUNET_MESSENGER_CreateMessage, NULL ), + GNUNET_MQ_hd_fixed_size( update, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE, struct GNUNET_MESSENGER_UpdateMessage, NULL ), + GNUNET_MQ_hd_fixed_size( destroy, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY, struct GNUNET_MESSENGER_DestroyMessage, NULL ), + GNUNET_MQ_hd_var_size( set_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME, struct GNUNET_MESSENGER_NameMessage, NULL ), + GNUNET_MQ_hd_fixed_size( room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, struct GNUNET_MESSENGER_RoomMessage, NULL ), + GNUNET_MQ_hd_fixed_size( room_entry, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, struct GNUNET_MESSENGER_RoomMessage, NULL ), + GNUNET_MQ_hd_fixed_size( room_close, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, struct GNUNET_MESSENGER_RoomMessage, NULL ), + GNUNET_MQ_hd_var_size( send_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE, struct GNUNET_MESSENGER_SendMessage, NULL ), + GNUNET_MQ_hd_fixed_size( get_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE, struct GNUNET_MESSENGER_RecvMessage, NULL ), + GNUNET_MQ_handler_end()); diff --git a/src/messenger/gnunet-service-messenger.h b/src/messenger/gnunet-service-messenger.h new file mode 100644 index 000000000..85a1d2549 --- /dev/null +++ b/src/messenger/gnunet-service-messenger.h @@ -0,0 +1,121 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_H +#define GNUNET_SERVICE_MESSENGER_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_mq_lib.h" +#include "gnunet_peer_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_util_lib.h" + +/** + * Message to create a handle for a client + */ +struct GNUNET_MESSENGER_CreateMessage +{ + struct GNUNET_MessageHeader header; +}; + +/** + * Message to update the handle (its EGO key) for a client + */ +struct GNUNET_MESSENGER_UpdateMessage +{ + struct GNUNET_MessageHeader header; +}; + +/** + * Message to destroy the handle for a client + */ +struct GNUNET_MESSENGER_DestroyMessage +{ + struct GNUNET_MessageHeader header; +}; + +/** + * Message to receive the current name of a handle + */ +struct GNUNET_MESSENGER_NameMessage +{ + struct GNUNET_MessageHeader header; +}; + +/** + * Message to receive the current public key of a handle + */ +struct GNUNET_MESSENGER_KeyMessage +{ + struct GNUNET_MessageHeader header; + struct GNUNET_IDENTITY_PublicKey pubkey; +}; + +/** + * General message to confirm interaction with a room + */ +struct GNUNET_MESSENGER_RoomMessage +{ + struct GNUNET_MessageHeader header; + + struct GNUNET_PeerIdentity door; + struct GNUNET_HashCode key; +}; + +/** + * Message to receive the current member id of a handle in room + */ +struct GNUNET_MESSENGER_MemberMessage +{ + struct GNUNET_MessageHeader header; + + struct GNUNET_HashCode key; + struct GNUNET_ShortHashCode id; +}; + +/** + * Message to send something into a room + */ +struct GNUNET_MESSENGER_SendMessage +{ + struct GNUNET_MessageHeader header; + struct GNUNET_HashCode key; +}; + +/** + * Message to receive something from a room + */ +struct GNUNET_MESSENGER_RecvMessage +{ + struct GNUNET_MessageHeader header; + struct GNUNET_HashCode key; + struct GNUNET_HashCode hash; +}; + +#endif //GNUNET_SERVICE_MESSENGER_H diff --git a/src/messenger/gnunet-service-messenger_basement.c b/src/messenger/gnunet-service-messenger_basement.c new file mode 100644 index 000000000..190cf2de5 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_basement.c @@ -0,0 +1,58 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_basement.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_basement.h" + +size_t +count_of_tunnels (const struct GNUNET_MESSENGER_ListTunnels *tunnels) +{ + const struct GNUNET_MESSENGER_ListTunnel *element; + size_t count = 0; + + for (element = tunnels->head; element; element = element->next) + count++; + + return count; +} + +int +should_connect_tunnel_to (size_t count, size_t src, size_t dst) +{ + if ((src + 1) % count == dst % count) + return GNUNET_YES; + + return GNUNET_NO; +} + +int +required_connection_between (size_t count, size_t src, size_t dst) +{ + if (GNUNET_YES == should_connect_tunnel_to (count, src, dst)) + return GNUNET_YES; + if (GNUNET_YES == should_connect_tunnel_to (count, dst, src)) + return GNUNET_YES; + + return GNUNET_NO; +} diff --git a/src/messenger/gnunet-service-messenger_basement.h b/src/messenger/gnunet-service-messenger_basement.h new file mode 100644 index 000000000..0a1a9b126 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_basement.h @@ -0,0 +1,66 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_basement.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_BASEMENT_H +#define GNUNET_SERVICE_MESSENGER_BASEMENT_H + +#include "messenger_api_list_tunnels.h" + +/** + * Returns the count of peers in a list (typically from the basement of a room). + * + * @param tunnels List of peer identities + * @return Count of the entries in the list + */ +size_t +count_of_tunnels (const struct GNUNET_MESSENGER_ListTunnels *tunnels); + +/** + * Returns GNUNET_YES or GNUNET_NO to determine if the peer at index src should + * or should not connect outgoing to the peer at index dst to construct a complete + * basement with a given count of peers. + * + * @param count Count of peers + * @param src Source index + * @param dst Destination index + * @return GNUNET_YES or GNUNET_NO based on topologic requirement + */ +int +should_connect_tunnel_to (size_t count, size_t src, size_t dst); + +/** + * Returns GNUNET_YES or GNUNET_NO to determine if the peers of index src and + * index dst should be connected in any direction to construct a complete + * basement with a given count of peers. + * + * @param count Count of peers + * @param src Source index + * @param dst Destination index + * @return GNUNET_YES or GNUNET_NO based on topologic requirement + */ +int +required_connection_between (size_t count, size_t src, size_t dst); + +#endif //GNUNET_SERVICE_MESSENGER_BASEMENT_H diff --git a/src/messenger/gnunet-service-messenger_contact.c b/src/messenger/gnunet-service-messenger_contact.c new file mode 100644 index 000000000..1ec125402 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_contact.c @@ -0,0 +1,96 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_contact.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_contact.h" + +struct GNUNET_MESSENGER_SrvContact* +create_contact (const struct GNUNET_IDENTITY_PublicKey *key) +{ + struct GNUNET_MESSENGER_SrvContact *contact = GNUNET_new(struct GNUNET_MESSENGER_SrvContact); + + contact->name = NULL; + contact->rc = 0; + + GNUNET_memcpy(&(contact->public_key), key, sizeof(contact->public_key)); + + return contact; +} + +void +destroy_contact (struct GNUNET_MESSENGER_SrvContact *contact) +{ + if (contact->name) + GNUNET_free(contact->name); + + GNUNET_free(contact); +} + +const char* +get_contact_name (const struct GNUNET_MESSENGER_SrvContact *contact) +{ + return contact->name; +} + +void +set_contact_name (struct GNUNET_MESSENGER_SrvContact *contact, const char *name) +{ + GNUNET_assert(name); + + if (contact->name) + GNUNET_free(contact->name); + + contact->name = GNUNET_strdup(name); +} + +const struct GNUNET_IDENTITY_PublicKey* +get_contact_key (const struct GNUNET_MESSENGER_SrvContact *contact) +{ + return &(contact->public_key); +} + +void +increase_contact_rc (struct GNUNET_MESSENGER_SrvContact *contact) +{ + contact->rc++; +} + +int +decrease_contact_rc (struct GNUNET_MESSENGER_SrvContact *contact) +{ + if (contact->rc > 0) + contact->rc--; + + return contact->rc ? GNUNET_NO : GNUNET_YES; +} + +const struct GNUNET_HashCode* +get_contact_id_from_key (const struct GNUNET_MESSENGER_SrvContact *contact) +{ + static struct GNUNET_HashCode id; + + GNUNET_CRYPTO_hash (&(contact->public_key), sizeof(contact->public_key), &id); + + return &id; +} diff --git a/src/messenger/gnunet-service-messenger_contact.h b/src/messenger/gnunet-service-messenger_contact.h new file mode 100644 index 000000000..4a4f8bf0f --- /dev/null +++ b/src/messenger/gnunet-service-messenger_contact.h @@ -0,0 +1,112 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_contact.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_CONTACT_H +#define GNUNET_SERVICE_MESSENGER_CONTACT_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" + +struct GNUNET_MESSENGER_SrvContact +{ + char *name; + size_t rc; + + struct GNUNET_IDENTITY_PublicKey public_key; +}; + +/** + * Creates and allocates a new contact with a given public key from an EGO. + * + * @param key Public key + * @return New contact + */ +struct GNUNET_MESSENGER_SrvContact* +create_contact (const struct GNUNET_IDENTITY_PublicKey *key); + +/** + * Destroys a contact and frees its memory fully. + * + * @param contact Contact + */ +void +destroy_contact (struct GNUNET_MESSENGER_SrvContact *contact); + +/** + * Returns the current name of a given contact or NULL if no valid name was assigned yet. + * + * @param contact Contact + * @return Name of the contact or NULL + */ +const char* +get_contact_name (const struct GNUNET_MESSENGER_SrvContact *contact); + +/** + * Changes the current name of a given contact by copying it from the parameter name. + * + * @param contact Contact + * @param name Valid name (may not be NULL!) + */ +void +set_contact_name (struct GNUNET_MESSENGER_SrvContact *contact, const char *name); + +/** + * Returns the public key of a given contact. + * + * @param contact Contact + * @return Public key of the contact + */ +const struct GNUNET_IDENTITY_PublicKey* +get_contact_key (const struct GNUNET_MESSENGER_SrvContact *contact); + +/** + * Increases the reference counter of a given contact which is zero as default. + * + * @param contact Contact + */ +void +increase_contact_rc (struct GNUNET_MESSENGER_SrvContact *contact); + +/** + * Decreases the reference counter if possible (can not underflow!) of a given contact + * and returns GNUNET_YES if the counter is equal to zero, otherwise GNUNET_NO. + * + * @param contact Contact + * @return GNUNET_YES or GNUNET_NO depending on the reference counter + */ +int +decrease_contact_rc (struct GNUNET_MESSENGER_SrvContact *contact); + +/** + * Returns the resulting hashcode of the public key from a given contact. + * + * @param contact Contact + * @return Hash of the contacts public key + */ +const struct GNUNET_HashCode* +get_contact_id_from_key (const struct GNUNET_MESSENGER_SrvContact *contact); + +#endif //GNUNET_SERVICE_MESSENGER_CONTACT_H diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c new file mode 100644 index 000000000..38ad6fbb4 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_handle.c @@ -0,0 +1,503 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_handle.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_handle.h" + +#include "gnunet-service-messenger.h" +#include "gnunet-service-messenger_message_kind.h" + +struct GNUNET_MESSENGER_SrvHandle* +create_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) +{ + struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle); + + handle->service = service; + handle->mq = mq; + + handle->name = NULL; + + handle->operation = NULL; + + handle->ego = NULL; + + handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + return handle; +} + +int +iterate_free_member_ids (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + GNUNET_free(value); + + return GNUNET_YES; +} + +void +destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle) +{ + if (handle->service->dir) + save_handle_configuration(handle); + + if (handle->operation) + GNUNET_IDENTITY_cancel (handle->operation); + + if (handle->name) + GNUNET_free(handle->name); + + GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL); + GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids); + + GNUNET_free(handle); +} + +void +get_handle_data_subdir (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name, char **dir) +{ + if (name) + GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities", + DIR_SEPARATOR, name, DIR_SEPARATOR); + else + GNUNET_asprintf (dir, "%s%s%c", handle->service->dir, "anonymous", + DIR_SEPARATOR); +} + +static int +create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_ShortHashCode *random_id = generate_service_new_member_id (handle->service, key); + + if (!random_id) + return GNUNET_NO; + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + GNUNET_free(random_id); + return GNUNET_NO; + } + + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", + GNUNET_sh2s(random_id), GNUNET_h2s(key)); + + return GNUNET_YES; +} + +const struct GNUNET_ShortHashCode* +get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) +{ + return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); +} + +void +change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, + const struct GNUNET_ShortHashCode *unique_id) +{ + struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); + + if (member_id) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Changed a member id (%s) for room (%s) ", + GNUNET_sh2s(member_id), GNUNET_h2s(key)); + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "into (%s).\n", + GNUNET_sh2s(unique_id)); + + GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id)); + + struct GNUNET_MESSENGER_MemberMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID); + + GNUNET_memcpy(&(msg->key), key, sizeof(*key)); + GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id)); + + GNUNET_MQ_send (handle->mq, env); + } + else + { + member_id = GNUNET_new(struct GNUNET_ShortHashCode); + GNUNET_memcpy(member_id, unique_id, sizeof(*member_id)); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + GNUNET_free(member_id); + } +} + +static void +change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) +{ + if (handle->name) + GNUNET_free(handle->name); + + handle->name = name ? GNUNET_strdup(name) : NULL; + + const uint16_t name_len = handle->name ? strlen (handle->name) : 0; + + struct GNUNET_MESSENGER_NameMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME); + + char *extra = ((char*) msg) + sizeof(*msg); + + if (name_len) + GNUNET_memcpy(extra, handle->name, name_len); + + extra[name_len] = '\0'; + + GNUNET_MQ_send (handle->mq, env); +} + +static void +change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Ego *ego) +{ + handle->ego = ego; + + ego = get_handle_ego(handle); + + struct GNUNET_MESSENGER_KeyMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY); + + GNUNET_memcpy(&(msg->pubkey), &(ego->pub), sizeof(ego->pub)); + + GNUNET_MQ_send (handle->mq, env); +} + +struct GNUNET_MESSENGER_Ego* +get_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle) +{ + static struct GNUNET_MESSENGER_Ego anonymous; + static int read_keys = 0; + + if (handle->ego) + return handle->ego; + + if (!read_keys) + { + struct GNUNET_IDENTITY_Ego* ego = GNUNET_IDENTITY_ego_get_anonymous (); + GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key(ego), sizeof(anonymous.priv)); + GNUNET_IDENTITY_ego_get_public_key(ego, &(anonymous.pub)); + read_keys = 1; + } + + return &anonymous; +} + +void +setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) +{ + change_handle_name (handle, name); + change_handle_ego (handle, handle->name? lookup_service_ego(handle->service, handle->name) : NULL); + + if (handle->service->dir) + load_handle_configuration(handle); +} + +struct GNUNET_MESSENGER_MessageHandle +{ + struct GNUNET_MESSENGER_SrvHandle *handle; + struct GNUNET_MESSENGER_Message *message; +}; + +static int +iterate_send_message (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls; + + send_handle_message (msg_handle->handle, key, msg_handle->message); + + return GNUNET_YES; +} + +static void +callback_ego_create (void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg) +{ + struct GNUNET_MESSENGER_SrvHandle *handle = cls; + + handle->operation = NULL; + + if (emsg) + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg); + + if (key) + { + struct GNUNET_MESSENGER_MessageHandle msg_handle; + + msg_handle.handle = handle; + msg_handle.message = create_message_key (key); + + GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle); + + destroy_message (msg_handle.message); + + update_service_ego(handle->service, handle->name, key); + + change_handle_ego (handle, lookup_service_ego(handle->service, handle->name)); + } +} + +int +update_handle (struct GNUNET_MESSENGER_SrvHandle *handle) +{ + GNUNET_assert(handle); + + if (!handle->name) + return GNUNET_SYSERR; + + struct GNUNET_MESSENGER_Ego *ego = lookup_service_ego(handle->service, handle->name); + + if (!ego) + handle->operation = GNUNET_IDENTITY_create (handle->service->identity, handle->name, NULL, + GNUNET_IDENTITY_TYPE_ECDSA, callback_ego_create, handle); + else + change_handle_ego (handle, ego); + + return GNUNET_OK; +} + +int +set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name) +{ + GNUNET_assert(handle); + + if ((name) && (lookup_service_ego(handle->service, name))) + return GNUNET_NO; + + struct GNUNET_IDENTITY_Operation *operation = handle->operation; + + if (handle->name) + handle->operation = GNUNET_IDENTITY_rename (handle->service->identity, handle->name, name, NULL, NULL); + + char *old_dir; + get_handle_data_subdir (handle, handle->name, &old_dir); + + char *new_dir; + get_handle_data_subdir (handle, name, &new_dir); + + int result = 0; + + if (GNUNET_YES == GNUNET_DISK_directory_test (old_dir, GNUNET_YES)) + { + GNUNET_DISK_directory_create_for_file (new_dir); + + result = rename (old_dir, new_dir); + } + else if (GNUNET_YES == GNUNET_DISK_directory_test (new_dir, GNUNET_NO)) + result = -1; + + if (0 == result) + { + struct GNUNET_MESSENGER_MessageHandle msg_handle; + + msg_handle.handle = handle; + msg_handle.message = create_message_name (name); + + GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle); + + destroy_message (msg_handle.message); + + change_handle_name (handle, name); + + if (operation) + GNUNET_IDENTITY_cancel (operation); + } + else + { + if (handle->operation) + { + GNUNET_IDENTITY_cancel (handle->operation); + + handle->operation = operation; + } + } + + GNUNET_free(old_dir); + GNUNET_free(new_dir); + + return (result == 0 ? GNUNET_OK : GNUNET_NO); +} + +int +open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) +{ + if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) + return GNUNET_NO; + + return open_service_room (handle->service, handle, key); +} + +int +entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key) +{ + if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) + return GNUNET_NO; + + return entry_service_room (handle->service, handle, door, key); +} + +int +close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) +{ + if (!get_handle_member_id (handle, key)) + return GNUNET_NO; + + return close_service_room (handle->service, handle, key); +} + +int +send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, + struct GNUNET_MESSENGER_Message *message) +{ + const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); + + if (!id) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "It is required to be a member of a room to send messages!\n"); + return GNUNET_NO; + } + + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key); + + if (!room) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", GNUNET_h2s (key)); + return GNUNET_NO; + } + + struct GNUNET_HashCode hash; + + GNUNET_memcpy(&(message->header.sender_id), id, sizeof(*id)); + + send_room_message (room, handle, message, &hash); + return GNUNET_YES; +} + +static int callback_scan_for_rooms(void* cls, const char *filename) { + struct GNUNET_MESSENGER_SrvHandle* handle = cls; + + struct GNUNET_CONFIGURATION_Handle* cfg = GNUNET_CONFIGURATION_create(); + + if ((GNUNET_YES == GNUNET_DISK_file_test(filename)) && + (GNUNET_OK == GNUNET_CONFIGURATION_parse(cfg, filename))) + { + struct GNUNET_HashCode key; + struct GNUNET_ShortHashCode member_id; + + if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data(cfg, "room", "key", &key, sizeof(key))) && + (GNUNET_OK == GNUNET_CONFIGURATION_get_data(cfg, "room", "member_id", &member_id, sizeof(member_id)))) + change_handle_member_id(handle, &key, &member_id); + } + + GNUNET_CONFIGURATION_destroy(cfg); + return GNUNET_OK; +} + +void load_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) { + char* id_dir; + get_handle_data_subdir(handle, handle->name, &id_dir); + + if (GNUNET_YES == GNUNET_DISK_directory_test(id_dir, GNUNET_YES)) + { + char* scan_dir; + GNUNET_asprintf(&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); + + if (GNUNET_OK == GNUNET_DISK_directory_test(scan_dir, GNUNET_YES)) + GNUNET_DISK_directory_scan(scan_dir, callback_scan_for_rooms, handle); + + GNUNET_free(scan_dir); + } + + GNUNET_free(id_dir); +} + +static int +iterate_save_rooms(void* cls, const struct GNUNET_HashCode* key, void* value) +{ + struct GNUNET_MESSENGER_SrvHandle* handle = cls; + struct GNUNET_ShortHashCode* member_id = value; + + char* id_dir; + get_handle_data_subdir(handle, handle->name, &id_dir); + + char* filename; + GNUNET_asprintf(&filename, "%s%s%c%s.cfg", + id_dir, "rooms", DIR_SEPARATOR, + GNUNET_h2s(key)); + + GNUNET_free(id_dir); + + struct GNUNET_CONFIGURATION_Handle* cfg = GNUNET_CONFIGURATION_create(); + + char* key_data = GNUNET_STRINGS_data_to_string_alloc(key, sizeof(*key)); + + if (key_data) + { + GNUNET_CONFIGURATION_set_value_string(cfg, "room", "key", key_data); + + GNUNET_free(key_data); + } + + char* member_id_data = GNUNET_STRINGS_data_to_string_alloc(member_id, sizeof(*member_id)); + + if (member_id_data) + { + GNUNET_CONFIGURATION_set_value_string(cfg, "room", "member_id", member_id_data); + + GNUNET_free(member_id_data); + } + + GNUNET_CONFIGURATION_write(cfg, filename); + GNUNET_CONFIGURATION_destroy(cfg); + + GNUNET_free(filename); + + return GNUNET_YES; +} + +void save_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle) +{ + char* id_dir; + get_handle_data_subdir(handle, handle->name, &id_dir); + + if ((GNUNET_YES == GNUNET_DISK_directory_test(id_dir, GNUNET_NO)) || + (GNUNET_OK == GNUNET_DISK_directory_create(id_dir))) + { + char* save_dir; + GNUNET_asprintf(&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); + + if ((GNUNET_YES == GNUNET_DISK_directory_test(save_dir, GNUNET_NO)) || + (GNUNET_OK == GNUNET_DISK_directory_create(save_dir))) + GNUNET_CONTAINER_multihashmap_iterate(handle->member_ids, iterate_save_rooms, handle); + + GNUNET_free(save_dir); + } + + GNUNET_free(id_dir); +} diff --git a/src/messenger/gnunet-service-messenger_handle.h b/src/messenger/gnunet-service-messenger_handle.h new file mode 100644 index 000000000..81cf377a8 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_handle.h @@ -0,0 +1,216 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_handle.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_HANDLE_H +#define GNUNET_SERVICE_MESSENGER_HANDLE_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_peer_lib.h" +#include "gnunet_mq_lib.h" + +#include "gnunet-service-messenger_service.h" + +#include "messenger_api_ego.h" +#include "messenger_api_message.h" + +struct GNUNET_MESSENGER_SrvHandle +{ + struct GNUNET_MESSENGER_Service *service; + struct GNUNET_MQ_Handle *mq; + + char *name; + + struct GNUNET_IDENTITY_Operation *operation; + + struct GNUNET_MESSENGER_Ego *ego; + + struct GNUNET_CONTAINER_MultiHashMap *member_ids; +}; + +/** + * Creates and allocates a new handle related to a service and using a given mq (message queue). + * + * @param service MESSENGER Service + * @param mq Message queue + * @return New handle + */ +struct GNUNET_MESSENGER_SrvHandle* +create_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq); + +/** + * Destroys a handle and frees its memory fully. + * + * @param handle Handle + */ +void +destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Writes the path of the directory for a given handle using a specific name to the parameter + * dir. This directory will be used to store data regarding the handle and its messages. + * + * @param handle Handle + * @param name Potential name of the handle + * @param dir[out] Path to store data + */ +void +get_handle_data_subdir (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name, char **dir); + +/** + * Returns the member id of a given handle in a specific room. + * + * If the handle is not a member of the specific room, NULL gets returned. + * + * @param handle Handle + * @param key Key of a room + * @return Member id or NULL + */ +const struct GNUNET_ShortHashCode* +get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key); + +/** + * Changes the member id of a given handle in a specific room to match a unique_id. + * + * The client connected to the handle will be informed afterwards automatically. + * + * @param handle Handle + * @param key Key of a room + * @param unique_id Unique member id + */ +void +change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, + const struct GNUNET_ShortHashCode *unique_id); + +/** + * Returns the EGO used by a given handle. + * + * @param handle Handle + * @return EGO keypair + */ +struct GNUNET_MESSENGER_Ego* +get_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Tries to set the name and EGO key of a handle initially by looking up a specific name. + * + * @param handle Handle + * @param name Name (optionally: valid EGO name) + */ +void +setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name); + +/** + * Tries to change the keypair of an EGO of a handle under the same name and informs all rooms + * about the change automatically. + * + * @param handle Handle + * @return GNUNET_OK on success, otherwise GNUNET_SYSERR + */ +int +update_handle (struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Tries to rename the handle which implies renaming the EGO its using and moving all related data into + * the directory fitting to the changed name. + * + * The client connected to the handle will be informed afterwards automatically. + * + * @param handle Handle + * @param name New name + * @return GNUNET_OK on success, otherwise GNUNET_NO + */ +int +set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, const char *name); + +/** + * Makes a given handle a member of the room using a specific key and opens the + * room from the handles service. + * + * @param handle Handle + * @param key Key of a room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key); + +/** + * Makes a given handle a member of the room using a specific key and enters the room + * through a tunnel to a peer identified by a given door (peer identity). + * + * @param handle Handle + * @param door Peer identity + * @param key Key of a room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key); + +/** + * Removes the membership of the room using a specific key and closes it if no other handle + * from this service is still a member of it. + * + * @param handle Handle + * @param key Key of a room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key); + +/** + * Sends a message from a given handle to the room using a specific key. + * + * @param handle Handle + * @param key Key of a room + * @param message Message + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, + struct GNUNET_MESSENGER_Message *message); + +/** + * Loads member ids and other potential configuration from a given handle which + * depends on the given name the handle uses. + * + * @param handle Handle + */ +void +load_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Saves member ids and other potential configuration from a given handle which + * depends on the given name the handle uses. + * + * @param handle Handle + */ +void +save_handle_configuration(struct GNUNET_MESSENGER_SrvHandle *handle); + +#endif //GNUNET_SERVICE_MESSENGER_HANDLE_H diff --git a/src/messenger/gnunet-service-messenger_list_handles.c b/src/messenger/gnunet-service-messenger_list_handles.c new file mode 100644 index 000000000..16a160dea --- /dev/null +++ b/src/messenger/gnunet-service-messenger_list_handles.c @@ -0,0 +1,95 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_list_handles.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_list_handles.h" + +#include "gnunet-service-messenger_handle.h" + +void +init_list_handles (struct GNUNET_MESSENGER_ListHandles *handles) +{ + GNUNET_assert(handles); + + handles->head = NULL; + handles->tail = NULL; +} + +void +clear_list_handles (struct GNUNET_MESSENGER_ListHandles *handles) +{ + GNUNET_assert(handles); + + while (handles->head) + { + struct GNUNET_MESSENGER_ListHandle *element = handles->head; + + GNUNET_CONTAINER_DLL_remove(handles->head, handles->tail, element); + destroy_handle (element->handle); + GNUNET_free(element); + } + + handles->head = NULL; + handles->tail = NULL; +} + +void +add_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, void *handle) +{ + struct GNUNET_MESSENGER_ListHandle *element = GNUNET_new(struct GNUNET_MESSENGER_ListHandle); + + element->handle = handle; + + GNUNET_CONTAINER_DLL_insert_tail(handles->head, handles->tail, element); +} + +int +remove_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, void *handle) +{ + struct GNUNET_MESSENGER_ListHandle *element; + + for (element = handles->head; element; element = element->next) + if (element->handle == handle) + break; + + if (!element) + return GNUNET_NO; + + GNUNET_CONTAINER_DLL_remove(handles->head, handles->tail, element); + GNUNET_free(element); + + return GNUNET_YES; +} + +void* +find_list_handle_by_member (struct GNUNET_MESSENGER_ListHandles *handles, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_ListHandle *element; + + for (element = handles->head; element; element = element->next) + if (get_handle_member_id ((struct GNUNET_MESSENGER_SrvHandle*) element->handle, key)) + return element->handle; + + return NULL; +} diff --git a/src/messenger/gnunet-service-messenger_list_handles.h b/src/messenger/gnunet-service-messenger_list_handles.h new file mode 100644 index 000000000..fe92cc58a --- /dev/null +++ b/src/messenger/gnunet-service-messenger_list_handles.h @@ -0,0 +1,96 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_list_handles.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H +#define GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_container_lib.h" + +struct GNUNET_MESSENGER_ListHandle +{ + struct GNUNET_MESSENGER_ListHandle *prev; + struct GNUNET_MESSENGER_ListHandle *next; + + void *handle; +}; + +struct GNUNET_MESSENGER_ListHandles +{ + struct GNUNET_MESSENGER_ListHandle *head; + struct GNUNET_MESSENGER_ListHandle *tail; +}; + +/** + * Initializes list of handles as empty list. + * + * @param handles List of handles + */ +void +init_list_handles (struct GNUNET_MESSENGER_ListHandles *handles); + +/** + * Destroys remaining handles and clears the list. + * + * @param handles List of handles + */ +void +clear_list_handles (struct GNUNET_MESSENGER_ListHandles *handles); + +/** + * Adds a specific handle to the end of the list. + * + * @param handles List of handles + * @param handle Handle + */ +void +add_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, void *handle); + +/** + * Removes the first entry matching with a specific handle from the list and + * returns GNUNET_YES on success or GNUNET_NO on failure. + * + * @param handles List of handles + * @param handle Handle + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +remove_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, void *handle); + +/** + * Searches linearly through the list of handles for members of a specific room + * which is identified by a given key. + * + * If no handle is found which is a current member, NULL gets returned. + * + * @param handles List of handles + * @param key Common key of a room + * @return First handle which is a current member + */ +void* +find_list_handle_by_member (struct GNUNET_MESSENGER_ListHandles *handles, const struct GNUNET_HashCode *key); + +#endif //GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H diff --git a/src/messenger/gnunet-service-messenger_list_messages.c b/src/messenger/gnunet-service-messenger_list_messages.c new file mode 100644 index 000000000..c4f1f7043 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_list_messages.c @@ -0,0 +1,76 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_list_messages.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_list_messages.h" + +void +init_list_messages (struct GNUNET_MESSENGER_ListMessages *messages) +{ + GNUNET_assert(messages); + + messages->head = NULL; + messages->tail = NULL; +} + +void +clear_list_messages (struct GNUNET_MESSENGER_ListMessages *messages) +{ + GNUNET_assert(messages); + + while (messages->head) + { + struct GNUNET_MESSENGER_ListMessage *element = messages->head; + + GNUNET_CONTAINER_DLL_remove(messages->head, messages->tail, element); + GNUNET_free(element); + } + + messages->head = NULL; + messages->tail = NULL; +} + +void +add_to_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ListMessage *element = GNUNET_new(struct GNUNET_MESSENGER_ListMessage); + + GNUNET_memcpy(&(element->hash), hash, sizeof(struct GNUNET_HashCode)); + + GNUNET_CONTAINER_DLL_insert_tail(messages->head, messages->tail, element); +} + +void +remove_from_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ListMessage *element; + + for (element = messages->head; element; element = element->next) + if (0 == GNUNET_CRYPTO_hash_cmp (&(element->hash), hash)) + { + GNUNET_CONTAINER_DLL_remove(messages->head, messages->tail, element); + GNUNET_free(element); + break; + } +} diff --git a/src/messenger/gnunet-service-messenger_list_messages.h b/src/messenger/gnunet-service-messenger_list_messages.h new file mode 100644 index 000000000..266c30ec6 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_list_messages.h @@ -0,0 +1,81 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_list_messages.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H +#define GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_container_lib.h" + +struct GNUNET_MESSENGER_ListMessage +{ + struct GNUNET_MESSENGER_ListMessage *prev; + struct GNUNET_MESSENGER_ListMessage *next; + + struct GNUNET_HashCode hash; +}; + +struct GNUNET_MESSENGER_ListMessages +{ + struct GNUNET_MESSENGER_ListMessage *head; + struct GNUNET_MESSENGER_ListMessage *tail; +}; + +/** + * Initializes list of message hashes as empty list. + * + * @param messages List of hashes + */ +void +init_list_messages (struct GNUNET_MESSENGER_ListMessages *messages); + +/** + * Clears the list of message hashes. + * + * @param messages List of hashes + */ +void +clear_list_messages (struct GNUNET_MESSENGER_ListMessages *messages); + +/** + * Adds a specific hash from a message to the end of the list. + * + * @param messages List of hashes + * @param hash Hash of message + */ +void +add_to_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash); + +/** + * Removes the first entry with a matching hash from the list. + * + * @param messages List of hashes + * @param hash Hash of message + */ +void +remove_from_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, const struct GNUNET_HashCode *hash); + +#endif //GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H diff --git a/src/messenger/gnunet-service-messenger_message_handle.c b/src/messenger/gnunet-service-messenger_message_handle.c new file mode 100644 index 000000000..1652435c8 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_handle.c @@ -0,0 +1,130 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_handle.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_message_handle.h" + +void +handle_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_SrvContact *contact = get_room_contact (room, &(message->header.sender_id)); + + if (!contact) + add_room_contact (room, &(message->header.sender_id), &(message->body.join.key)); + + struct GNUNET_MESSENGER_MemberInfo *info = get_room_member_info (room, &(message->header.sender_id)); + + if (!info) + { + info = GNUNET_new(struct GNUNET_MESSENGER_MemberInfo); + + info->access = GNUNET_MESSENGER_MEMBER_UNKNOWN; + init_list_messages (&(info->session_messages)); + } + else + clear_list_messages (&(info->session_messages)); + + if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_put (room->member_infos, &(message->header.sender_id), info, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + add_to_list_messages (&(info->session_messages), hash); +} + +void +handle_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_MemberInfo *info = get_room_member_info (room, &(message->header.sender_id)); + + if (info) + clear_list_messages (&(info->session_messages)); +} + +void +handle_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_SrvContact *contact = get_room_contact (room, &(message->header.sender_id)); + + if (contact) + set_contact_name (contact, message->body.name.name); + + struct GNUNET_MESSENGER_MemberInfo *info = get_room_member_info (room, &(message->header.sender_id)); + + if (info) + add_to_list_messages (&(info->session_messages), hash); +} + +void +handle_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_SrvContact *contact = get_room_contact (room, &(message->header.sender_id)); + + if (contact) + swap_service_contact_by_pubkey (room->service, contact, &(message->body.key.key)); + + struct GNUNET_MESSENGER_MemberInfo *info = get_room_member_info (room, &(message->header.sender_id)); + + if (info) + add_to_list_messages (&(info->session_messages), hash); +} + +void +handle_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + if (GNUNET_NO == contains_list_tunnels (&(room->basement), &(message->body.peer.peer))) + add_to_list_tunnels (&(room->basement), &(message->body.peer.peer)); + + if (room->peer_message) + rebuild_room_basement_structure (room); +} + +void +handle_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_MemberInfo *info = get_room_member_info (room, &(message->header.sender_id)); + + if (info) + add_to_list_messages (&(info->session_messages), hash); + + switch_room_member_id (room, &(message->header.sender_id), &(message->body.id.id), hash); +} + +void +handle_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ListTunnel *element = find_list_tunnels (&(room->basement), &(message->body.peer.peer), NULL); + + if (!element) + return; + + remove_from_list_tunnels (&(room->basement), element); + + if (room->peer_message) + rebuild_room_basement_structure (room); +} diff --git a/src/messenger/gnunet-service-messenger_message_handle.h b/src/messenger/gnunet-service-messenger_message_handle.h new file mode 100644 index 000000000..d091e1d11 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_handle.h @@ -0,0 +1,128 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_handle.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H +#define GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" + +#include "gnunet-service-messenger_message_kind.h" + +#include "gnunet-service-messenger_tunnel.h" +#include "messenger_api_message.h" + +/** + * Handles a received or sent join message to make changes of current member information. + * (add matching member and clear member info) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message JOIN-Message + * @param hash Hash of the message + */ +void +handle_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent leave message to make changes of current member information. + * (remove matching member and clear member info) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message LEAVE-Message + * @param hash Hash of the message + */ +void +handle_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent name message to rename a current member. + * (change name of matching member) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message NAME-Message + * @param hash Hash of the message + */ +void +handle_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent key message to change the key of a member and rearrange the contacts accordingly. + * (move the member in the contacts and change its key) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message KEY-Message + * @param hash Hash of the message + */ +void +handle_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent peer message to make changes of the basement in the room. + * (add a new peer to the basement and restructure connections based on updated list of peers) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message PEER-Message + * @param hash Hash of the message + */ +void +handle_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent id message to change a members id. + * (change id of matching member) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message ID-Message + * @param hash Hash of the message + */ +void +handle_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received or sent miss message to drop a peer from the basement in the room. + * (remove a peer from the basement and restructure connections based on updated list of peers) + * + * @param room Room of the message + * @param tunnel Receiving/sending connection (may be NULL) + * @param message MISS-Message + * @param hash Hash of the message + */ +void +handle_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H diff --git a/src/messenger/gnunet-service-messenger_message_kind.c b/src/messenger/gnunet-service-messenger_message_kind.c new file mode 100644 index 000000000..9c829fe09 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_kind.c @@ -0,0 +1,192 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_kind.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_message_kind.h" +#include "gnunet-service-messenger_util.h" + +struct GNUNET_MESSENGER_Message* +create_message_info (struct GNUNET_MESSENGER_Ego *ego, struct GNUNET_CONTAINER_MultiShortmap *members) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_INFO); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.info.host_key), &(ego->pub), sizeof(ego->pub)); + + if (GNUNET_YES == generate_free_member_id (&(message->body.info.unique_id), members)) + return message; + else + { + destroy_message (message); + return NULL; + } +} + +struct GNUNET_MESSENGER_Message* +create_message_join (struct GNUNET_MESSENGER_Ego *ego) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_JOIN); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.join.key), &(ego->pub), sizeof(ego->pub)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_leave () +{ + return create_message (GNUNET_MESSENGER_KIND_LEAVE); +} + +struct GNUNET_MESSENGER_Message* +create_message_name (const char *name) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_NAME); + + if (!message) + return NULL; + + message->body.name.name = GNUNET_strdup(name); + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_key (const struct GNUNET_IDENTITY_PrivateKey *key) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_KEY); + + if (!message) + return NULL; + + GNUNET_IDENTITY_key_get_public (key, &(message->body.key.key)); + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_peer (const struct GNUNET_MESSENGER_Service *service) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_PEER); + + if (!message) + return NULL; + + if (GNUNET_OK == get_service_peer_identity (service, &(message->body.peer.peer))) + return message; + else + { + destroy_message (message); + return NULL; + } +} + +struct GNUNET_MESSENGER_Message* +create_message_id (const struct GNUNET_ShortHashCode *unique_id) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_ID); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.id.id), unique_id, sizeof(struct GNUNET_ShortHashCode)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_miss (const struct GNUNET_PeerIdentity *peer) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_MISS); + + if (!message) + { + return NULL; + } + + GNUNET_memcpy(&(message->body.miss.peer), peer, sizeof(struct GNUNET_PeerIdentity)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_merge (const struct GNUNET_HashCode *previous) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_MERGE); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.merge.previous), previous, sizeof(struct GNUNET_HashCode)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_request (const struct GNUNET_HashCode *hash) +{ + struct GNUNET_HashCode zero; + memset (&zero, 0, sizeof(zero)); + + if (0 == GNUNET_CRYPTO_hash_cmp (hash, &zero)) + return NULL; + + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_REQUEST); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.request.hash), hash, sizeof(struct GNUNET_HashCode)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_invite (const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_INVITE); + + if (!message) + return NULL; + + GNUNET_memcpy(&(message->body.invite.door), door, sizeof(struct GNUNET_PeerIdentity)); + GNUNET_memcpy(&(message->body.invite.key), key, sizeof(struct GNUNET_HashCode)); + + return message; +} + +struct GNUNET_MESSENGER_Message* +create_message_text (const char *text) +{ + struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_TEXT); + + if (!message) + return NULL; + + message->body.text.text = GNUNET_strdup(text); + return message; +} diff --git a/src/messenger/gnunet-service-messenger_message_kind.h b/src/messenger/gnunet-service-messenger_message_kind.h new file mode 100644 index 000000000..dd89d0b2f --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_kind.h @@ -0,0 +1,160 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_kind.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H +#define GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H + +#include "platform.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" + +#include "messenger_api_message.h" +#include "gnunet-service-messenger_service.h" +#include "messenger_api_ego.h" + +/** + * Creates and allocates a new info message containing the hosts public key and a newly generated unique member id. + * (all values are stored as copy) + * + * @param ego EGO of the host + * @param members Map of all assigned member ids + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_info (struct GNUNET_MESSENGER_Ego *ego, struct GNUNET_CONTAINER_MultiShortmap *members); + +/** + * Creates and allocates a new join message containing the clients public key. + * (all values are stored as copy) + * + * @param ego EGO of the client + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_join (struct GNUNET_MESSENGER_Ego *ego); + +/** + * Creates and allocates a new leave message. + * + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_leave (); + +/** + * Creates and allocates a new name message containing the name to change to. + * (all values are stored as copy) + * + * @param name New name + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_name (const char *name); + +/** + * Creates and allocates a new key message containing the public key to change to derived + * from its private counterpart. (all values are stored as copy) + * + * @param key Private key of EGO + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_key (const struct GNUNET_IDENTITY_PrivateKey *key); + +/** + * Creates and allocates a new peer message containing a services peer identity. + * (all values are stored as copy) + * + * @param service Service + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_peer (const struct GNUNET_MESSENGER_Service *service); + +/** + * Creates and allocates a new id message containing the unique member id to change to. + * (all values are stored as copy) + * + * @param unique_id Unique member id + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_id (const struct GNUNET_ShortHashCode *unique_id); + +/** + * Creates and allocates a new miss message containing the missing peer identity. + * (all values are stored as copy) + * + * @param peer Missing peer identity + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_miss (const struct GNUNET_PeerIdentity *peer); + +/** + * Creates and allocates a new merge message containing the hash of a second previous message + * besides the regular previous message mentioned in a messages header. + * (all values are stored as copy) + * + * @param previous Hash of message + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_merge (const struct GNUNET_HashCode *previous); + +/** + * Creates and allocates a new request message containing the hash of a missing message. + * (all values are stored as copy) + * + * @param hash Hash of message + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_request (const struct GNUNET_HashCode *hash); + +/** + * Creates and allocates a new invite message containing the peer identity of an entrance peer + * to a room using a given key as shared secret for communication. + * (all values are stored as copy) + * + * @param door Peer identity + * @param key Shared secret of a room + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_invite (const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key); + +/** + * Creates and allocates a new text message containing a string representing text. + * (all values are stored as copy) + * + * @param text Text + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message_text (const char *text); + +#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H diff --git a/src/messenger/gnunet-service-messenger_message_recv.c b/src/messenger/gnunet-service-messenger_message_recv.c new file mode 100644 index 000000000..aa28a36ea --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_recv.c @@ -0,0 +1,204 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_recv.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_message_recv.h" +#include "gnunet-service-messenger_message_handle.h" + +void +recv_message_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + int conflict = GNUNET_CONTAINER_multishortmap_contains (room->members, &(message->body.info.unique_id)); + + if (GNUNET_NO == conflict) + { + struct GNUNET_MESSENGER_Message *sync_message = create_message_id (&(message->body.info.unique_id)); + struct GNUNET_HashCode sync_hash; + + send_room_message_ext (room, room->host, sync_message, &sync_hash, tunnel); + destroy_message (sync_message); + + switch_room_member_id (room, get_room_host_id (room), &(message->body.info.unique_id), NULL); + + change_room_host_id (room, &(message->body.info.unique_id)); + } + + if (!tunnel->contact_id) + tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_memcpy(tunnel->contact_id, &(message->header.sender_id), sizeof(struct GNUNET_ShortHashCode)); + + struct GNUNET_ShortHashCode original_id; + + if (GNUNET_YES == conflict) + { + GNUNET_memcpy(&original_id, get_room_host_id (room), sizeof(struct GNUNET_ShortHashCode)); + + change_room_host_id (room, &(message->body.info.unique_id)); + } + + { + struct GNUNET_MESSENGER_Message *join_message = create_message_join (room->host->ego); + struct GNUNET_HashCode join_hash; + + send_tunnel_message (tunnel, room->host, join_message, &join_hash); + destroy_message (join_message); + } + + if ((GNUNET_YES == conflict) && (0 != GNUNET_memcmp(&original_id, get_room_host_id (room)))) + { + struct GNUNET_MESSENGER_Message *sync_message = create_message_id (&original_id); + struct GNUNET_HashCode sync_hash; + + send_tunnel_message (tunnel, room->host, sync_message, &sync_hash); + destroy_message (sync_message); + } +} + +struct GNUNET_MESSENGER_MemberInfoSpread +{ + struct GNUNET_MESSENGER_SrvRoom *room; + struct GNUNET_MESSENGER_SrvTunnel *tunnel; +}; + +static int +iterate_send_member_infos (void *cls, const struct GNUNET_ShortHashCode *key, void *value) +{ + struct GNUNET_MESSENGER_MemberInfo *info = value; + struct GNUNET_MESSENGER_MemberInfoSpread *spread = cls; + + struct GNUNET_MESSENGER_ListMessage *element = info->session_messages.head; + + while (element) + { + const struct GNUNET_MESSENGER_Message *message = get_room_message (spread->room, spread->room->host, + &(element->hash), GNUNET_NO); + + if (message) + forward_tunnel_message (spread->tunnel, message, &(element->hash)); + + element = element->next; + } + + return GNUNET_YES; +} + +void +recv_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + const struct GNUNET_MESSENGER_Message *info_msg = get_room_message (room, room->host, &(message->header.previous), + GNUNET_NO); + + if ((info_msg) && (0 == GNUNET_memcmp(&(info_msg->header.sender_id), get_room_host_id (room))) + && (GNUNET_MESSENGER_KIND_INFO == info_msg->header.kind)) + { + struct GNUNET_MESSENGER_MemberInfoSpread spread; + + spread.room = room; + + if ((tunnel) && (tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, &(message->header.sender_id)))) + spread.tunnel = tunnel; + else + spread.tunnel = find_room_tunnel_to (room, &(message->header.sender_id)); + + if (spread.tunnel) + GNUNET_CONTAINER_multishortmap_iterate (room->member_infos, iterate_send_member_infos, &spread); + } + + handle_message_join (room, tunnel, message, hash); +} + +void +recv_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + handle_message_leave (room, tunnel, message, hash); +} + +void +recv_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + handle_message_name (room, tunnel, message, hash); +} + +void +recv_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + handle_message_key (room, tunnel, message, hash); +} + +void +recv_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_PeerIdentity peer; + GNUNET_PEER_resolve (tunnel->peer, &peer); + + if (0 == GNUNET_memcmp(&peer, &(message->body.peer.peer))) + { + if (!tunnel->peer_message) + tunnel->peer_message = GNUNET_new(struct GNUNET_HashCode); + + GNUNET_memcpy(tunnel->peer_message, hash, sizeof(struct GNUNET_HashCode)); + + if (!tunnel->contact_id) + tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_memcpy(tunnel->contact_id, &(message->header.sender_id), sizeof(struct GNUNET_ShortHashCode)); + } + + handle_message_peer (room, tunnel, message, hash); +} + +void +recv_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + if ((tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, &(message->header.sender_id)))) + GNUNET_memcpy(tunnel->contact_id, &(message->body.id.id), sizeof(struct GNUNET_ShortHashCode)); + + handle_message_id (room, tunnel, message, hash); +} + +void +recv_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + handle_message_miss (room, tunnel, message, hash); +} + +void +recv_message_request (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(message->body.request.hash), + GNUNET_NO); + + if (msg) + forward_tunnel_message (tunnel, msg, &(message->body.request.hash)); +} diff --git a/src/messenger/gnunet-service-messenger_message_recv.h b/src/messenger/gnunet-service-messenger_message_recv.h new file mode 100644 index 000000000..245612cb0 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_recv.h @@ -0,0 +1,159 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_recv.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H +#define GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" + +#include "gnunet-service-messenger_tunnel.h" +#include "messenger_api_message.h" + +/** + * Handles a received info message to change the current member id to the one generated by + * the host connected to. (all current tunnels will be informed about the id change) + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message INFO-Message + * @param hash Hash of the message + */ +void +recv_message_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received join message to forward all member information to the new member if the message was + * the direct reaction to a previous info message from this peer. + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message JOIN-Message + * @param hash Hash of the message + */ +void +recv_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received leave message. + * @see handle_message_leave() + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message LEAVE-Message + * @param hash Hash of the message + */ +void +recv_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received name message. + * @see handle_message_name() + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message NAME-Message + * @param hash Hash of the message + */ +void +recv_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received key message. + * @see handle_message_key() + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message KEY-Message + * @param hash Hash of the message + */ +void +recv_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received peer message to link it to its origin tunnel if the peer identity matches. + * (the peer message and the member id can potentially be linked to the tunnel) + * + * TODO: This handling will only check the one given tunnel! + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message PEER-Message + * @param hash Hash of the message + */ +void +recv_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received id message to change the tunnels linked member id if necessary. + * (the tunnels linked member id will be changed if the sender id is matching) + * + * TODO: This handling will only check the one given tunnel! + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message ID-Message + * @param hash Hash of the message + */ +void +recv_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received miss message. + * @see handle_message_miss() + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message MISS-Message + * @param hash Hash of the message + */ +void +recv_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Handles a received request message by checking for the requested message and forwarding it back + * if the message was found. + * (this can also cause this peer to send a new request instead of only forwarding the received one) + * + * TODO: Requests can cause exponentially more requests! + * + * @param room Room of the message + * @param tunnel Receiving connection + * @param message REQUEST-Message + * @param hash Hash of the message + */ +void +recv_message_request (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H diff --git a/src/messenger/gnunet-service-messenger_message_send.c b/src/messenger/gnunet-service-messenger_message_send.c new file mode 100644 index 000000000..86cf9b888 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_send.c @@ -0,0 +1,118 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_send.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_message_send.h" +#include "gnunet-service-messenger_message_handle.h" + +void +send_message_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + if (!tunnel->contact_id) + { + tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_memcpy(tunnel->contact_id, &(message->body.info.unique_id), sizeof(struct GNUNET_ShortHashCode)); + } + else + { + disconnect_tunnel (tunnel); + } +} + +void +send_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_join (room, tunnel, message, hash); + + if (room->peer_message) + { + const struct GNUNET_MESSENGER_Message *peer_message = get_room_message (room, handle, room->peer_message, + GNUNET_NO); + + if ((peer_message) && (tunnel)) + { + forward_tunnel_message (tunnel, peer_message, room->peer_message); + } + } +} + +void +send_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_leave (room, tunnel, message, hash); +} + +void +send_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_name (room, tunnel, message, hash); +} + +void +send_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_key (room, tunnel, message, hash); +} + +void +send_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + if (!room->peer_message) + { + room->peer_message = GNUNET_new(struct GNUNET_HashCode); + } + + GNUNET_memcpy(room->peer_message, hash, sizeof(struct GNUNET_HashCode)); + + handle_message_peer (room, tunnel, message, hash); +} + +void +send_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_id (room, tunnel, message, hash); +} + +void +send_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + handle_message_miss (room, tunnel, message, hash); +} diff --git a/src/messenger/gnunet-service-messenger_message_send.h b/src/messenger/gnunet-service-messenger_message_send.h new file mode 100644 index 000000000..c1096205a --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_send.h @@ -0,0 +1,155 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_send.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H +#define GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" + +#include "gnunet-service-messenger_tunnel.h" +#include "messenger_api_message.h" + +/** + * Handles a sent info message to setup a tunnels linked member id. + * (if a tunnel has already got a member id linked to it, the connection will be closed) + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message INFO-Message + * @param hash Hash of the message + */ +void +send_message_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent join message to ensure growth of the decentralized room structure. + * (if the service provides a peer message for this room currently, it will be forwarded) + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message JOIN-Message + * @param hash Hash of the message + */ +void +send_message_join (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent leave message. + * @see handle_message_leave() + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message LEAVE-Message + * @param hash Hash of the message + */ +void +send_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent name message. + * @see handle_message_name() + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message NAME-Message + * @param hash Hash of the message + */ +void +send_message_name (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent key message. + * @see handle_message_key() + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message KEY-Message + * @param hash Hash of the message + */ +void +send_message_key (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent peer message to update the rooms peer message of this service. + * (a set peer message indicates this service being a part of the decentralized room structure) + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message PEER-Message + * @param hash Hash of the message + */ +void +send_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent id message. + * @see handle_message_id() + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message ID-Message + * @param hash Hash of the message + */ +void +send_message_id (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Handles a sent miss message. + * @see handle_message_miss() + * + * @param room Room of the message + * @param handle Sending handle + * @param tunnel Sending connection (may be NULL) + * @param message MISS-Message + * @param hash Hash of the message + */ +void +send_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H diff --git a/src/messenger/gnunet-service-messenger_message_store.c b/src/messenger/gnunet-service-messenger_message_store.c new file mode 100644 index 000000000..5933d6390 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_store.c @@ -0,0 +1,282 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_store.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_message_store.h" +#include "messenger_api_message.h" + +void +init_message_store (struct GNUNET_MESSENGER_MessageStore *store) +{ + store->storage_messages = NULL; + + store->entries = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + store->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); +} + +static int +iterate_destroy_entries (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_MessageEntry *entry = value; + + GNUNET_free(entry); + + return GNUNET_YES; +} + +static int +iterate_destroy_messages (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Message *message = value; + + destroy_message (message); + + return GNUNET_YES; +} + +void +clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) +{ + if (store->storage_messages) + { + GNUNET_DISK_file_close (store->storage_messages); + + store->storage_messages = NULL; + } + + GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_destroy_entries, NULL); + GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_destroy_messages, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (store->entries); + GNUNET_CONTAINER_multihashmap_destroy (store->messages); +} + +struct GNUNET_MESSENGER_MessageEntryStorage +{ + struct GNUNET_HashCode hash; + struct GNUNET_MESSENGER_MessageEntry entry; +}; + +void +load_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory) +{ + enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + + if (store->storage_messages) + GNUNET_DISK_file_close (store->storage_messages); + + char *filename; + GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); + + if (GNUNET_YES == GNUNET_DISK_file_test (filename)) + store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); + else + store->storage_messages = NULL; + + GNUNET_free(filename); + + if (!store->storage_messages) + return; + + GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); + + if (GNUNET_YES != GNUNET_DISK_file_test (filename)) + goto free_filename; + + struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); + + if (!entries) + goto free_filename; + + struct GNUNET_MESSENGER_MessageEntryStorage storage; + struct GNUNET_MESSENGER_MessageEntry *entry; + + do + { + entry = GNUNET_new(struct GNUNET_MESSENGER_MessageEntry); + + if (GNUNET_DISK_file_read (entries, &storage, sizeof(storage)) == sizeof(storage)) + { + GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry)); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + GNUNET_free(entry); + } + else + { + GNUNET_free(entry); + + entry = NULL; + } + } + while (entry); + + GNUNET_DISK_file_close (entries); + +free_filename: + GNUNET_free(filename); +} + +struct GNUNET_MESSENGER_MessageSave +{ + struct GNUNET_MESSENGER_MessageStore *store; + + struct GNUNET_DISK_FileHandle *storage_entries; +}; + +static int +iterate_save_messages (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_MessageSave *save = cls; + + if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key)) + return GNUNET_YES; + + struct GNUNET_MESSENGER_Message *message = value; + struct GNUNET_MESSENGER_MessageEntryStorage storage; + + GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash)); + + storage.entry.length = get_message_size (message); + storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END); + + if ((GNUNET_SYSERR == storage.entry.offset) || + (sizeof(storage) != GNUNET_DISK_file_write (save->storage_entries, &storage, sizeof(storage)))) + return GNUNET_YES; + + char *buffer = GNUNET_malloc(storage.entry.length); + + encode_message (message, storage.entry.length, buffer); + + GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length); + + GNUNET_free(buffer); + + return GNUNET_YES; +} + +void +save_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory) +{ + struct GNUNET_MESSENGER_MessageSave save; + + enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + + char *filename; + GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); + + save.store = store; + save.storage_entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); + + GNUNET_free(filename); + + if (!save.storage_entries) + return; + + if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage_entries, 0, GNUNET_DISK_SEEK_END)) + goto close_entries; + + if (store->storage_messages) + GNUNET_DISK_file_close (store->storage_messages); + + GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); + + store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, + permission); + + GNUNET_free(filename); + + if (store->storage_messages) + { + GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_save_messages, &save); + + GNUNET_DISK_file_sync (store->storage_messages); + GNUNET_DISK_file_sync (save.storage_entries); + } + +close_entries: + GNUNET_DISK_file_close (save.storage_entries); +} + +int +contains_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash) +{ + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages, hash)) + return GNUNET_YES; + + return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash); +} + +const struct GNUNET_MESSENGER_Message* +get_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash); + + if (message) + return message; + + if (!store->storage_messages) + return NULL; + + const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); + + if (!entry) + return NULL; + + if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) + return message; + + char *buffer = GNUNET_malloc(entry->length); + + if (GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) + goto free_buffer; + + + message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN); + + if ((GNUNET_YES != decode_message (message, entry->length, buffer)) || (GNUNET_OK + != GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + { + destroy_message (message); + + message = NULL; + + GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry); + } + +free_buffer: + GNUNET_free(buffer); + + return message; +} + +int +put_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, + struct GNUNET_MESSENGER_Message *message) +{ + return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); +} diff --git a/src/messenger/gnunet-service-messenger_message_store.h b/src/messenger/gnunet-service-messenger_message_store.h new file mode 100644 index 000000000..e58459b21 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_message_store.h @@ -0,0 +1,120 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_message_store.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H +#define GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H + +#include "platform.h" +#include "gnunet_container_lib.h" +#include "gnunet_disk_lib.h" + +struct GNUNET_MESSENGER_MessageEntry +{ + off_t offset; + uint16_t length; +}; + +struct GNUNET_MESSENGER_MessageStore +{ + struct GNUNET_DISK_FileHandle *storage_messages; + + struct GNUNET_CONTAINER_MultiHashMap *entries; + struct GNUNET_CONTAINER_MultiHashMap *messages; +}; + +/** + * Initializes a message store as fully empty. + * + * @param store Message store + */ +void +init_message_store (struct GNUNET_MESSENGER_MessageStore *store); + +/** + * Clears a message store, wipes its content and deallocates its memory. + * + * @param store Message store + */ +void +clear_message_store (struct GNUNET_MESSENGER_MessageStore *store); + +/** + * Loads messages from a directory into a message store. + * + * @param store Message store + * @param directory Path to a directory + */ +void +load_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory); + +/** + * Saves messages from a message store into a directory. + * + * @param store Message store + * @param directory Path to a directory + */ +void +save_message_store (struct GNUNET_MESSENGER_MessageStore *store, const char *directory); + +/** + * Checks if a message matching a given hash is stored in a message store. The function returns + * GNUNET_YES if a match is found, GNUNET_NO otherwise. + * + * The message has not to be loaded from disk into memory for this check! + * + * @param store Message store + * @param hash Hash of message + * @return GNUNET_YES on match, otherwise GNUNET_NO + */ +int +contains_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash); + +/** + * Returns the message from a message store matching a given hash. If no matching message is found, + * NULL gets returned. + * + * This function requires the message to be loaded into memory! + * @see contains_store_message() + * + * @param store Message store + * @param hash Hash of message + * @return Message or NULL + */ +const struct GNUNET_MESSENGER_Message* +get_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash); + +/** + * Stores a message into the message store. The result indicates if the operation was successful. + * + * @param store Message store + * @param hash Hash of message + * @param message Message + * @return GNUNET_OK on success, otherwise GNUNET_NO + */ +int +put_store_message (struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash, + struct GNUNET_MESSENGER_Message *message); + +#endif //GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H diff --git a/src/messenger/gnunet-service-messenger_room.c b/src/messenger/gnunet-service-messenger_room.c new file mode 100644 index 000000000..7383e1d20 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_room.c @@ -0,0 +1,1051 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_room.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_room.h" + +#include "gnunet-service-messenger_message_kind.h" + +#include "gnunet-service-messenger_service.h" +#include "gnunet-service-messenger_util.h" + +static void +idle_request_room_messages (void *cls); + +struct GNUNET_MESSENGER_SrvRoom* +create_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key) +{ + GNUNET_assert((handle) && (key)); + + struct GNUNET_MESSENGER_SrvRoom *room = GNUNET_new(struct GNUNET_MESSENGER_SrvRoom); + + room->service = handle->service; + room->host = handle; + room->port = NULL; + + GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode)); + + room->tunnels = GNUNET_CONTAINER_multipeermap_create (8, GNUNET_NO); + room->members = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO); + room->member_infos = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO); + + init_message_store (&(room->store)); + room->requested = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + init_list_tunnels (&(room->basement)); + init_list_messages (&(room->last_messages)); + + room->peer_message = NULL; + + init_list_messages (&(room->handling)); + room->idle = NULL; + + room->strict_access = GNUNET_NO; + + if (room->service->dir) + load_service_room_and_messages (room->service, room); + + room->idle = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, idle_request_room_messages, room); + + return room; +} + +static int +iterate_destroy_tunnels (void *cls, const struct GNUNET_PeerIdentity *key, void *value) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = value; + destroy_tunnel (tunnel); + return GNUNET_YES; +} + +static int +iterate_clear_members (void *cls, const struct GNUNET_ShortHashCode *key, void *value) +{ + struct GNUNET_MESSENGER_SrvContact *contact = value; + + if (GNUNET_YES == decrease_contact_rc (contact)) + { + struct GNUNET_MESSENGER_SrvRoom *room = cls; + + const struct GNUNET_HashCode *id = get_contact_id_from_key (contact); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (room->service->contacts, id, contact)) + destroy_contact (contact); + } + + return GNUNET_YES; +} + +static int +iterate_destroy_member_infos (void *cls, const struct GNUNET_ShortHashCode *key, void *value) +{ + struct GNUNET_MESSENGER_MemberInfo *info = value; + + clear_list_messages (&(info->session_messages)); + + GNUNET_free(info); + return GNUNET_YES; +} + +void +destroy_room (struct GNUNET_MESSENGER_SrvRoom *room) +{ + GNUNET_assert(room); + + if (room->idle) + { + GNUNET_SCHEDULER_cancel (room->idle); + + room->idle = NULL; + } + + if (room->port) + GNUNET_CADET_close_port (room->port); + + merge_room_last_messages (room, room->host); + + GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_destroy_tunnels, + NULL); + + handle_room_messages (room); + + if (room->service->dir) + save_service_room_and_messages (room->service, room); + + GNUNET_CONTAINER_multishortmap_iterate (room->members, iterate_clear_members, room); + GNUNET_CONTAINER_multishortmap_iterate (room->member_infos, iterate_destroy_member_infos, NULL); + + clear_message_store (&(room->store)); + + GNUNET_CONTAINER_multihashmap_destroy (room->requested); + + GNUNET_CONTAINER_multipeermap_destroy (room->tunnels); + GNUNET_CONTAINER_multishortmap_destroy (room->members); + GNUNET_CONTAINER_multishortmap_destroy (room->member_infos); + + clear_list_tunnels (&(room->basement)); + clear_list_messages (&(room->last_messages)); + + if (room->peer_message) + GNUNET_free(room->peer_message); + + GNUNET_free(room); +} + +struct GNUNET_MESSENGER_SrvContact* +get_room_contact (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id) +{ + GNUNET_assert((room) && (room->members)); + + return GNUNET_CONTAINER_multishortmap_get (room->members, id); +} + +void +add_room_contact (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + struct GNUNET_MESSENGER_SrvContact *contact = get_service_contact_by_pubkey (room->service, pubkey); + + if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put (room->members, id, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + increase_contact_rc (contact); +} + +struct GNUNET_MESSENGER_MemberInfo* +get_room_member_info (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id) +{ + GNUNET_assert((room) && (room->member_infos)); + + return GNUNET_CONTAINER_multishortmap_get (room->member_infos, id); +} + +struct GNUNET_ShortHashCode* +generate_room_member_id (const struct GNUNET_MESSENGER_SrvRoom *room) +{ + struct GNUNET_ShortHashCode *unique_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_assert(room); + + if (GNUNET_YES == generate_free_member_id (unique_id, room->members)) + return unique_id; + else + { + GNUNET_free(unique_id); + return NULL; + } +} + +const struct GNUNET_ShortHashCode* +get_room_host_id (const struct GNUNET_MESSENGER_SrvRoom *room) +{ + GNUNET_assert(room); + + return get_handle_member_id (room->host, &(room->key)); +} + +void +change_room_host_id (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *unique_id) +{ + GNUNET_assert(room); + + change_handle_member_id (room->host, &(room->key), unique_id); +} + +static int +send_room_info (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + if (!handle) + return GNUNET_NO; + + merge_room_last_messages (room, handle); + + if (!is_tunnel_connected (tunnel)) + return GNUNET_NO; + + struct GNUNET_MESSENGER_Message *message = create_message_info (get_handle_ego(handle), room->members); + + if (!message) + return GNUNET_NO; + + if ((tunnel->peer_message) && (tunnel->contact_id)) + { + GNUNET_memcpy(&(message->body.info.unique_id), &(tunnel->contact_id), sizeof(struct GNUNET_ShortHashCode)); + GNUNET_free(tunnel->contact_id); + + tunnel->contact_id = NULL; + } + + struct GNUNET_HashCode hash; + + send_tunnel_message (tunnel, handle, message, &hash); + destroy_message (message); + + if (tunnel->contact_id) + { + GNUNET_free(tunnel->contact_id); + + tunnel->contact_id = NULL; + } + + return GNUNET_YES; +} + +static void* +callback_room_connect (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source) +{ + struct GNUNET_MESSENGER_SrvRoom *room = cls; + + struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, source); + + if (tunnel) + { + if (GNUNET_YES == bind_tunnel (tunnel, channel)) + { + if (GNUNET_YES == send_room_info (room, room->host, tunnel)) + return tunnel; + else + { + disconnect_tunnel (tunnel); + return NULL; + } + } + else + { + delayed_disconnect_channel (channel); + return NULL; + } + } + else + { + tunnel = create_tunnel (room, source); + + if ((GNUNET_YES == bind_tunnel (tunnel, channel)) && (GNUNET_OK + == GNUNET_CONTAINER_multipeermap_put (room->tunnels, source, tunnel, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + { + if (GNUNET_YES == send_room_info (room, room->host, tunnel)) + return tunnel; + else + { + GNUNET_CONTAINER_multipeermap_remove (room->tunnels, source, tunnel); + + disconnect_tunnel (tunnel); + destroy_tunnel (tunnel); + return NULL; + } + } + else + { + tunnel->channel = NULL; + destroy_tunnel (tunnel); + + delayed_disconnect_channel (channel); + return NULL; + } + } +} + +static int +join_room (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_ShortHashCode *member_id) +{ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s(get_room_key(room)), GNUNET_sh2s(member_id)); + + struct GNUNET_MESSENGER_Message *message = create_message_join (get_handle_ego(handle)); + + if (!message) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be created!\n"); + + return GNUNET_NO; + } + + struct GNUNET_HashCode hash; + + send_room_message (room, handle, message, &hash); + destroy_message (message); + + struct GNUNET_MESSENGER_MemberInfo *info = GNUNET_new(struct GNUNET_MESSENGER_MemberInfo); + + info->access = GNUNET_MESSENGER_MEMBER_ALLOWED; + init_list_messages (&(info->session_messages)); + + if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_put (room->member_infos, member_id, info, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + change_handle_member_id (handle, &(room->key), member_id); + + add_to_list_messages (&(info->session_messages), &hash); + return GNUNET_YES; + } + else + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Your member information could not be registered!\n"); + + GNUNET_free(info); + return GNUNET_NO; + } +} + +static int +join_room_locally (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle) +{ + const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, &(room->key)); + + struct GNUNET_MESSENGER_MemberInfo *info = GNUNET_CONTAINER_multishortmap_get (room->member_infos, member_id); + + if ((!info) && (GNUNET_NO == join_room (room, handle, member_id))) + return GNUNET_NO; + + return GNUNET_YES; +} + +extern int +check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header); +extern void +handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header); + +extern void +callback_tunnel_disconnect (void *cls, const struct GNUNET_CADET_Channel *channel); + +int +open_room (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle) +{ + if (room->port) + return join_room_locally (room, handle); + + struct GNUNET_CADET_Handle *cadet = get_room_cadet (room); + struct GNUNET_HashCode *key = get_room_key (room); + + struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, + struct GNUNET_MessageHeader, NULL), + GNUNET_MQ_handler_end() }; + + room->port = GNUNET_CADET_open_port (cadet, key, callback_room_connect, room, NULL, + callback_tunnel_disconnect, handlers); + + const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, &(room->key)); + + struct GNUNET_MESSENGER_MemberInfo *info = GNUNET_CONTAINER_multishortmap_get (room->member_infos, member_id); + + if ((!info) && (GNUNET_NO == join_room (room, handle, member_id)) && (room->port)) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, therefore it keeps closed!\n"); + + GNUNET_CADET_close_port (room->port); + room->port = NULL; + + return GNUNET_NO; + } + + struct GNUNET_MESSENGER_Message *message = create_message_peer (room->service); + + if (message) + { + struct GNUNET_HashCode hash; + + send_room_message (room, handle, message, &hash); + destroy_message (message); + } + + return (room->port ? GNUNET_YES : GNUNET_NO); +} + +int +entry_room_at (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_PeerIdentity *door) +{ + if (room->peer_message) + { + const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, handle, room->peer_message, GNUNET_NO); + + if (0 == GNUNET_memcmp(&(msg->body.peer.peer), door)) + return join_room_locally (room, handle); + } + + struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, door); + + if (tunnel) + { + switch (connect_tunnel (tunnel)) + { + case GNUNET_YES: + return GNUNET_YES; + case GNUNET_NO: + return join_room_locally (room, handle); + default: + return GNUNET_NO; + } + } + + tunnel = create_tunnel (room, door); + + if ((GNUNET_YES == connect_tunnel (tunnel)) && + (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (room->tunnels, door, tunnel, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + return GNUNET_YES; + else + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that door!\n"); + + destroy_tunnel (tunnel); + return GNUNET_NO; + } +} + +struct GNUNET_MESSENGER_SrvTunnelFinder +{ + const struct GNUNET_ShortHashCode *needle; + struct GNUNET_MESSENGER_SrvTunnel *tunnel; +}; + +static int +iterate_find_tunnel (void *cls, const struct GNUNET_PeerIdentity *peer, void *value) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = value; + struct GNUNET_MESSENGER_SrvTunnelFinder *finder = cls; + + if ((tunnel->contact_id) && (0 == GNUNET_memcmp(tunnel->contact_id, finder->needle))) + { + finder->tunnel = tunnel; + return GNUNET_NO; + } + + return GNUNET_YES; +} + +struct GNUNET_MESSENGER_SrvTunnel* +find_room_tunnel_to (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *contact_id) +{ + struct GNUNET_MESSENGER_SrvTunnelFinder finder; + + finder.needle = contact_id; + finder.tunnel = NULL; + + GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_find_tunnel, &finder); + + return finder.tunnel; +} + +struct GNUNET_MQ_Envelope* +pack_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, int mode) +{ + message->header.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); + + const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, &(room->key)); + + GNUNET_assert(id); + + GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode)); + + if (room->last_messages.head) + GNUNET_memcpy(&(message->header.previous), &(room->last_messages.head->hash), sizeof(struct GNUNET_HashCode)); + else + memset (&(message->header.previous), 0, sizeof(struct GNUNET_HashCode)); + + return pack_message (message, hash, get_handle_ego (handle), mode); +} + +struct GNUNET_MESSENGER_ClosureSendRoom +{ + struct GNUNET_MESSENGER_SrvRoom *room; + struct GNUNET_MESSENGER_SrvHandle *handle; + struct GNUNET_MESSENGER_SrvTunnel *exclude; + struct GNUNET_MESSENGER_Message *message; + struct GNUNET_HashCode *hash; + int packed; +}; + +static int +iterate_send_room_message (void *cls, const struct GNUNET_PeerIdentity *key, void *value) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = value; + + if ((!is_tunnel_connected (tunnel)) || (!tunnel->contact_id)) + return GNUNET_YES; + + struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls; + + if (tunnel == closure->exclude) + return GNUNET_YES; + + struct GNUNET_MQ_Envelope *env = NULL; + + if (closure->packed == GNUNET_NO) + { + env = pack_room_message (closure->room, closure->handle, closure->message, closure->hash, + GNUNET_MESSENGER_PACK_MODE_ENVELOPE); + + if (env) + { + closure->message = copy_message (closure->message); + closure->packed = GNUNET_YES; + } + } + else + { + env = pack_message (closure->message, NULL, NULL, + GNUNET_MESSENGER_PACK_MODE_ENVELOPE); + } + + if (env) + send_tunnel_envelope (tunnel, closure->handle, env, closure->message, closure->hash); + + return GNUNET_YES; +} + +void +callback_room_sent (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +void +send_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ClosureSendRoom closure; + + closure.room = room; + closure.handle = handle; + closure.exclude = NULL; + closure.message = message; + closure.hash = hash; + closure.packed = GNUNET_NO; + + GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_send_room_message, &closure); + + if ((GNUNET_NO == closure.packed) && (closure.message == message)) + { + pack_room_message (room, handle, message, hash, + GNUNET_MESSENGER_PACK_MODE_UNKNOWN); + + callback_room_sent (room, handle, NULL, copy_message (message), hash); + } +} + +void +send_room_message_ext (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, + struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + struct GNUNET_MESSENGER_ClosureSendRoom closure; + + closure.room = room; + closure.handle = handle; + closure.exclude = tunnel; + closure.message = message; + closure.hash = hash; + closure.packed = GNUNET_NO; + + GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_send_room_message, &closure); + + if ((GNUNET_NO == closure.packed) && (closure.message == message)) + { + pack_room_message (room, handle, message, hash, + GNUNET_MESSENGER_PACK_MODE_UNKNOWN); + + callback_room_sent (room, handle, NULL, copy_message (message), hash); + } +} + +void +forward_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ClosureSendRoom closure; + struct GNUNET_HashCode message_hash; + + GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode)); + + closure.room = room; + closure.handle = NULL; + closure.exclude = tunnel; + closure.message = copy_message (message); + closure.hash = &message_hash; + closure.packed = GNUNET_YES; + + GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_send_room_message, &closure); +} + +void +merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle) +{ + if (!handle) + return; + + if (!room->last_messages.head) + return; + + while (room->last_messages.head != room->last_messages.tail) + { + struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.tail; + + struct GNUNET_MESSENGER_Message *message = create_message_merge (&(element->hash)); + + if (message) + { + struct GNUNET_HashCode hash; + + send_room_message (room, handle, message, &hash); + destroy_message (message); + } + + if (element->prev) + GNUNET_CONTAINER_DLL_remove(room->last_messages.head, room->last_messages.tail, element); + } +} + +struct GNUNET_CADET_Handle* +get_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room) +{ + return room->service->cadet; +} + +struct GNUNET_HashCode* +get_room_key (struct GNUNET_MESSENGER_SrvRoom *room) +{ + return &(room->key); +} + +const struct GNUNET_MESSENGER_SrvTunnel* +get_room_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *peer) +{ + return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer); +} + +const struct GNUNET_MESSENGER_Message* +get_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *hash, int request) +{ + const struct GNUNET_MESSENGER_Message *message = get_store_message (&(room->store), hash); + + if ((message) || (!handle) || (GNUNET_YES != request) + || (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->requested, hash))) + return message; + + struct GNUNET_MESSENGER_Message *request_msg = create_message_request (hash); + + if (request_msg) + { + if (GNUNET_CONTAINER_multihashmap_put (room->requested, hash, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST) == GNUNET_OK) + { + struct GNUNET_HashCode request_hash; + + send_room_message (room, handle, request_msg, &request_hash); + } + + destroy_message (request_msg); + } + + return message; +} + +void +callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room, void *cls) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; + + if (!room->host) + return; + + struct GNUNET_PeerIdentity identity; + + GNUNET_PEER_resolve (tunnel->peer, &identity); + + if (GNUNET_YES == contains_list_tunnels (&(room->basement), &identity)) + { + struct GNUNET_MESSENGER_Message *message = create_message_miss (&identity); + + if (message) + { + struct GNUNET_HashCode hash; + + send_room_message (room, room->host, message, &hash); + destroy_message (message); + } + } +} + +int +callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash) +{ + if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind) + return GNUNET_SYSERR; + + struct GNUNET_MESSENGER_SrvContact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, + &(message->header.sender_id)); + + if (!contact) + { + if (GNUNET_MESSENGER_KIND_INFO == message->header.kind) + contact = get_service_contact_by_pubkey (room->service, &(message->body.info.host_key)); + else if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind) + contact = get_service_contact_by_pubkey (room->service, &(message->body.join.key)); + } + + if ((!contact) || (GNUNET_SYSERR == verify_message (message, hash, get_contact_key (contact)))) + return GNUNET_SYSERR; + + if (GNUNET_YES == room->strict_access) + { + struct GNUNET_MESSENGER_MemberInfo *info = GNUNET_CONTAINER_multishortmap_get (room->member_infos, + &(message->header.sender_id)); + + if ((info) && (GNUNET_MESSENGER_MEMBER_BLOCKED == info->access)) + return GNUNET_SYSERR; + } + + if (GNUNET_YES == contains_store_message (&(room->store), hash)) + return GNUNET_NO; + + return GNUNET_YES; +} + +static void +search_room_for_message (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_HashCode *hash) +{ + const struct GNUNET_MESSENGER_Message *message = get_room_message (room, room->host, hash, GNUNET_YES); + + if (!message) + return; + + if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind) + search_room_for_message (room, &(message->body.merge.previous)); + + search_room_for_message (room, &(message->header.previous)); +} + +static void +idle_request_room_messages (void *cls) +{ + struct GNUNET_MESSENGER_SrvRoom *room = cls; + + room->idle = NULL; + + struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.head; + + while (element) + { + search_room_for_message (room, &(element->hash)); + + element = element->next; + } + + merge_room_last_messages (room, room->host); + + room->idle = GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_second_ (), + GNUNET_SCHEDULER_PRIORITY_IDLE, idle_request_room_messages, + cls); +} + +void +update_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ListMessage *element = room->last_messages.head; + struct GNUNET_MESSENGER_ListMessage *merging = NULL; + + if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind) + { + merging = room->last_messages.head; + + while (merging) + { + if (0 == GNUNET_CRYPTO_hash_cmp (&(merging->hash), &(message->body.merge.previous))) + break; + + merging = merging->next; + } + + if (merging) + element = merging->next; + } + + while (element) + { + if (0 == GNUNET_CRYPTO_hash_cmp (&(element->hash), &(message->header.previous))) + break; + + element = element->next; + } + + if ((merging) && (!element)) + { + element = merging; + merging = NULL; + } + + if (element) + { + GNUNET_memcpy(&(element->hash), hash, sizeof(struct GNUNET_HashCode)); + + if (merging) + GNUNET_CONTAINER_DLL_remove(room->last_messages.head, room->last_messages.tail, merging); + } + else + add_to_list_messages (&(room->last_messages), hash); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (room->requested, hash)) + GNUNET_CONTAINER_multihashmap_remove_all (room->requested, hash); +} + +void +switch_room_member_id (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *old_id, + const struct GNUNET_ShortHashCode *new_id, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_SrvContact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, old_id); + + if ((contact) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (room->members, old_id, contact))) + GNUNET_CONTAINER_multishortmap_put (room->members, new_id, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + + struct GNUNET_MESSENGER_MemberInfo *info = GNUNET_CONTAINER_multishortmap_get (room->member_infos, old_id); + + if ((!info) || (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove (room->member_infos, old_id, contact)) + || (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put (room->member_infos, new_id, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + return; + + if (hash) + add_to_list_messages (&(info->session_messages), hash); +} + +void +rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room) +{ + struct GNUNET_PeerIdentity peer; + size_t src; + + if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) || (!find_list_tunnels (&(room->basement), &peer, + &src))) + return; + + size_t count = count_of_tunnels (&(room->basement)); + + struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head; + struct GNUNET_MESSENGER_SrvTunnel *tunnel; + + size_t dst = 0; + + while (element) + { + GNUNET_PEER_resolve (element->peer, &peer); + + tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, &peer); + + if (!tunnel) + { + element = remove_from_list_tunnels (&(room->basement), element); + continue; + } + + if (GNUNET_YES == required_connection_between (count, src, dst)) + { + if (GNUNET_SYSERR == connect_tunnel (tunnel)) + { + element = remove_from_list_tunnels (&(room->basement), element); + continue; + } + } + else + disconnect_tunnel (tunnel); + + element = element->next; + dst++; + } +} + +void +handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room) +{ + while (room->handling.head) + { + struct GNUNET_MESSENGER_ListMessage *element = room->handling.head; + + const struct GNUNET_MESSENGER_Message *msg = get_room_message (room, room->host, &(element->hash), GNUNET_NO); + + if (msg) + handle_service_message (room->service, room, msg, &(element->hash)); + + GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element); + GNUNET_free(element); + } +} + +#include "gnunet-service-messenger_message_recv.h" + +void +callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; + + if (GNUNET_OK != put_store_message (&(room->store), hash, message)) + return; + + update_room_last_messages (room, message, hash); + + if (GNUNET_MESSENGER_KIND_INFO != message->header.kind) + forward_room_message (room, tunnel, message, hash); + + const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES; + + add_to_list_messages (&(room->handling), hash); + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_INFO: + recv_message_info (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_JOIN: + recv_message_join (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + recv_message_leave (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_NAME: + recv_message_name (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_KEY: + recv_message_key (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_PEER: + recv_message_peer (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_ID: + recv_message_id (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_MISS: + recv_message_miss (room, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_REQUEST: + recv_message_request (room, tunnel, message, hash); + break; + default: + break; + } + + if (GNUNET_YES == start_handle) + handle_room_messages (room); +} + +#include "gnunet-service-messenger_message_send.h" + +void +callback_room_sent (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + const struct GNUNET_MESSENGER_Message *old_message = get_room_message (room, handle, hash, GNUNET_NO); + + if ((old_message) || (GNUNET_OK != put_store_message (&(room->store), hash, message))) + { + if (old_message != message) + GNUNET_free(message); + } + else + { + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; // may be NULL + + update_room_last_messages (room, message, hash); + + const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES; + + add_to_list_messages (&(room->handling), hash); + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_INFO: + send_message_info (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_JOIN: + send_message_join (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + send_message_leave (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_NAME: + send_message_name (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_KEY: + send_message_key (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_PEER: + send_message_peer (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_ID: + send_message_id (room, handle, tunnel, message, hash); + break; + case GNUNET_MESSENGER_KIND_MISS: + send_message_miss (room, handle, tunnel, message, hash); + break; + default: + break; + } + + if (GNUNET_YES == start_handle) + handle_room_messages (room); + } +} diff --git a/src/messenger/gnunet-service-messenger_room.h b/src/messenger/gnunet-service-messenger_room.h new file mode 100644 index 000000000..36c9e8cf5 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_room.h @@ -0,0 +1,378 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_room.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_ROOM_H +#define GNUNET_SERVICE_MESSENGER_ROOM_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_mq_lib.h" + +#include "gnunet-service-messenger_contact.h" + +#include "gnunet_messenger_service.h" +#include "gnunet-service-messenger_basement.h" +#include "gnunet-service-messenger_handle.h" +#include "gnunet-service-messenger_tunnel.h" + +#include "gnunet-service-messenger_list_messages.h" +#include "messenger_api_list_tunnels.h" + +#include "gnunet-service-messenger_message_store.h" +#include "messenger_api_ego.h" + +enum GNUNET_MESSENGER_MemberAccess +{ + GNUNET_MESSENGER_MEMBER_ALLOWED = 1, + GNUNET_MESSENGER_MEMBER_BLOCKED = 1, + + GNUNET_MESSENGER_MEMBER_UNKNOWN = 0 +}; + +struct GNUNET_MESSENGER_MemberInfo +{ + enum GNUNET_MESSENGER_MemberAccess access; + + struct GNUNET_MESSENGER_ListMessages session_messages; +}; + +struct GNUNET_MESSENGER_SrvRoom +{ + struct GNUNET_MESSENGER_Service *service; + struct GNUNET_MESSENGER_SrvHandle *host; + struct GNUNET_CADET_Port *port; + + struct GNUNET_HashCode key; + + struct GNUNET_CONTAINER_MultiPeerMap *tunnels; + struct GNUNET_CONTAINER_MultiShortmap *members; + struct GNUNET_CONTAINER_MultiShortmap *member_infos; + + struct GNUNET_MESSENGER_MessageStore store; + struct GNUNET_CONTAINER_MultiHashMap *requested; + + struct GNUNET_MESSENGER_ListTunnels basement; + struct GNUNET_MESSENGER_ListMessages last_messages; + + struct GNUNET_HashCode *peer_message; + + struct GNUNET_MESSENGER_ListMessages handling; + struct GNUNET_SCHEDULER_Task *idle; + + int strict_access; +}; + +/** + * Creates and allocates a new room for a handle with a given key. + * + * @param handle Handle + * @param key Key of room + * @return New room + */ +struct GNUNET_MESSENGER_SrvRoom* +create_room (struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key); + +/** + * Destroys a room and frees its memory fully. + * + * @param room Room + */ +void +destroy_room (struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Returns the contact of a member in a room identified by a given id. If the room + * does not contain a member with the given id, NULL gets returned. + * + * @param room Room + * @param id Member id + * @return Contact or NULL + */ +struct GNUNET_MESSENGER_SrvContact* +get_room_contact (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id); + +/** + * Adds a contact from the service to a room under a specific id with a given public key. + * + * @param room Room + * @param id Member id + * @param pubkey Public key of EGO + */ +void +add_room_contact (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id, + const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Returns the member information of a member in a room identified by a given id. If the room + * does not contain a member with the given id, NULL gets returned. + * + * @param room Room + * @param id Member id + * @return Member information or NULL + */ +struct GNUNET_MESSENGER_MemberInfo* +get_room_member_info (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *id); + +/** + * Tries to generate and allocate a new unique member id checking all current members for possible + * duplicates. If the function fails, NULL gets returned. + * + * @param room Room + * @return New member id or NULL + */ +struct GNUNET_ShortHashCode* +generate_room_member_id (const struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Returns the member id of the member representing the handle currently hosting this room. + * + * @param room Room + * @return Host member id or NULL + */ +const struct GNUNET_ShortHashCode* +get_room_host_id (const struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Changes the member id of the member representing the handle currently hosting this room. + * + * @param room Room + * @param unique_id Unique member id + */ +void +change_room_host_id (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *unique_id); + +/** + * Tries to open a room for a given handle. If the room has already been opened, the handle + * will locally join the room. + * + * Calling this method should result in joining a room and sending a peer message as well for this peer. + * + * If the function returns GNUNET_YES the port for this room is guranteed to be open for incoming connections. + * + * @param room Room + * @param handle Handle + * @return GNUNET_YES on success, GNUNET_NO on failure. + */ +int +open_room (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Connects a tunnel to a hosting peer of a room through a so called door which is represented by + * a peer identity of a hosting peer. During the connection the handle will join the room as a member, waiting for + * an info message from the selected host. + * + * @param room Room + * @param handle Handle + * @param door Peer identity + * @return GNUNET_YES on success, GNUNET_NO on failure. + */ +int +entry_room_at (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_PeerIdentity *door); + +/** + * Returns a tunnel granting a direct connection to a specific member in a room. The member gets identified + * by an id. If no tunnel has been linked to the selected id, NULL gets returned. + * + * @param room Room + * @param contact_id Member id + * @return Tunnel to the member or NULL + */ +struct GNUNET_MESSENGER_SrvTunnel* +find_room_tunnel_to (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *contact_id); + +/** + * Packs a message depending on the selected mode into a newly allocated envelope. It will set the + * timestamp of the message, the sender id and the previous messages hash automatically before packing. The message + * will be signed by the handles EGO. + * + * If the optional hash parameter is a valid pointer, its value will be overriden by the signed messages hash. + * + * If mode is set to GNUNET_MESSENGER_PACK_MODE_ENVELOPE, the function returns a valid envelope to send + * through a message queue, otherwise NULL. + * + * @param room Room + * @param handle Handle + * @param message Message + * @param[out] hash Hash of message + * @param mode Packing mode + * @return New envelope or NULL + */ +struct GNUNET_MQ_Envelope* +pack_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, int mode); + +/** + * Sends a message from a given handle into a room. The hash parameter will be + * updated with the hash-value resulting from the sent message. + * + * The function handles packing the message automatically and will call linked message-events locally even if + * the message won't be sent to another peer. + * + * @param room Room + * @param handle Handle + * @param message Message + * @param[out] hash Hash of message + */ +void +send_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash); + +/** + * Sends a message from a given handle into a room excluding one specific tunnel. + * The hash parameter will be updated with the hash-value resulting from the sent message. + * + * The function handles packing the message automatically and will call linked message-events locally even if + * the message won't be sent to another peer. + * + * @param room Room + * @param handle Handle + * @param message Message + * @param[out] hash Hash of message + * @param tunnel Tunnel + */ +void +send_room_message_ext (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, + struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +/** + * Forwards a message with a given hash to a specific tunnel inside of a room. + * + * @param room Room + * @param tunnel Tunnel + * @param message Message + * @param hash Hash of message + */ +void +forward_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel, + const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Reduces all current forks inside of the message history of a room to one remaining last message + * by merging them down. All merge messages will be sent from a given handle. + * + * @param room Room + * @param handle Handle + */ +void +merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Returns the CADET handle from a rooms service. + * + * @param room Room + * @return CADET handle + */ +struct GNUNET_CADET_Handle* +get_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Returns the shared secret you need to access a room. + * + * @param room Room + * @return Shared secret + */ +struct GNUNET_HashCode* +get_room_key (struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Returns a tunnel inside of a room leading towards a given peer if such a tunnel exists, + * otherwise NULL. + * + * @param room Room + * @param peer Peer identity + * @return Tunnel or NULL + */ +const struct GNUNET_MESSENGER_SrvTunnel* +get_room_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *peer); + +/** + * Returns a message from a room identified by a given hash. If no matching message is + * found and request is set to GNUNET_YES, the handle will request the missing message + * automatically. + * + * The function uses the optimized check for a message via its hash from the message store. + * @see contains_store_message() + * + * If a message is missing independent of the following request, NULL gets returned instead of the + * matching message. + * + * @param room Room + * @param handle Handle + * @param hash Hash of message + * @param request Flag to request a message + * @return Message or NULL + */ +const struct GNUNET_MESSENGER_Message* +get_room_message (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *hash, int request); + +/** + * Updates the last messages of a room by replacing them if the previous hash of a given message + * matches with one of the latest messages. + * + * @param room Room + * @param message Message + * @param hash Hash of message + */ +void +update_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Changes an id of a current member from an old id to a new one and adds optionally the hash of an + * id message to the members information. + * + * @param room Room + * @param old_id Old member id + * @param new_id New member id + * @param hash Hash of id message + */ +void +switch_room_member_id (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_ShortHashCode *old_id, + const struct GNUNET_ShortHashCode *new_id, const struct GNUNET_HashCode *hash); + +/** + * Rebuilds the decentralized structure for a room by ensuring all required connections are made + * depending on the amount of peers and this peers index in the list of them. + * + * @param room Room + */ +void +rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Handles all queued up messages of a room to handle in correct order. + * + * @param room Room + */ +void +handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room); + +#endif //GNUNET_SERVICE_MESSENGER_ROOM_H diff --git a/src/messenger/gnunet-service-messenger_service.c b/src/messenger/gnunet-service-messenger_service.c new file mode 100644 index 000000000..963314fd8 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_service.c @@ -0,0 +1,516 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_service.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_service.h" + +#include "gnunet-service-messenger_message_kind.h" + +#include "gnunet-service-messenger.h" +#include "gnunet-service-messenger_util.h" + +static void +callback_shutdown_service (void *cls) +{ + struct GNUNET_MESSENGER_Service *service = cls; + + if (service) + { + service->shutdown = NULL; + + destroy_service (service); + } +} + +static void +callback_update_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) +{ + if ((!ego) || (!identifier)) + return; + + struct GNUNET_MESSENGER_Service *service = cls; + + update_service_ego(service, identifier, GNUNET_IDENTITY_ego_get_private_key(ego)); +} + +struct GNUNET_MESSENGER_Service* +create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle) +{ + struct GNUNET_MESSENGER_Service *service = GNUNET_new(struct GNUNET_MESSENGER_Service); + + service->config = config; + service->service = service_handle; + + service->shutdown = GNUNET_SCHEDULER_add_shutdown (&callback_shutdown_service, service); + + service->dir = NULL; + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (service->config, + GNUNET_MESSENGER_SERVICE_NAME, + "MESSENGER_DIR", &(service->dir))) + { + if (service->dir) + GNUNET_free(service->dir); + + service->dir = NULL; + } + else + { + if ((GNUNET_YES != GNUNET_DISK_directory_test (service->dir, GNUNET_YES)) && (GNUNET_OK + != GNUNET_DISK_directory_create (service->dir))) + { + GNUNET_free(service->dir); + + service->dir = NULL; + } + } + + service->cadet = GNUNET_CADET_connect (service->config); + service->identity = GNUNET_IDENTITY_connect (service->config, &callback_update_ego, service); + + service->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + init_list_handles (&(service->handles)); + + service->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + service->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + return service; +} + +static int +iterate_destroy_egos (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Ego *ego = value; + GNUNET_free(ego); + return GNUNET_YES; +} + +static int +iterate_destroy_rooms (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_SrvRoom *room = value; + destroy_room (room); + return GNUNET_YES; +} + +static int +iterate_destroy_contacts (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_SrvContact *contact = value; + destroy_contact (contact); + return GNUNET_YES; +} + +void +destroy_service (struct GNUNET_MESSENGER_Service *service) +{ + if (service->shutdown) + { + GNUNET_SCHEDULER_cancel (service->shutdown); + + service->shutdown = NULL; + } + + GNUNET_CONTAINER_multihashmap_iterate (service->egos, iterate_destroy_egos, NULL); + + clear_list_handles (&(service->handles)); + + GNUNET_CONTAINER_multihashmap_iterate (service->rooms, iterate_destroy_rooms, NULL); + GNUNET_CONTAINER_multihashmap_iterate (service->contacts, iterate_destroy_contacts, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (service->egos); + GNUNET_CONTAINER_multihashmap_destroy (service->rooms); + GNUNET_CONTAINER_multihashmap_destroy (service->contacts); + + if (service->cadet) + { + GNUNET_CADET_disconnect (service->cadet); + + service->cadet = NULL; + } + + if (service->identity) + { + GNUNET_IDENTITY_disconnect (service->identity); + + service->identity = NULL; + } + + if (service->dir) + { + GNUNET_free(service->dir); + + service->dir = NULL; + } + + GNUNET_SERVICE_shutdown (service->service); + + GNUNET_free(service); +} + +struct GNUNET_MESSENGER_Ego* +lookup_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier) +{ + GNUNET_assert(identifier); + + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash(identifier, strlen(identifier), &hash); + return GNUNET_CONTAINER_multihashmap_get(service->egos, &hash); +} + +void +update_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier, + const struct GNUNET_IDENTITY_PrivateKey* key) +{ + GNUNET_assert((identifier) && (key)); + + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash(identifier, strlen(identifier), &hash); + + struct GNUNET_MESSENGER_Ego* ego = GNUNET_CONTAINER_multihashmap_get(service->egos, &hash); + + if (!ego) + { + ego = GNUNET_new(struct GNUNET_MESSENGER_Ego); + GNUNET_CONTAINER_multihashmap_put(service->egos, &hash, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } + + GNUNET_memcpy(&(ego->priv), key, sizeof(*key)); + + if (GNUNET_OK != GNUNET_IDENTITY_key_get_public(key, &(ego->pub))) + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n"); +} + +struct GNUNET_MESSENGER_SrvHandle* +add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq) +{ + struct GNUNET_MESSENGER_SrvHandle *handle = create_handle (service, mq); + + if (handle) + { + add_list_handle (&(service->handles), handle); + } + + return handle; +} + +void +remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle) +{ + if (!handle) + return; + + if (GNUNET_YES == remove_list_handle (&(service->handles), handle)) + destroy_handle (handle); +} + +int +get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer) +{ + return GNUNET_CRYPTO_get_peer_identity (service->config, peer); +} + +struct GNUNET_MESSENGER_SrvContact* +get_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); + + struct GNUNET_MESSENGER_SrvContact *contact = GNUNET_CONTAINER_multihashmap_get (service->contacts, &hash); + + if (contact) + return contact; + + contact = create_contact (pubkey); + + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->contacts, &hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + return contact; + + destroy_contact (contact); + return NULL; +} + +void +swap_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvContact *contact, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + const struct GNUNET_HashCode *hash = get_contact_id_from_key (contact); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (service->contacts, hash, contact)) + { + GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey)); + + hash = get_contact_id_from_key (contact); + + GNUNET_CONTAINER_multihashmap_put (service->contacts, hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } +} + +struct GNUNET_ShortHashCode* +generate_service_new_member_id (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); + + if (room) + { + return generate_room_member_id (room); + } + else + { + struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode); + generate_free_member_id (random_id, NULL); + return random_id; + } +} + +struct GNUNET_MESSENGER_SrvRoom* +get_service_room (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key) +{ + return GNUNET_CONTAINER_multihashmap_get (service->rooms, key); +} + +int +open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); + + if (room) + return open_room (room, handle); + + room = create_room (handle, key); + + if ((GNUNET_YES == open_room (room, handle)) && (GNUNET_OK + == GNUNET_CONTAINER_multihashmap_put (service->rooms, key, room, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + return GNUNET_YES; + + destroy_room (room); + return GNUNET_NO; +} + +int +entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); + + if (room) + { + if (GNUNET_YES == entry_room_at (room, handle, door)) + return GNUNET_YES; + else + return GNUNET_NO; + } + + room = create_room (handle, key); + + if ((GNUNET_YES == entry_room_at (room, handle, door)) && (GNUNET_OK + == GNUNET_CONTAINER_multihashmap_put (service->rooms, key, room, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + { + return GNUNET_YES; + } + else + { + destroy_room (room); + return GNUNET_NO; + } + +} + +int +close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); + + if (!room) + return GNUNET_NO; + + struct GNUNET_MESSENGER_Message *message = create_message_leave (); + + if (message) + { + struct GNUNET_HashCode hash; + + send_room_message (room, handle, message, &hash); + destroy_message (message); + } + + const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); + + GNUNET_assert(id); + + if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (handle->member_ids, key, id)) + return GNUNET_NO; + + struct GNUNET_MESSENGER_SrvHandle *member_handle = (struct GNUNET_MESSENGER_SrvHandle*) find_list_handle_by_member ( + &(service->handles), key); + + if (!member_handle) + { + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (service->rooms, key, room)) + { + destroy_room (room); + return GNUNET_YES; + } + else + return GNUNET_NO; + } + + if (room->host == handle) + room->host = member_handle; + + return GNUNET_YES; +} + +static void +get_room_data_subdir (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, char **dir) +{ + GNUNET_asprintf (dir, "%s%s%c%s%c", service->dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (&(room->key)), DIR_SEPARATOR); +} + +void +load_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room) +{ + char *room_dir; + get_room_data_subdir (service, room, &room_dir); + + if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES)) + { + load_message_store (&room->store, room_dir); + + char *config_file; + GNUNET_asprintf (&config_file, "%s%s", room_dir, "room.cfg"); + + struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); + + if ((GNUNET_YES == GNUNET_DISK_file_test (config_file)) && (GNUNET_OK + == GNUNET_CONFIGURATION_parse (cfg, config_file))) + { + unsigned long long access; + + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "room", "access-rule", &access)) + room->strict_access = (int) (access); + + char *message_string; + + if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "room", "last-message", &message_string)) && (message_string)) + { + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash_from_string(message_string, &hash); + + const struct GNUNET_MESSENGER_Message *message = get_room_message (room, room->host, &hash, GNUNET_NO); + + if (message) + update_room_last_messages (room, message, &hash); + + GNUNET_free(message_string); + } + } + + GNUNET_CONFIGURATION_destroy (cfg); + + GNUNET_free(config_file); + } + + GNUNET_free(room_dir); +} + +void +save_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room) +{ + if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (service->rooms, &(room->key))) + { + return; + } + + char *room_dir; + get_room_data_subdir (service, room, &room_dir); + + if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) || (GNUNET_OK + == GNUNET_DISK_directory_create (room_dir))) + { + save_message_store (&room->store, room_dir); + + char *config_file; + GNUNET_asprintf (&config_file, "%s%s", room_dir, "room.cfg"); + + struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); + + GNUNET_CONFIGURATION_set_value_number (cfg, "room", "access-rule", room->strict_access); + + if (room->last_messages.head) + GNUNET_CONFIGURATION_set_value_string (cfg, "room", "last-message", + GNUNET_h2s_full (&(room->last_messages.head->hash))); + + GNUNET_CONFIGURATION_write (cfg, config_file); + GNUNET_CONFIGURATION_destroy (cfg); + + GNUNET_free(config_file); + } + + GNUNET_free(room_dir); +} + +void +handle_service_message (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, + const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; + + const uint16_t length = get_message_size (message); + + while (element) + { + struct GNUNET_MESSENGER_SrvHandle *handle = (struct GNUNET_MESSENGER_SrvHandle*) element->handle; + + if ((handle->mq) && (get_handle_member_id (handle, &(room->key)))) + { + struct GNUNET_MESSENGER_RecvMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE); + + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash)); + + char *buffer = ((char*) msg) + sizeof(*msg); + encode_message (message, length, buffer); + + GNUNET_MQ_send (handle->mq, env); + } + + element = element->next; + } +} diff --git a/src/messenger/gnunet-service-messenger_service.h b/src/messenger/gnunet-service-messenger_service.h new file mode 100644 index 000000000..246c74771 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_service.h @@ -0,0 +1,259 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_service.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_SERVICE_H +#define GNUNET_SERVICE_MESSENGER_SERVICE_H + +#include "platform.h" +#include "gnunet_configuration_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_container_lib.h" +#include "gnunet_disk_lib.h" +#include "gnunet_identity_service.h" + +#include "messenger_api_ego.h" + +#include "gnunet-service-messenger_list_handles.h" + +#include "gnunet-service-messenger_contact.h" +#include "gnunet-service-messenger_room.h" + +struct GNUNET_MESSENGER_Service +{ + const struct GNUNET_CONFIGURATION_Handle *config; + struct GNUNET_SERVICE_Handle *service; + + struct GNUNET_SCHEDULER_Task *shutdown; + + char *dir; + + struct GNUNET_CADET_Handle *cadet; + struct GNUNET_IDENTITY_Handle *identity; + + struct GNUNET_CONTAINER_MultiHashMap *egos; + + struct GNUNET_MESSENGER_ListHandles handles; + + struct GNUNET_CONTAINER_MultiHashMap *contacts; + struct GNUNET_CONTAINER_MultiHashMap *rooms; +}; + +/** + * Creates and allocates a new service using a given config and a GNUnet service handle. + * + * @param config Configuration + * @param service_handle GNUnet service handle + * @return New service + */ +struct GNUNET_MESSENGER_Service* +create_service (const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle); + +/** + * Destroys a service and frees its memory fully. + * + * @param service Service + */ +void +destroy_service (struct GNUNET_MESSENGER_Service *service); + +/** + * Lookups an EGO which was registered to a service under + * a specific identifier. + * + * @param service Service + * @param identifier Identifier string + * @return EGO or NULL + */ +struct GNUNET_MESSENGER_Ego* +lookup_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier); + +/** + * Updates the registration of an EGO to a service under + * a specific identifier with a new key. + * + * @param service Service + * @param identifier Identifier string + * @param key Private EGO key + */ +void +update_service_ego (struct GNUNET_MESSENGER_Service *service, const char *identifier, + const struct GNUNET_IDENTITY_PrivateKey* key); + +/** + * Creates and adds a new handle to a service using a given message queue. + * + * @param service Service + * @param mq Message queue + * @return New handle + */ +struct GNUNET_MESSENGER_SrvHandle* +add_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq); + +/** + * Removes a handle from a service and destroys it. + * + * @param service Service + * @param handle Handle + */ +void +remove_service_handle (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle); + +/** + * Tries to write the peer identity of the peer running a service on to the peer + * parameter. The functions returns GNUNET_OK on success, otherwise GNUNET_SYSERR. + * + * @param service Service + * @param[out] peer Peer identity + * @return GNUNET_OK on success, otherwise GNUNET_SYSERR + */ +int +get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer); + +/** + * Returns a contact of a service identified by a given public key. If no matching contact exists, + * it will tried to create one with the specific public key. If the function still fails to do so, + * NULL gets returned. + * + * @param service Service + * @param pubkey Public key of EGO + * @return Contact + */ +struct GNUNET_MESSENGER_SrvContact* +get_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Changes the public key for a contact known to a service to a specific public key and + * updates local map entries to access the contact by its updated key. + * + * @param service Service + * @param contact Contact + * @param pubkey Public key of EGO + */ +void +swap_service_contact_by_pubkey (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvContact *contact, + const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Tries to generate and allocate a new unique member id for a given room of a service identified by its key. + * If the generation fails caused by too many tries of duplicates, it returns NULL. + * + * @param service Service + * @param key Key of room + * @return Newly generated member id or NULL + */ +struct GNUNET_ShortHashCode* +generate_service_new_member_id (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key); + +/** + * Returns the room identified by a given key for a service. If the service doesn't know any room + * using the given key, NULL gets returned. + * + * @param service Service + * @param key Key of room + * @return Room or NULL + */ +struct GNUNET_MESSENGER_SrvRoom* +get_service_room (struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key); + +/** + * Tries to open a room using a given key for a service by a specific handle. The room will be + * created if necessary. If the function is successful, it returns GNUNET_YES, otherwise GNUNET_NO. + * + * @param service Service + * @param handle Handle + * @param key Key of room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +open_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *key); + +/** + * Tries to enter a room using a given key for a service by a specific handle. The room will + * be created if necessary. If the function is successful, it returns GNUNET_YES, otherwise GNUNET_NO. + * + * The room will be entered through the peer identitied by the peer identity provided as door parameter and + * a new connection will be made. + * + * @param service Service + * @param handle Handle + * @param door Peer identity + * @param key Key of room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +entry_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key); + +/** + * Tries to close a room using a given key for a service by a specific handle. The room will + * be created if necessary. If the function is successful, it returns GNUNET_YES, otherwise GNUNET_NO. + * + * If the specific handle is currently the host of the room for this service, a new handle which is a member will + * take its place. Otherwise the room will be destroyed for this service. + * + * @param service Service + * @param handle Handle + * @param key Key of room + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +close_service_room (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, + const struct GNUNET_HashCode *key); + +/** + * Loads the local configuration for a given room of a service which contains the last messages hash + * and the ruleset for general access of new members. + * + * @param service Service + * @param room Room + */ +void +load_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Saves the configuration for a given room of a service which contains the last messages hash + * and the ruleset for general access of new members locally. + * + * @param service Service + * @param room Room + */ +void +save_service_room_and_messages (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room); + +/** + * Sends a received or sent message with a given hash to each handle of a service which + * is currently member of a specific room for handling it in the client API. + * + * @param service Service + * @param room Room + * @param message Message + * @param hash Hash of message + */ +void +handle_service_message (struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, + const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +#endif //GNUNET_SERVICE_MESSENGER_SERVICE_H diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c new file mode 100644 index 000000000..df9e5c4c7 --- /dev/null +++ b/src/messenger/gnunet-service-messenger_tunnel.c @@ -0,0 +1,300 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_tunnel.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_tunnel.h" + +#include "gnunet-service-messenger_handle.h" +#include "gnunet-service-messenger_util.h" + +struct GNUNET_MESSENGER_SrvTunnel* +create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door) +{ + GNUNET_assert((room) && (door)); + + struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_new(struct GNUNET_MESSENGER_SrvTunnel); + + tunnel->room = room; + tunnel->channel = NULL; + + tunnel->peer = GNUNET_PEER_intern (door); + tunnel->contact_id = NULL; + + tunnel->peer_message = NULL; + tunnel->last_message = NULL; + + return tunnel; +} + +void +destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + GNUNET_assert(tunnel); + + if (tunnel->channel) + GNUNET_CADET_channel_destroy (tunnel->channel); + + GNUNET_PEER_change_rc (tunnel->peer, -1); + + if (tunnel->contact_id) + GNUNET_free(tunnel->contact_id); + + if (tunnel->peer_message) + GNUNET_free(tunnel->peer_message); + + if (tunnel->last_message) + GNUNET_free(tunnel->last_message); + + GNUNET_free(tunnel); +} + +int +bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel) +{ + GNUNET_assert(tunnel); + + if (tunnel->channel) + { + if (tunnel->contact_id) + return GNUNET_NO; + + delayed_disconnect_channel (tunnel->channel); + } + + tunnel->channel = channel; + + return GNUNET_YES; +} + +extern void +callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room, void *cls); + +void +callback_tunnel_disconnect (void *cls, const struct GNUNET_CADET_Channel *channel) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; + + if (tunnel) + { + tunnel->channel = NULL; + + callback_room_disconnect (tunnel->room, cls); + } +} + +extern int +callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, + struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash); + +int +check_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; + + if (!tunnel) + return GNUNET_NO; + + const uint16_t length = ntohs (header->size) - sizeof(*header); + const char *buffer = (const char*) &header[1]; + + struct GNUNET_MESSENGER_Message message; + + if (length < sizeof(message.header)) + return GNUNET_NO; + + if (GNUNET_YES != decode_message (&message, length, buffer)) + return GNUNET_NO; + + struct GNUNET_HashCode hash; + hash_message (length, buffer, &hash); + + int result = callback_verify_room_message (tunnel->room, cls, &message, &hash); + + if (GNUNET_MESSENGER_KIND_PEER == message.header.kind) + { + struct GNUNET_PeerIdentity identity; + + GNUNET_PEER_resolve (tunnel->peer, &identity); + + if (0 == GNUNET_memcmp(&(message.body.peer.peer), &(identity))) + { + if (tunnel->contact_id) + { + if (0 != GNUNET_memcmp(tunnel->contact_id, &(message.header.sender_id))) + result = GNUNET_SYSERR; + } + else + { + tunnel->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_memcpy(tunnel->contact_id, &(message.header.sender_id), sizeof(struct GNUNET_ShortHashCode)); + } + } + } + + return (result == GNUNET_YES ? GNUNET_OK : GNUNET_NO); +} + +extern void +callback_room_recv (struct GNUNET_MESSENGER_SrvRoom *room, void *cls, struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +void +handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; + + const uint16_t length = ntohs (header->size) - sizeof(*header); + const char *buffer = (const char*) &header[1]; + + struct GNUNET_MESSENGER_Message message; + struct GNUNET_HashCode hash; + + decode_message (&message, length, buffer); + hash_message (length, buffer, &hash); + + if (tunnel) + { + if (!tunnel->last_message) + tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); + + GNUNET_memcpy(tunnel->last_message, &hash, sizeof(struct GNUNET_HashCode)); + + callback_room_recv (tunnel->room, cls, copy_message (&message), &hash); + } + + GNUNET_CADET_receive_done (tunnel->channel); +} + +int +connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + GNUNET_assert(tunnel); + + if (tunnel->channel) + return GNUNET_NO; + + const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); + + struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); + struct GNUNET_HashCode *key = get_room_key (tunnel->room); + + struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, + struct GNUNET_MessageHeader, NULL), + GNUNET_MQ_handler_end() }; + + tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, key, NULL, callback_tunnel_disconnect, handlers); + + return GNUNET_YES; +} + +void +disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + if (tunnel->channel) + { + delayed_disconnect_channel (tunnel->channel); + + tunnel->channel = NULL; + } +} + +int +is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + return (tunnel->channel ? GNUNET_YES : GNUNET_NO); +} + +struct GNUNET_MESSENGER_MessageSent +{ + struct GNUNET_MESSENGER_SrvTunnel *tunnel; + struct GNUNET_HashCode hash; +}; + +extern void +callback_room_sent (struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, void *cls, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +static void +callback_tunnel_sent (void *cls) +{ + struct GNUNET_MESSENGER_MessageSent *sent = cls; + + if (sent->tunnel) + { + if (!sent->tunnel->last_message) + sent->tunnel->last_message = GNUNET_new(struct GNUNET_HashCode); + + GNUNET_memcpy(sent->tunnel->last_message, &(sent->hash), sizeof(struct GNUNET_HashCode)); + } + + GNUNET_free(sent); +} + +void +send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); + + struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); + + GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode)); + + sent->tunnel = tunnel; + + GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); + GNUNET_MQ_send (mq, env); + + callback_room_sent (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, tunnel, message, hash); +} + +void +send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, + struct GNUNET_HashCode *hash) +{ + struct GNUNET_MQ_Envelope *env = pack_room_message (tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, + message, hash, + GNUNET_MESSENGER_PACK_MODE_ENVELOPE); + + if (env) + send_tunnel_envelope (tunnel, handle, env, copy_message (message), hash); +} + +void +forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Message *clone = copy_message (message); + struct GNUNET_MQ_Envelope *env = pack_message (clone, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); + + if (env) + send_tunnel_envelope (tunnel, NULL, env, clone, hash); +} + +const struct GNUNET_HashCode* +get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) +{ + return tunnel->peer_message; +} diff --git a/src/messenger/gnunet-service-messenger_tunnel.h b/src/messenger/gnunet-service-messenger_tunnel.h new file mode 100644 index 000000000..e6efb226d --- /dev/null +++ b/src/messenger/gnunet-service-messenger_tunnel.h @@ -0,0 +1,155 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_tunnel.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_TUNNEL_H +#define GNUNET_SERVICE_MESSENGER_TUNNEL_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_peer_lib.h" +#include "gnunet_crypto_lib.h" + +#include "gnunet-service-messenger_room.h" + +struct GNUNET_MESSENGER_SrvTunnel +{ + struct GNUNET_MESSENGER_SrvRoom *room; + struct GNUNET_CADET_Channel *channel; + + GNUNET_PEER_Id peer; + struct GNUNET_ShortHashCode *contact_id; + + struct GNUNET_HashCode *peer_message; + struct GNUNET_HashCode *last_message; +}; + +/** + * Creates and allocates a tunnel of a room to a specific peer identity. + * + * @param room Room + * @param door Peer identity + * @return New tunnel + */ +struct GNUNET_MESSENGER_SrvTunnel* +create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_PeerIdentity *door); + +/** + * Destroys a tunnel and frees its memory fully. + * + * @param tunnel + */ +void +destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +/** + * Binds a CADET channel to a tunnel on returns GNUNET_YES only if + * the bounds channel was replaced successfully, otherwise GNUNET_NO gets returned. + * + * @param tunnel Tunnel + * @param channel CADET channel + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, struct GNUNET_CADET_Channel *channel); + +/** + * Tries to connect a tunnel by creating a new CADET channel and binding it. + * The function returns GNUNET_YES on success, otherwise GNUNET_NO. + * + * @param tunnel Tunnel + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +/** + * Disconnects and unbinds a channel from a tunnel. The actual disconnection + * will be asynchronous. + * + * @param tunnel Tunnel + */ +void +disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +/** + * Returns the status of a currently bound channel of a tunnel. + * + * @param tunnel Tunnel + * @return GNUNET_YES or GNUNET_NO + */ +int +is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +/** + * Sends an envelope containing a message with a given hash through + * a tunnel by a given handle. + * + * @param tunnel Tunnel + * @param handle Handle + * @param env Envelope + * @param message Message + * @param hash Hash of message + */ +void +send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MQ_Envelope *env, + struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash); + +/** + * Sends a message by packing it automatically into an envelope and passing it + * through the tunnel. The used handle will sign the message and + * the hash will be calculated and stored. + * + * @param tunnel Tunnel + * @param handle Handle + * @param[out] message Message + * @param[out] hash Hash of message + */ +void +send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, void *handle, struct GNUNET_MESSENGER_Message *message, + struct GNUNET_HashCode *hash); + +/** + * Forwards a given message with a known hash through a tunnel. + * + * @param tunnel Tunnel + * @param message Message + * @param hash Hash of message + */ +void +forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +/** + * Returns the hash of the latest peer message published through a given tunnel + * and matching the tunnels peer identity. If no peer message has been linked to the tunnel + * yet, NULL gets returned. + * + * @param tunnel Tunnel + * @return Hash of peer message or NULL + */ +const struct GNUNET_HashCode* +get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel); + +#endif //GNUNET_SERVICE_MESSENGER_TUNNEL_H diff --git a/src/messenger/gnunet-service-messenger_util.c b/src/messenger/gnunet-service-messenger_util.c new file mode 100644 index 000000000..94fc9469d --- /dev/null +++ b/src/messenger/gnunet-service-messenger_util.c @@ -0,0 +1,64 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_util.c + * @brief GNUnet MESSENGER service + */ + +#include "gnunet-service-messenger_util.h" + +static void +callback_close_channel (void *cls) +{ + struct GNUNET_CADET_Channel *channel = cls; + + if (channel) + GNUNET_CADET_channel_destroy (channel); +} + +void +delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel) +{ + GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_zero_ (), GNUNET_SCHEDULER_PRIORITY_URGENT, + callback_close_channel, channel); +} + +int +generate_free_member_id (struct GNUNET_ShortHashCode *id, const struct GNUNET_CONTAINER_MultiShortmap *members) +{ + size_t counter = 1 + (members ? GNUNET_CONTAINER_multishortmap_size (members) : 0); + + do + { + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, id, sizeof(struct GNUNET_ShortHashCode)); + + if ((members) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (members, id))) + counter--; + else + break; + } + while (counter > 0); + + if (counter) + return GNUNET_YES; + + return GNUNET_NO; +} diff --git a/src/messenger/gnunet-service-messenger_util.h b/src/messenger/gnunet-service-messenger_util.h new file mode 100644 index 000000000..20f8f0afe --- /dev/null +++ b/src/messenger/gnunet-service-messenger_util.h @@ -0,0 +1,53 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/gnunet-service-messenger_util.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_SERVICE_MESSENGER_UTIL_H +#define GNUNET_SERVICE_MESSENGER_UTIL_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" + +/** + * Starts an urgent task to close a CADET channel asynchronously. + * + * @param channel Channel + */ +void +delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel); + +/** + * Tries to generate an unused member id and store it into the id parameter. A map containing all currently + * used member ids is used to check against. + * + * @param[out] id New member id + * @param members Map of member ids + * @return GNUNET_YES on success, GNUNET_NO on failure + */ +int +generate_free_member_id (struct GNUNET_ShortHashCode *id, const struct GNUNET_CONTAINER_MultiShortmap *members); + +#endif //GNUNET_SERVICE_MESSENGER_UTIL_H diff --git a/src/messenger/messenger.conf.in b/src/messenger/messenger.conf.in new file mode 100644 index 000000000..59e11b166 --- /dev/null +++ b/src/messenger/messenger.conf.in @@ -0,0 +1,13 @@ +[messenger] +START_ON_DEMAND = YES +PORT = 2097 +HOSTNAME = localhost +BINARY = gnunet-service-messenger +ACCEPT_FROM = 127.0.0.1; +ACCEPT_FROM6 = ::1; +UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-messenger.sock +UNIX_MATCH_UID = NO +UNIX_MATCH_GID = YES + +# Directory to store messages and contacts +MESSENGER_DIR = $GNUNET_DATA_HOME/messenger/ \ No newline at end of file diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c new file mode 100644 index 000000000..6401b18d7 --- /dev/null +++ b/src/messenger/messenger_api.c @@ -0,0 +1,568 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api.c + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#include "gnunet_messenger_service.h" + +#include "gnunet-service-messenger.h" + +#include "messenger_api_handle.h" +#include "messenger_api_message.h" + +const char* +GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind) +{ + switch (kind) + { + case GNUNET_MESSENGER_KIND_INFO: + return "INFO"; + case GNUNET_MESSENGER_KIND_JOIN: + return "JOIN"; + case GNUNET_MESSENGER_KIND_LEAVE: + return "LEAVE"; + case GNUNET_MESSENGER_KIND_NAME: + return "NAME"; + case GNUNET_MESSENGER_KIND_KEY: + return "KEY"; + case GNUNET_MESSENGER_KIND_PEER: + return "PEER"; + case GNUNET_MESSENGER_KIND_ID: + return "ID"; + case GNUNET_MESSENGER_KIND_MISS: + return "MISS"; + case GNUNET_MESSENGER_KIND_MERGE: + return "MERGE"; + case GNUNET_MESSENGER_KIND_REQUEST: + return "REQUEST"; + case GNUNET_MESSENGER_KIND_INVITE: + return "INVITE"; + case GNUNET_MESSENGER_KIND_TEXT: + return "TEXT"; + case GNUNET_MESSENGER_KIND_FILE: + return "FILE"; + default: + return "UNKNOWN"; + } +} + +static int +check_get_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) +{ + GNUNET_MQ_check_zero_termination(msg); + return GNUNET_OK; +} + +static void +handle_get_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const char *name = ((const char*) msg) + sizeof(*msg); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name); + + set_handle_name (handle, strlen(name) > 0? name : NULL); +} + +static void +handle_get_key (void *cls, const struct GNUNET_MESSENGER_KeyMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_IDENTITY_PublicKey *pubkey = &(msg->pubkey); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", GNUNET_IDENTITY_public_key_to_string (pubkey)); + + set_handle_key (handle, pubkey); + + if (handle->identity_callback) + handle->identity_callback (handle->identity_cls, handle); +} + +static void +handle_member_id (void *cls, const struct GNUNET_MESSENGER_MemberMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_HashCode *key = &(msg->key); + const struct GNUNET_ShortHashCode *id = &(msg->id); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set id of handle in room: %s\n", GNUNET_h2s (key)); + + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + { + if (!room->contact_id) + room->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); + + GNUNET_memcpy(room->contact_id, id, sizeof(*id)); + } +} + +static void +handle_room_open (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_HashCode *key = &(msg->key); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key)); + + open_handle_room (handle, key); +} + +static void +handle_room_entry (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_PeerIdentity *door = &(msg->door); + const struct GNUNET_HashCode *key = &(msg->key); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key)); + + entry_handle_room_at (handle, door, key); +} + +static void +handle_room_close (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_HashCode *key = &(msg->key); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); + + close_handle_room (handle, key); +} + +static int +check_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg) +{ + const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header); + + if (full_length < sizeof(msg->hash)) + return GNUNET_NO; + + const uint16_t length = full_length - sizeof(msg->hash); + const char *buffer = ((const char*) msg) + sizeof(*msg); + + struct GNUNET_MESSENGER_Message message; + + if (length < sizeof(message.header)) + return GNUNET_NO; + + if (GNUNET_YES != decode_message (&message, length, buffer)) + return GNUNET_NO; + + return GNUNET_OK; +} + +static void +handle_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + const struct GNUNET_HashCode *key = &(msg->key); + const struct GNUNET_HashCode *hash = &(msg->hash); + + const char *buffer = ((const char*) msg) + sizeof(*msg); + + const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); + + struct GNUNET_MESSENGER_Message message; + decode_message (&message, length, buffer); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind)); + + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + { + handle_room_message (room, &message, hash); + + if (handle->msg_callback) + handle->msg_callback (handle->msg_cls, room, &message, hash); + } + else + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MESSENGER ERROR: Room not found\n"); +} + +static void +reconnect (struct GNUNET_MESSENGER_Handle *handle); + +static void +send_open_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room) +{ + struct GNUNET_MESSENGER_RoomMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + GNUNET_MQ_send (handle->mq, env); +} + +static void +send_entry_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room, + const struct GNUNET_PeerIdentity *door) +{ + struct GNUNET_MESSENGER_RoomMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); + GNUNET_memcpy(&(msg->door), door, sizeof(*door)); + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + GNUNET_MQ_send (handle->mq, env); +} + +static void +send_close_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room) +{ + struct GNUNET_MESSENGER_RoomMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + GNUNET_MQ_send (handle->mq, env); +} + +static int +iterate_reset_room (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + struct GNUNET_MESSENGER_Room *room = value; + + if (GNUNET_YES == room->opened) + send_open_room (handle, room); + + struct GNUNET_MESSENGER_ListTunnel *entry = room->entries.head; + + struct GNUNET_PeerIdentity door; + + while (entry) + { + GNUNET_PEER_resolve (entry->peer, &door); + + send_entry_room (handle, room, &door); + + entry = entry->next; + } + + return GNUNET_YES; +} + +static void +callback_reconnect (void *cls) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + handle->reconnect_task = NULL; + handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time) + ; + + reconnect (handle); + + GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_reset_room, handle); +} + +static int +iterate_close_room (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + struct GNUNET_MESSENGER_Room *room = value; + + send_close_room (handle, room); + + return GNUNET_YES; +} + +static void +callback_mq_error (void *cls, enum GNUNET_MQ_Error error) +{ + struct GNUNET_MESSENGER_Handle *handle = cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error); + + GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, handle); + + if (handle->mq) + { + GNUNET_MQ_destroy (handle->mq); + handle->mq = NULL; + } + + handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_time, &callback_reconnect, handle); +} + +static void +reconnect (struct GNUNET_MESSENGER_Handle *handle) +{ + const struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size( + get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME, struct GNUNET_MESSENGER_NameMessage, handle), + GNUNET_MQ_hd_fixed_size( + get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY, + struct GNUNET_MESSENGER_KeyMessage, handle), + GNUNET_MQ_hd_fixed_size( + member_id, + GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID, + struct GNUNET_MESSENGER_MemberMessage, handle), + GNUNET_MQ_hd_fixed_size(room_open, + GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, + struct GNUNET_MESSENGER_RoomMessage, + handle), + GNUNET_MQ_hd_fixed_size(room_entry, + GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, + struct GNUNET_MESSENGER_RoomMessage, + handle), + GNUNET_MQ_hd_fixed_size(room_close, + GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, + struct GNUNET_MESSENGER_RoomMessage, + handle), + GNUNET_MQ_hd_var_size( + recv_message, + GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE, + struct GNUNET_MESSENGER_RecvMessage, handle), + GNUNET_MQ_handler_end() }; + + handle->mq = GNUNET_CLIENT_connect (handle->cfg, + GNUNET_MESSENGER_SERVICE_NAME, + handlers, &callback_mq_error, handle); +} + +struct GNUNET_MESSENGER_Handle* +GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, + GNUNET_MESSENGER_IdentityCallback identity_callback, void *identity_cls, + GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls) +{ + struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, identity_callback, identity_cls, msg_callback, msg_cls); + + reconnect (handle); + + if (handle->mq) + { + const uint16_t name_len = name ? strlen (name) : 0; + + struct GNUNET_MESSENGER_CreateMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE); + + char *extra = ((char*) msg) + sizeof(*msg); + + if (name_len) + GNUNET_memcpy(extra, name, name_len); + + extra[name_len] = '\0'; + + GNUNET_MQ_send (handle->mq, env); + return handle; + } + else + { + destroy_handle (handle); + return NULL; + } +} + +int +GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle) +{ + if ((!handle) || (!get_handle_name(handle))) + return GNUNET_SYSERR; + + struct GNUNET_MESSENGER_UpdateMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE); + GNUNET_MQ_send (handle->mq, env); + return GNUNET_OK; +} + +void +GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) +{ + if (!handle) + return; + + struct GNUNET_MESSENGER_DestroyMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY); + GNUNET_MQ_send (handle->mq, env); + + destroy_handle (handle); +} + +const char* +GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) +{ + if (!handle) + return NULL; + + return get_handle_name (handle); +} + +int +GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, const char *name) +{ + if (!handle) + return GNUNET_SYSERR; + + const uint16_t name_len = name ? strlen (name) : 0; + + struct GNUNET_MESSENGER_NameMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME); + + char *extra = ((char*) msg) + sizeof(*msg); + + if (name_len) + GNUNET_memcpy(extra, name, name_len); + + extra[name_len] = '\0'; + + GNUNET_MQ_send (handle->mq, env); + return GNUNET_YES; +} + +const struct GNUNET_IDENTITY_PublicKey* +GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle) +{ + if (!handle) + return NULL; + + return get_handle_key (handle); +} + +struct GNUNET_MESSENGER_Room* +GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (!room) + { + room = create_room (handle, key); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + destroy_room (room); + return NULL; + } + } + + send_open_room (handle, room); + return room; +} + +struct GNUNET_MESSENGER_Room* +GNUNET_MESSENGER_entry_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (!room) + { + room = create_room (handle, key); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + destroy_room (room); + return NULL; + } + } + + send_entry_room (handle, room, door); + return room; +} + +void +GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room) +{ + send_close_room (room->handle, room); +} + +struct GNUNET_MESSENGER_Contact* +GNUNET_MESSENGER_get_member (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_ShortHashCode *id) +{ + return GNUNET_CONTAINER_multishortmap_get (room->members, id); +} + +const char* +GNUNET_MESSENGER_contact_get_name (const struct GNUNET_MESSENGER_Contact *contact) +{ + if (!contact) + return NULL; + + return get_contact_name (contact); +} + +const struct GNUNET_IDENTITY_PublicKey* +GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact) +{ + if (!contact) + return NULL; + + return get_contact_key (contact); +} + +void +GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message) +{ + const uint16_t length = get_message_size (message); + + struct GNUNET_MESSENGER_SendMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE); + + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + + char *buffer = ((char*) msg) + sizeof(*msg); + encode_message (message, length, buffer); + + GNUNET_MQ_send (room->handle->mq, env); +} + +const struct GNUNET_MESSENGER_Message* +GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash) +{ + const struct GNUNET_MESSENGER_Message *message = get_room_message (room, hash); + + if (!message) + { + struct GNUNET_MESSENGER_RecvMessage *msg; + struct GNUNET_MQ_Envelope *env; + + env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE); + GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); + GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash)); + GNUNET_MQ_send (room->handle->mq, env); + } + + return message; +} diff --git a/src/messenger/messenger_api_contact.c b/src/messenger/messenger_api_contact.c new file mode 100644 index 000000000..9a242aa00 --- /dev/null +++ b/src/messenger/messenger_api_contact.c @@ -0,0 +1,78 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_contact.c + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_contact.h" + +struct GNUNET_MESSENGER_Contact* +create_contact (const struct GNUNET_IDENTITY_PublicKey *key) +{ + struct GNUNET_MESSENGER_Contact *contact = GNUNET_new(struct GNUNET_MESSENGER_Contact); + + contact->name = NULL; + + GNUNET_memcpy(&(contact->public_key), key, sizeof(contact->public_key)); + + return contact; +} + +void +destroy_contact (struct GNUNET_MESSENGER_Contact *contact) +{ + if (contact->name) + GNUNET_free(contact->name); + + GNUNET_free(contact); +} + +const char* +get_contact_name (const struct GNUNET_MESSENGER_Contact *contact) +{ + return contact->name; +} + +void +set_contact_name (struct GNUNET_MESSENGER_Contact *contact, const char *name) +{ + if (contact->name) + GNUNET_free(contact->name); + + contact->name = name? GNUNET_strdup(name) : NULL; +} + +const struct GNUNET_IDENTITY_PublicKey* +get_contact_key (const struct GNUNET_MESSENGER_Contact *contact) +{ + return &(contact->public_key); +} + +const struct GNUNET_HashCode* +get_contact_id_from_key (const struct GNUNET_MESSENGER_Contact *contact) +{ + static struct GNUNET_HashCode id; + + GNUNET_CRYPTO_hash (&(contact->public_key), sizeof(contact->public_key), &id); + + return &id; +} diff --git a/src/messenger/messenger_api_contact.h b/src/messenger/messenger_api_contact.h new file mode 100644 index 000000000..0673b9b85 --- /dev/null +++ b/src/messenger/messenger_api_contact.h @@ -0,0 +1,93 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_contact.h + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_CONTACT_H +#define GNUNET_MESSENGER_API_CONTACT_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" + +struct GNUNET_MESSENGER_Contact +{ + char *name; + + struct GNUNET_IDENTITY_PublicKey public_key; +}; + +/** + * Creates and allocates a new contact with a given public key from an EGO. + * + * @param key Public key + * @return New contact + */ +struct GNUNET_MESSENGER_Contact* +create_contact (const struct GNUNET_IDENTITY_PublicKey *key); + +/** + * Destroys a contact and frees its memory fully. + * + * @param contact Contact + */ +void +destroy_contact (struct GNUNET_MESSENGER_Contact *contact); + +/** + * Returns the current name of a given contact or NULL if no valid name was assigned yet. + * + * @param contact Contact + * @return Name of the contact or NULL + */ +const char* +get_contact_name (const struct GNUNET_MESSENGER_Contact *contact); + +/** + * Changes the current name of a given contact by copying it from the parameter name. + * + * @param contact Contact + * @param name Valid name (may not be NULL!) + */ +void +set_contact_name (struct GNUNET_MESSENGER_Contact *contact, const char *name); + +/** + * Returns the public key of a given contact. + * + * @param contact Contact + * @return Public key of the contact + */ +const struct GNUNET_IDENTITY_PublicKey* +get_contact_key (const struct GNUNET_MESSENGER_Contact *contact); + +/** + * Returns the resulting hashcode of the public key from a given contact. + * + * @param contact Contact + * @return Hash of the contacts public key + */ +const struct GNUNET_HashCode* +get_contact_id_from_key (const struct GNUNET_MESSENGER_Contact *contact); + +#endif //GNUNET_MESSENGER_API_CONTACT_H diff --git a/src/messenger/messenger_api_ego.h b/src/messenger/messenger_api_ego.h new file mode 100644 index 000000000..c60eeac50 --- /dev/null +++ b/src/messenger/messenger_api_ego.h @@ -0,0 +1,38 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_ego.h + * @brief GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_EGO_H +#define GNUNET_MESSENGER_API_EGO_H + +#include "platform.h" +#include "gnunet_identity_service.h" + +struct GNUNET_MESSENGER_Ego +{ + struct GNUNET_IDENTITY_PrivateKey priv; + struct GNUNET_IDENTITY_PublicKey pub; +}; + +#endif //GNUNET_MESSENGER_API_EGO_H diff --git a/src/messenger/messenger_api_handle.c b/src/messenger/messenger_api_handle.c new file mode 100644 index 000000000..20ef77254 --- /dev/null +++ b/src/messenger/messenger_api_handle.c @@ -0,0 +1,213 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_handle.c + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_handle.h" + +struct GNUNET_MESSENGER_Handle* +create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_MESSENGER_IdentityCallback identity_callback, + void *identity_cls, GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls) +{ + struct GNUNET_MESSENGER_Handle *handle = GNUNET_new(struct GNUNET_MESSENGER_Handle); + + handle->cfg = cfg; + handle->mq = NULL; + + handle->identity_callback = identity_callback; + handle->identity_cls = identity_cls; + + handle->msg_callback = msg_callback; + handle->msg_cls = msg_cls; + + handle->name = NULL; + handle->pubkey = NULL; + + handle->reconnect_time = GNUNET_TIME_relative_get_zero_ (); + handle->reconnect_task = NULL; + + handle->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + handle->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + return handle; +} + +static int +iterate_destroy_room (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Room *room = value; + + destroy_room (room); + + return GNUNET_YES; +} + +static int +iterate_destroy_contact (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Contact *contact = value; + + destroy_contact (contact); + + return GNUNET_YES; +} + +void +destroy_handle (struct GNUNET_MESSENGER_Handle *handle) +{ + if (handle->reconnect_task) + GNUNET_SCHEDULER_cancel (handle->reconnect_task); + + if (handle->mq) + GNUNET_MQ_destroy (handle->mq); + + if (handle->name) + GNUNET_free(handle->name); + + if (handle->pubkey) + GNUNET_free(handle->pubkey); + + if (handle->rooms) + { + GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_destroy_room, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (handle->rooms); + } + + if (handle->contacts) + { + GNUNET_CONTAINER_multihashmap_iterate (handle->contacts, iterate_destroy_contact, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (handle->contacts); + } + + GNUNET_free(handle->name); +} + +void +set_handle_name (struct GNUNET_MESSENGER_Handle *handle, const char *name) +{ + if (handle->name) + GNUNET_free(handle->name); + + handle->name = name? GNUNET_strdup(name) : NULL; +} + +const char* +get_handle_name (const struct GNUNET_MESSENGER_Handle *handle) +{ + return handle->name; +} + +void +set_handle_key (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + if (!handle->pubkey) + handle->pubkey = GNUNET_new(struct GNUNET_IDENTITY_PublicKey); + + GNUNET_memcpy(handle->pubkey, pubkey, sizeof(*pubkey)); +} + +const struct GNUNET_IDENTITY_PublicKey* +get_handle_key (const struct GNUNET_MESSENGER_Handle *handle) +{ + if (!handle->pubkey) + { + struct GNUNET_IDENTITY_Ego *anonymous = GNUNET_IDENTITY_ego_get_anonymous (); + static struct GNUNET_IDENTITY_PublicKey pubkey; + + GNUNET_IDENTITY_ego_get_public_key (anonymous, &pubkey); + + return &pubkey; + } + + return handle->pubkey; +} + +struct GNUNET_MESSENGER_Contact* +get_handle_contact_by_pubkey (const struct GNUNET_MESSENGER_Handle *handle, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); + + struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multihashmap_get (handle->contacts, &hash); + + if (contact) + return contact; + + contact = create_contact (pubkey); + + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (handle->contacts, &hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + return contact; + + destroy_contact (contact); + return NULL; +} + +void +swap_handle_contact_by_pubkey (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Contact *contact, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + const struct GNUNET_HashCode *hash = get_contact_id_from_key (contact); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (handle->contacts, hash, contact)) + { + GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey)); + + hash = get_contact_id_from_key (contact); + + GNUNET_CONTAINER_multihashmap_put (handle->contacts, hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } +} + +void +open_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + room->opened = GNUNET_YES; +} + +void +entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + add_to_list_tunnels (&(room->entries), door); +} + +void +close_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if ((room) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (handle->rooms, key, room))) + destroy_room (room); +} diff --git a/src/messenger/messenger_api_handle.h b/src/messenger/messenger_api_handle.h new file mode 100644 index 000000000..d6cde0106 --- /dev/null +++ b/src/messenger/messenger_api_handle.h @@ -0,0 +1,174 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_handle.h + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_HANDLE_H +#define GNUNET_MESSENGER_API_HANDLE_H + +#include "platform.h" +#include "gnunet_cadet_service.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_peer_lib.h" + +#include "gnunet_messenger_service.h" + +#include "messenger_api_contact.h" +#include "messenger_api_room.h" + +struct GNUNET_MESSENGER_Handle +{ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + struct GNUNET_MQ_Handle *mq; + + GNUNET_MESSENGER_IdentityCallback identity_callback; + void *identity_cls; + + GNUNET_MESSENGER_MessageCallback msg_callback; + void *msg_cls; + + char *name; + struct GNUNET_IDENTITY_PublicKey *pubkey; + + struct GNUNET_TIME_Relative reconnect_time; + struct GNUNET_SCHEDULER_Task *reconnect_task; + + struct GNUNET_CONTAINER_MultiHashMap *rooms; + struct GNUNET_CONTAINER_MultiHashMap *contacts; +}; + +/** + * Creates and allocates a new handle using a given configuration and a custom message callback + * with a given closure for the client API. + * + * @param cfg Configuration + * @param msg_callback Message callback + * @param msg_cls Closure + * @return New handle + */ +struct GNUNET_MESSENGER_Handle* +create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_MESSENGER_IdentityCallback identity_callback, + void *identity_cls, GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls); + +/** + * Destroys a handle and frees its memory fully from the client API. + * + * @param handle Handle + */ +void +destroy_handle (struct GNUNET_MESSENGER_Handle *handle); + +/** + * Sets the name of a handle to a specific name. + * + * @param handle Handle + * @param name New name + */ +void +set_handle_name (struct GNUNET_MESSENGER_Handle *handle, const char *name); + +/** + * Returns the current name of a given handle or NULL if no valid name was assigned yet. + * + * @param handle Handle + * @return Name of the handle or NULL + */ +const char* +get_handle_name (const struct GNUNET_MESSENGER_Handle *handle); + +/** + * Sets the public key of a given handle to a specific public key. + * + * @param handle Handle + * @param pubkey Public key + */ +void +set_handle_key (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Returns the public key of a given handle. + * + * @param handle Handle + * @return Public key of the handle + */ +const struct GNUNET_IDENTITY_PublicKey* +get_handle_key (const struct GNUNET_MESSENGER_Handle *handle); + +/** + * Returns a contact known to a handle identified by a given public key. If not matching + * contact is found, NULL gets returned. + * + * @param handle Handle + * @param pubkey Public key of EGO + * @return Contact or NULL + */ +struct GNUNET_MESSENGER_Contact* +get_handle_contact_by_pubkey (const struct GNUNET_MESSENGER_Handle *handle, + const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Changes the public key for a contact known to a handle to a specific public key and + * updates local map entries to access the contact by its updated key. + * + * @param handle Handle + * @param contact Contact + * @param pubkey Public key of EGO + */ +void +swap_handle_contact_by_pubkey (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Contact *contact, + const struct GNUNET_IDENTITY_PublicKey *pubkey); + +/** + * Marks a room known to a handle identified by a given key as open. + * + * @param handle Handle + * @param key Key of room + */ +void +open_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key); + +/** + * Adds a tunnel for a room known to a handle identified by a given key to a + * list of opened connections. + * + * @param handle Handle + * @param door Peer identity + * @param key Key of room + */ +void +entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key); + +/** + * Destroys and so implicitly closes a room known to a handle identified by a given key. + * + * @param handle Handle + * @param key Key of room + */ +void +close_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key); + +#endif //GNUNET_MESSENGER_API_HANDLE_H diff --git a/src/messenger/messenger_api_list_tunnels.c b/src/messenger/messenger_api_list_tunnels.c new file mode 100644 index 000000000..13d8c1906 --- /dev/null +++ b/src/messenger/messenger_api_list_tunnels.c @@ -0,0 +1,112 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_list_tunnels.c + * @brief messenger api: client and service implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_list_tunnels.h" + +void +init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels) +{ + GNUNET_assert(tunnels); + + tunnels->head = NULL; + tunnels->tail = NULL; +} + +void +clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels) +{ + GNUNET_assert(tunnels); + + struct GNUNET_MESSENGER_ListTunnel *element; + + for (element = tunnels->head; element; element = tunnels->head) + { + GNUNET_CONTAINER_DLL_remove(tunnels->head, tunnels->tail, element); + GNUNET_PEER_change_rc (element->peer, -1); + GNUNET_free(element); + } + + tunnels->head = NULL; + tunnels->tail = NULL; +} + +static int +compare_list_tunnels (void *cls, struct GNUNET_MESSENGER_ListTunnel *element0, + struct GNUNET_MESSENGER_ListTunnel *element1) +{ + return ((int) element0->peer) - ((int) element1->peer); +} + +void +add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer) +{ + struct GNUNET_MESSENGER_ListTunnel *element = GNUNET_new(struct GNUNET_MESSENGER_ListTunnel); + + element->peer = GNUNET_PEER_intern (peer); + + GNUNET_CONTAINER_DLL_insert_sorted(struct GNUNET_MESSENGER_ListTunnel, compare_list_tunnels, NULL, tunnels->head, + tunnels->tail, element); +} + +struct GNUNET_MESSENGER_ListTunnel* +find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer, size_t *index) +{ + struct GNUNET_MESSENGER_ListTunnel *element; + struct GNUNET_PeerIdentity pid; + + if (index) + *index = 0; + + for (element = tunnels->head; element; element = element->next) + { + GNUNET_PEER_resolve (element->peer, &pid); + + if (0 == GNUNET_memcmp(&pid, peer)) + return element; + + if (index) + (*index) = (*index) + 1; + } + + return NULL; +} + +int +contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer) +{ + return find_list_tunnels (tunnels, peer, NULL) != NULL ? GNUNET_YES : GNUNET_NO; +} + +struct GNUNET_MESSENGER_ListTunnel* +remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, struct GNUNET_MESSENGER_ListTunnel *element) +{ + struct GNUNET_MESSENGER_ListTunnel *next = element->next; + + GNUNET_CONTAINER_DLL_remove(tunnels->head, tunnels->tail, element); + GNUNET_PEER_change_rc (element->peer, -1); + GNUNET_free(element); + + return next; +} diff --git a/src/messenger/messenger_api_list_tunnels.h b/src/messenger/messenger_api_list_tunnels.h new file mode 100644 index 000000000..0240fceb8 --- /dev/null +++ b/src/messenger/messenger_api_list_tunnels.h @@ -0,0 +1,112 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_list_tunnels.h + * @brief messenger api: client and service implementation of GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_LIST_TUNNELS_H +#define GNUNET_MESSENGER_API_LIST_TUNNELS_H + +#include "platform.h" +#include "gnunet_peer_lib.h" +#include "gnunet_container_lib.h" + +struct GNUNET_MESSENGER_ListTunnel +{ + struct GNUNET_MESSENGER_ListTunnel *prev; + struct GNUNET_MESSENGER_ListTunnel *next; + + GNUNET_PEER_Id peer; +}; + +struct GNUNET_MESSENGER_ListTunnels +{ + struct GNUNET_MESSENGER_ListTunnel *head; + struct GNUNET_MESSENGER_ListTunnel *tail; +}; + +/** + * Initializes list of tunnels peer identities as empty list. + * + * @param tunnels List of peer identities + */ +void +init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels); + +/** + * Clears the list of tunnels peer identities. + * + * @param tunnels List of peer identities + */ +void +clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels); + +/** + * Adds a specific peer from a tunnel to the end of the list. + * + * @param tunnels List of peer identities + * @param peer Peer identity of tunnel + */ +void +add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer); + +/** + * Searches linearly through the list of tunnels peer identities for matching a + * specific peer identity and returns the matching element of the list. + * + * If no matching element is found, NULL gets returned. + * + * If index is not NULL, index will be overriden with the numeric index of + * the found element in the list. If no matching element is found, index will + * contain the total amount of elements in the list. + * + * @param tunnels List of peer identities + * @param peer Peer identity of tunnel + * @param[out] index Index of found element (optional) + * @return Element in the list with matching peer identity + */ +struct GNUNET_MESSENGER_ListTunnel* +find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer, size_t *index); + +/** + * Tests linearly if the list of tunnels peer identities contains a specific + * peer identity and returns GNUNET_YES on success, otherwise GNUNET_NO. + * + * @param tunnels List of peer identities + * @param peer Peer identity of tunnel + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, const struct GNUNET_PeerIdentity *peer); + +/** + * Removes a specific element from the list of tunnels peer identities and returns + * the next element in the list. + * + * @param tunnels List of peer identities + * @param element Element of the list + * @return Next element in the list + */ +struct GNUNET_MESSENGER_ListTunnel* +remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, struct GNUNET_MESSENGER_ListTunnel *element); + +#endif //GNUNET_MESSENGER_API_LIST_TUNNELS_H diff --git a/src/messenger/messenger_api_message.c b/src/messenger/messenger_api_message.c new file mode 100644 index 000000000..fdab60eef --- /dev/null +++ b/src/messenger/messenger_api_message.c @@ -0,0 +1,602 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_message.c + * @brief messenger api: client and service implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_message.h" + +struct GNUNET_MESSENGER_MessageSignature +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct GNUNET_HashCode hash; +}; + +struct GNUNET_MESSENGER_ShortMessage +{ + enum GNUNET_MESSENGER_MessageKind kind; + struct GNUNET_MESSENGER_MessageBody body; +}; + +struct GNUNET_MESSENGER_Message* +create_message (enum GNUNET_MESSENGER_MessageKind kind) +{ + struct GNUNET_MESSENGER_Message *message = GNUNET_new(struct GNUNET_MESSENGER_Message); + + message->header.kind = kind; + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_NAME: + message->body.name.name = NULL; + break; + case GNUNET_MESSENGER_KIND_TEXT: + message->body.text.text = NULL; + break; + case GNUNET_MESSENGER_KIND_FILE: + message->body.file.uri = NULL; + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + message->body.private.length = 0; + message->body.private.data = NULL; + break; + default: + break; + } + + return message; +} + +struct GNUNET_MESSENGER_Message* +copy_message (const struct GNUNET_MESSENGER_Message *message) +{ + struct GNUNET_MESSENGER_Message *copy = GNUNET_new(struct GNUNET_MESSENGER_Message); + + GNUNET_memcpy(copy, message, sizeof(struct GNUNET_MESSENGER_Message)); + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_NAME: + copy->body.name.name = GNUNET_strdup(message->body.name.name); + break; + case GNUNET_MESSENGER_KIND_TEXT: + copy->body.text.text = GNUNET_strdup(message->body.text.text); + break; + case GNUNET_MESSENGER_KIND_FILE: + copy->body.file.uri = GNUNET_strdup(message->body.file.uri); + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + copy->body.private.data = copy->body.private.length ? GNUNET_malloc(copy->body.private.length) : NULL; + + if (copy->body.private.data) + { + GNUNET_memcpy(copy->body.private.data, message->body.private.data, copy->body.private.length); + } + + break; + default: + break; + } + + return copy; +} + +static void +destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, struct GNUNET_MESSENGER_MessageBody *body) +{ + switch (kind) + { + case GNUNET_MESSENGER_KIND_NAME: + GNUNET_free(body->name.name); + break; + case GNUNET_MESSENGER_KIND_TEXT: + GNUNET_free(body->text.text); + break; + case GNUNET_MESSENGER_KIND_FILE: + GNUNET_free(body->file.uri); + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + GNUNET_free(body->private.data); + break; + default: + break; + } +} + +void +destroy_message (struct GNUNET_MESSENGER_Message *message) +{ + destroy_message_body (message->header.kind, &(message->body)); + + GNUNET_free(message); +} + +static void +fold_short_message (const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_ShortMessage *shortened) +{ + shortened->kind = message->header.kind; + + GNUNET_memcpy(&(shortened->body), &(message->body), sizeof(struct GNUNET_MESSENGER_MessageBody)); +} + +static void +unfold_short_message (struct GNUNET_MESSENGER_ShortMessage *shortened, struct GNUNET_MESSENGER_Message *message) +{ + destroy_message_body (message->header.kind, &(message->body)); + + message->header.kind = shortened->kind; + + GNUNET_memcpy(&(message->body), &(shortened->body), sizeof(struct GNUNET_MESSENGER_MessageBody)); +} + +#define member_size(type, member) sizeof(((type*) NULL)->member) + +static uint16_t +get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind) +{ + uint16_t length = 0; + + switch (kind) + { + case GNUNET_MESSENGER_KIND_INFO: + length += member_size(struct GNUNET_MESSENGER_Message, body.info.host_key); + length += member_size(struct GNUNET_MESSENGER_Message, body.info.unique_id); + break; + case GNUNET_MESSENGER_KIND_JOIN: + length += member_size(struct GNUNET_MESSENGER_Message, body.join.key); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + break; + case GNUNET_MESSENGER_KIND_NAME: + break; + case GNUNET_MESSENGER_KIND_KEY: + length += member_size(struct GNUNET_MESSENGER_Message, body.key.key); + break; + case GNUNET_MESSENGER_KIND_PEER: + length += member_size(struct GNUNET_MESSENGER_Message, body.peer.peer); + break; + case GNUNET_MESSENGER_KIND_ID: + length += member_size(struct GNUNET_MESSENGER_Message, body.id.id); + break; + case GNUNET_MESSENGER_KIND_MISS: + length += member_size(struct GNUNET_MESSENGER_Message, body.miss.peer); + break; + case GNUNET_MESSENGER_KIND_MERGE: + length += member_size(struct GNUNET_MESSENGER_Message, body.merge.previous); + break; + case GNUNET_MESSENGER_KIND_REQUEST: + length += member_size(struct GNUNET_MESSENGER_Message, body.request.hash); + break; + case GNUNET_MESSENGER_KIND_INVITE: + length += member_size(struct GNUNET_MESSENGER_Message, body.invite.door); + length += member_size(struct GNUNET_MESSENGER_Message, body.invite.key); + break; + case GNUNET_MESSENGER_KIND_TEXT: + break; + case GNUNET_MESSENGER_KIND_FILE: + length += member_size(struct GNUNET_MESSENGER_Message, body.file.key); + length += member_size(struct GNUNET_MESSENGER_Message, body.file.hash); + length += NAME_MAX; + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + length += member_size(struct GNUNET_MESSENGER_Message, body.private.key); + break; + default: + break; + } + + return length; +} + +uint16_t +get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind) +{ + uint16_t length = 0; + + length += member_size(struct GNUNET_MESSENGER_Message, header.signature); + length += member_size(struct GNUNET_MESSENGER_Message, header.timestamp); + length += member_size(struct GNUNET_MESSENGER_Message, header.sender_id); + length += member_size(struct GNUNET_MESSENGER_Message, header.previous); + length += member_size(struct GNUNET_MESSENGER_Message, header.kind); + + return length + get_message_body_kind_size (kind); +} + +static uint16_t +get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body) +{ + uint16_t length = 0; + + switch (kind) + { + case GNUNET_MESSENGER_KIND_NAME: + length += (body->name.name? strlen (body->name.name) : 0); + break; + case GNUNET_MESSENGER_KIND_TEXT: + length += strlen (body->text.text); + break; + case GNUNET_MESSENGER_KIND_FILE: + length += strlen (body->file.uri); + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + length += body->private.length; + break; + default: + break; + } + + return length; +} + +uint16_t +get_message_size (const struct GNUNET_MESSENGER_Message *message) +{ + return get_message_kind_size (message->header.kind) + get_message_body_size (message->header.kind, &(message->body)); +} + +static uint16_t +get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message) +{ + if (message) + return sizeof(message->kind) + get_message_body_kind_size (message->kind) + + get_message_body_size (message->kind, &(message->body)); + else + return sizeof(message->kind); +} + +#define min(x, y) (x < y? x : y) + +#define encode_step_ext(dst, offset, src, size) do { \ + GNUNET_memcpy(dst + offset, src, size); \ + offset += size; \ +} while (0) + +#define encode_step(dst, offset, src) do { \ + encode_step_ext(dst, offset, src, sizeof(*src)); \ +} while(0) + +static void +encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body, + uint16_t length, char *buffer, uint16_t offset) +{ + switch (kind) + { + case GNUNET_MESSENGER_KIND_INFO: + encode_step(buffer, offset, &(body->info.host_key)); + encode_step(buffer, offset, &(body->info.unique_id)); + break; + case GNUNET_MESSENGER_KIND_JOIN: + encode_step(buffer, offset, &(body->join.key)); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + break; + case GNUNET_MESSENGER_KIND_NAME: + if (body->name.name) + encode_step_ext(buffer, offset, body->name.name, min(length - offset, strlen(body->name.name))); + break; + case GNUNET_MESSENGER_KIND_KEY: + encode_step(buffer, offset, &(body->key.key)); + break; + case GNUNET_MESSENGER_KIND_PEER: + encode_step(buffer, offset, &(body->peer.peer)); + break; + case GNUNET_MESSENGER_KIND_ID: + encode_step(buffer, offset, &(body->id.id)); + break; + case GNUNET_MESSENGER_KIND_MISS: + encode_step(buffer, offset, &(body->miss.peer)); + break; + case GNUNET_MESSENGER_KIND_MERGE: + encode_step(buffer, offset, &(body->merge.previous)); + break; + case GNUNET_MESSENGER_KIND_REQUEST: + encode_step(buffer, offset, &(body->request.hash)); + break; + case GNUNET_MESSENGER_KIND_INVITE: + encode_step(buffer, offset, &(body->invite.door)); + encode_step(buffer, offset, &(body->invite.key)); + break; + case GNUNET_MESSENGER_KIND_TEXT: + encode_step_ext(buffer, offset, body->text.text, min(length - offset, strlen(body->text.text))); + break; + case GNUNET_MESSENGER_KIND_FILE: + encode_step(buffer, offset, &(body->file.key)); + encode_step(buffer, offset, &(body->file.hash)); + encode_step_ext(buffer, offset, body->file.name, NAME_MAX); + encode_step_ext(buffer, offset, body->file.uri, min(length - offset, strlen(body->file.uri))); + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + encode_step(buffer, offset, &(body->private.key)); + encode_step_ext(buffer, offset, body->private.data, min(length - offset, body->private.length)); + break; + default: + break; + } +} + +void +encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer) +{ + uint16_t offset = 0; + + encode_step(buffer, offset, &(message->header.signature)); + encode_step(buffer, offset, &(message->header.timestamp)); + encode_step(buffer, offset, &(message->header.sender_id)); + encode_step(buffer, offset, &(message->header.previous)); + encode_step(buffer, offset, &(message->header.kind)); + + encode_message_body (message->header.kind, &(message->body), length, buffer, offset); +} + +static void +encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, char *buffer) +{ + uint16_t offset = 0; + + encode_step(buffer, offset, &(message->kind)); + + encode_message_body (message->kind, &(message->body), length, buffer, offset); +} + +#define decode_step_ext(src, offset, dst, size) do { \ + GNUNET_memcpy(dst, src + offset, size); \ + offset += size; \ +} while (0) + +#define decode_step(src, offset, dst) do { \ + decode_step_ext(src, offset, dst, sizeof(*dst)); \ +} while (0) + +#define decode_step_malloc(src, offset, dst, size, zero) do { \ + dst = GNUNET_malloc(size + zero); \ + if (zero) dst[size] = 0; \ + decode_step_ext(src, offset, dst, size); \ +} while (0) + +static void +decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESSENGER_MessageBody *body, + uint16_t length, const char *buffer, uint16_t offset) +{ + switch (*kind) + { + case GNUNET_MESSENGER_KIND_INFO: + decode_step(buffer, offset, &(body->info.host_key)); + decode_step(buffer, offset, &(body->info.unique_id)); + break; + case GNUNET_MESSENGER_KIND_JOIN: + decode_step(buffer, offset, &(body->join.key)); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + break; + case GNUNET_MESSENGER_KIND_NAME: + if (length - offset > 0) + decode_step_malloc(buffer, offset, body->name.name, length - offset, 1); + else + body->name.name = NULL; + break; + case GNUNET_MESSENGER_KIND_KEY: + decode_step(buffer, offset, &(body->key.key)); + break; + case GNUNET_MESSENGER_KIND_PEER: + decode_step(buffer, offset, &(body->peer.peer)); + break; + case GNUNET_MESSENGER_KIND_ID: + decode_step(buffer, offset, &(body->id.id)); + break; + case GNUNET_MESSENGER_KIND_MISS: + decode_step(buffer, offset, &(body->miss.peer)); + break; + case GNUNET_MESSENGER_KIND_MERGE: + decode_step(buffer, offset, &(body->merge.previous)); + break; + case GNUNET_MESSENGER_KIND_REQUEST: + decode_step(buffer, offset, &(body->request.hash)); + break; + case GNUNET_MESSENGER_KIND_INVITE: + decode_step(buffer, offset, &(body->invite.door)); + decode_step(buffer, offset, &(body->invite.key)); + break; + case GNUNET_MESSENGER_KIND_TEXT: + decode_step_malloc(buffer, offset, body->text.text, length - offset, 1); + break; + case GNUNET_MESSENGER_KIND_FILE: + decode_step(buffer, offset, &(body->file.key)); + decode_step(buffer, offset, &(body->file.hash)); + decode_step_ext(buffer, offset, body->file.name, NAME_MAX); + decode_step_malloc(buffer, offset, body->file.uri, length - offset, 1); + break; + case GNUNET_MESSENGER_KIND_PRIVATE: + decode_step(buffer, offset, &(body->private.key)); + + body->private.length = (length - offset); + decode_step_malloc(buffer, offset, body->private.data, length - offset, 0); + break; + default: + *kind = GNUNET_MESSENGER_KIND_UNKNOWN; + break; + } +} + +int +decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer) +{ + uint16_t offset = 0; + + if (length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN)) + return GNUNET_NO; + + decode_step(buffer, offset, &(message->header.signature)); + decode_step(buffer, offset, &(message->header.timestamp)); + decode_step(buffer, offset, &(message->header.sender_id)); + decode_step(buffer, offset, &(message->header.previous)); + decode_step(buffer, offset, &(message->header.kind)); + + if (length < get_message_kind_size (message->header.kind)) + return GNUNET_NO; + + decode_message_body (&(message->header.kind), &(message->body), length, buffer, offset); + + return GNUNET_YES; +} + +static int +decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, const char *buffer) +{ + uint16_t offset = 0; + + if (length < get_short_message_size (NULL)) + return GNUNET_NO; + + decode_step(buffer, offset, &(message->kind)); + + if (length < get_short_message_size (message)) + return GNUNET_NO; + + decode_message_body (&(message->kind), &(message->body), length, buffer, offset); + + return GNUNET_YES; +} + +void +hash_message (uint16_t length, const char *buffer, struct GNUNET_HashCode *hash) +{ + GNUNET_CRYPTO_hash (buffer + sizeof(struct GNUNET_CRYPTO_EcdsaSignature), + length - sizeof(struct GNUNET_CRYPTO_EcdsaSignature), hash); +} + +void +sign_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, + const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego) +{ + struct GNUNET_MESSENGER_MessageSignature signature; + + signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); + signature.purpose.size = htonl (sizeof(signature)); + + GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); + + GNUNET_IDENTITY_sign(&(ego->priv), &signature, &(message->header.signature)); + GNUNET_memcpy(buffer, &(message->header.signature), sizeof(struct GNUNET_CRYPTO_EcdsaSignature)); +} + +int +verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, + const struct GNUNET_IDENTITY_PublicKey *key) +{ + struct GNUNET_MESSENGER_MessageSignature signature; + + signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); + signature.purpose.size = htonl (sizeof(signature)); + + GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); + + return GNUNET_IDENTITY_signature_verify(GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature, + &(message->header.signature), key); +} + +int +encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PublicKey *key) +{ + struct GNUNET_MESSENGER_ShortMessage shortened; + + fold_short_message (message, &shortened); + + const uint16_t length = get_short_message_size (&shortened); + + message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE; + message->body.private.data = GNUNET_malloc(length); + + encode_short_message (&shortened, length, message->body.private.data); + + if (GNUNET_IDENTITY_encrypt (message->body.private.data, length, key, &(message->body.private.key), + message->body.private.data) + == length) + { + destroy_message_body (shortened.kind, &(shortened.body)); + return GNUNET_YES; + } + else + { + unfold_short_message (&shortened, message); + return GNUNET_NO; + } +} + +int +decrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PrivateKey *key) +{ + if (message->body.private.length != GNUNET_IDENTITY_decrypt (message->body.private.data, + message->body.private.length, key, + &(message->body.private.key), + message->body.private.data)) + return GNUNET_NO; + + struct GNUNET_MESSENGER_ShortMessage shortened; + + if (GNUNET_YES != decode_short_message (&shortened, message->body.private.length, message->body.private.data)) + return GNUNET_NO; + + unfold_short_message (&shortened, message); + return GNUNET_YES; +} + +struct GNUNET_MQ_Envelope* +pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, + const struct GNUNET_MESSENGER_Ego *ego, int mode) +{ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packing message: %u\n", message->header.kind); + + struct GNUNET_MessageHeader *header; + + uint16_t length = get_message_size (message); + + struct GNUNET_MQ_Envelope *env; + char *buffer; + + if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode) + { + env = GNUNET_MQ_msg_extra(header, length, GNUNET_MESSAGE_TYPE_CADET_CLI); + + buffer = (char*) &(header[1]); + } + else + { + env = NULL; + + buffer = GNUNET_malloc(length); + } + + encode_message (message, length, buffer); + + if (hash) + { + hash_message (length, buffer, hash); + + if (ego) + sign_message (message, length, buffer, hash, ego); + } + + if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE != mode) + GNUNET_free(buffer); + + return env; +} diff --git a/src/messenger/messenger_api_message.h b/src/messenger/messenger_api_message.h new file mode 100644 index 000000000..0f0a97e9c --- /dev/null +++ b/src/messenger/messenger_api_message.h @@ -0,0 +1,190 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_message.h + * @brief messenger api: client and service implementation of GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_MESSAGE_H +#define GNUNET_MESSENGER_API_MESSAGE_H + +#include "platform.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_identity_service.h" +#include "gnunet_mq_lib.h" +#include "gnunet_signatures.h" + +#include "gnunet_messenger_service.h" + +#include "messenger_api_ego.h" + +/** + * Creates and allocates a new message with a specific kind. + * + * @param kind Kind of message + * @return New message + */ +struct GNUNET_MESSENGER_Message* +create_message (enum GNUNET_MESSENGER_MessageKind kind); + +/** + * Creates and allocates a copy of a given message. + * + * @param message Message + * @return New message + */ +struct GNUNET_MESSENGER_Message* +copy_message (const struct GNUNET_MESSENGER_Message *message); + +/** + * Destroys a message and frees its memory fully. + * + * @param message Message + */ +void +destroy_message (struct GNUNET_MESSENGER_Message *message); + +/** + * Returns the minimal size in bytes to encode a message of a specific kind. + * + * @param kind Kind of message + * @return Minimal size to encode + */ +uint16_t +get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind); + +/** + * Returns the exact size in bytes to encode a given message. + * + * @param message Message + * @return Size to encode + */ +uint16_t +get_message_size (const struct GNUNET_MESSENGER_Message *message); + +/** + * Encodes a given message into a buffer of a maximal length in bytes. + * + * @param message Message + * @param length Maximal length to encode + * @param[out] buffer Buffer + */ +void +encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer); + +/** + * Decodes a message from a given buffer of a maximal length in bytes. + * + * If the buffer is too small for a message of its decoded kind the function fails with + * resulting GNUNET_NO after decoding only the messages header. + * + * On success the function returns GNUNET_YES. + * + * @param[out] message Message + * @param length Maximal length to decode + * @param buffer Buffer + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer); + +/** + * Calculates a hash of a given buffer of a length in bytes. + * + * @param length Length of buffer + * @param buffer Buffer + * @param[out] hash Hash + */ +void +hash_message (uint16_t length, const char *buffer, struct GNUNET_HashCode *hash); + +/** + * Signs the hash of a message with a given ego and writes the signature + * into the buffer as well. + * + * @param[out] message Message + * @param length Length of buffer + * @param[out] buffer Buffer + * @param hash Hash of message + * @param ego EGO + */ +void +sign_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, + const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego); + +/** + * Verifies the signature of a given message and its hash with a specific + * public key. The function returns GNUNET_OK if the signature was valid, otherwise + * GNUNET_SYSERR. + * + * @param message Message + * @param hash Hash of message + * @param key Public key of EGO + * @return GNUNET_OK on success, otherwise GNUNET_SYSERR + */ +int +verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, + const struct GNUNET_IDENTITY_PublicKey *key); + +/** + * Encrypts a message using a given public key and replaces its body + * and kind with the now private encrypted message. The function returns + * GNUNET_YES if the operation succeeded, otherwise GNUNET_NO. + * + * @param message Message + * @param key Public key of EGO + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PublicKey *key); + +/** + * Decrypts a private message using a given private key and replaces its body + * and kind with the inner encrypted message. The function returns GNUNET_YES if the + * operation succeeded, otherwise GNUNET_NO. + * + * @param message Message + * @param key Private key of EGO + * @return GNUNET_YES on success, otherwise GNUNET_NO + */ +int +decrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PrivateKey *key); + +#define GNUNET_MESSENGER_PACK_MODE_ENVELOPE 0x1 +#define GNUNET_MESSENGER_PACK_MODE_UNKNOWN 0x0 + +/** + * Encodes the message to pack it into a newly allocated envelope if mode + * is equal to GNUNET_MESSENGER_PACK_MODE_ENVELOPE. Independent of the mode the message + * will be hashed if hash is not NULL and it will be signed if the ego is + * not NULL. + * + * @param[out] message Message + * @param[out] hash Hash of message + * @param ego EGO to sign + * @param mode Mode of packing + * @return Envelope or NULL + */ +struct GNUNET_MQ_Envelope* +pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, + const struct GNUNET_MESSENGER_Ego *ego, int mode); + +#endif //GNUNET_MESSENGER_API_MESSAGE_H diff --git a/src/messenger/messenger_api_room.c b/src/messenger/messenger_api_room.c new file mode 100644 index 000000000..5fedf1a78 --- /dev/null +++ b/src/messenger/messenger_api_room.c @@ -0,0 +1,189 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_room.c + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_room.h" + +#include "messenger_api_handle.h" + +struct GNUNET_MESSENGER_Room* +create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_new(struct GNUNET_MESSENGER_Room); + + room->handle = handle; + GNUNET_memcpy(&(room->key), key, sizeof(*key)); + + room->opened = GNUNET_NO; + room->contact_id = NULL; + + room->members = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO); + + init_list_tunnels (&(room->entries)); + + room->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + return room; +} + +static int +iterate_destroy_message (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Message *message = value; + + destroy_message (message); + + return GNUNET_YES; +} + +void +destroy_room (struct GNUNET_MESSENGER_Room *room) +{ + if (room->members) + GNUNET_CONTAINER_multishortmap_destroy (room->members); + + clear_list_tunnels (&(room->entries)); + + if (room->messages) + { + GNUNET_CONTAINER_multihashmap_iterate (room->messages, iterate_destroy_message, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (room->messages); + } + + if (room->contact_id) + GNUNET_free(room->contact_id); + + GNUNET_free(room); +} + +const struct GNUNET_MESSENGER_Message* +get_room_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash) +{ + return GNUNET_CONTAINER_multihashmap_get (room->messages, hash); +} + +static void +handle_join_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Contact *contact = get_handle_contact_by_pubkey (room->handle, &(message->body.join.key)); + + if (contact) + GNUNET_CONTAINER_multishortmap_put (room->members, &(message->header.sender_id), contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); +} + +static void +handle_leave_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + GNUNET_CONTAINER_multishortmap_remove_all (room->members, &(message->header.sender_id)); +} + +static void +handle_name_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, + &(message->header.sender_id)); + + if (contact) + set_contact_name (contact, message->body.name.name); +} + +static void +handle_key_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, + &(message->header.sender_id)); + + if (contact) + swap_handle_contact_by_pubkey (room->handle, contact, &(message->body.key.key)); +} + +static void +handle_id_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multishortmap_get (room->members, + &(message->header.sender_id)); + + if ((contact) && (GNUNET_OK + == GNUNET_CONTAINER_multishortmap_put (room->members, &(message->body.id.id), contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) + GNUNET_CONTAINER_multishortmap_remove (room->members, &(message->header.sender_id), contact); +} + +static void +handle_miss_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + if ((room->contact_id) && (0 == GNUNET_memcmp(&(message->header.sender_id), room->contact_id))) + { + struct GNUNET_MESSENGER_ListTunnel *match = find_list_tunnels (&(room->entries), &(message->body.miss.peer), NULL); + + if (match) + remove_from_list_tunnels (&(room->entries), match); + } +} + +void +handle_room_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->messages, hash)) + return; + + switch (message->header.kind) + { + case GNUNET_MESSENGER_KIND_JOIN: + handle_join_message (room, message, hash); + break; + case GNUNET_MESSENGER_KIND_LEAVE: + handle_leave_message (room, message, hash); + break; + case GNUNET_MESSENGER_KIND_NAME: + handle_name_message (room, message, hash); + break; + case GNUNET_MESSENGER_KIND_KEY: + handle_key_message (room, message, hash); + break; + case GNUNET_MESSENGER_KIND_ID: + handle_id_message (room, message, hash); + break; + case GNUNET_MESSENGER_KIND_MISS: + handle_miss_message (room, message, hash); + break; + default: + break; + } + + struct GNUNET_MESSENGER_Message *clone = copy_message (message); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, clone, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + destroy_message (clone); +} diff --git a/src/messenger/messenger_api_room.h b/src/messenger/messenger_api_room.h new file mode 100644 index 000000000..0038128d8 --- /dev/null +++ b/src/messenger/messenger_api_room.h @@ -0,0 +1,95 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_room.h + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#ifndef GNUNET_MESSENGER_API_ROOM_H +#define GNUNET_MESSENGER_API_ROOM_H + +#include "platform.h" +#include "gnunet_container_lib.h" +#include "gnunet_crypto_lib.h" + +#include "gnunet_messenger_service.h" + +#include "messenger_api_list_tunnels.h" +#include "messenger_api_contact.h" +#include "messenger_api_message.h" + +struct GNUNET_MESSENGER_Room +{ + struct GNUNET_MESSENGER_Handle *handle; + struct GNUNET_HashCode key; + + int opened; + + struct GNUNET_ShortHashCode *contact_id; + + struct GNUNET_CONTAINER_MultiShortmap *members; + struct GNUNET_MESSENGER_ListTunnels entries; + + struct GNUNET_CONTAINER_MultiHashMap *messages; +}; + +/** + * Creates and allocates a new room for a handle with a given key for the client API. + * + * @param handle Handle + * @param key Key of room + * @return New room + */ +struct GNUNET_MESSENGER_Room* +create_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key); + +/** + * Destroys a room and frees its memory fully from the client API. + * + * @param room Room + */ +void +destroy_room (struct GNUNET_MESSENGER_Room *room); + +/** + * Returns a message locally stored from a map for a given hash in a room. If no matching + * message is found, NULL gets returned. + * + * @param room Room + * @param hash Hash of message + * @return Message or NULL + */ +const struct GNUNET_MESSENGER_Message* +get_room_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash); + +/** + * Handles a message with a given hash in a room for the client API to update + * members and its information. The function also stores the message in map locally for access afterwards. + * + * @param room Room + * @param message Message + * @param hash Hash of message + */ +void +handle_room_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash); + +#endif //GNUNET_MESSENGER_API_ROOM_H diff --git a/src/messenger/test_messenger.c b/src/messenger/test_messenger.c new file mode 100644 index 000000000..b42dfe6d9 --- /dev/null +++ b/src/messenger/test_messenger.c @@ -0,0 +1,187 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file messenger/test_messenger.c + * @author Tobias Frisch + * @brief Test for the messenger service using cadet API. + */ +#include +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib.h" +#include "gnunet_messenger_service.h" + +/** + * How long until we really give up on a particular testcase portion? + */ +#define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \ + 60) + +/** + * How long until we give up on any particular operation (and retry)? + */ +#define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + +#define TESTER_NAME "tester" + +static int status = 1; + +static struct GNUNET_SCHEDULER_Task *die_task = NULL; +static struct GNUNET_SCHEDULER_Task *op_task = NULL; + +struct GNUNET_MESSENGER_Handle *messenger = NULL; + +static void +end (void *cls) +{ + die_task = NULL; + + if (op_task) + { + GNUNET_SCHEDULER_cancel (op_task); + op_task = NULL; + } + + if (messenger) + { + GNUNET_MESSENGER_disconnect(messenger); + messenger = NULL; + } + + status = 0; +} + + +static void +end_badly (void *cls) +{ + fprintf (stderr, "Testcase failed (timeout).\n"); + + end (NULL); + status = 1; +} + +static void +end_operation (void *cls) +{ + op_task = NULL; + + fprintf (stderr, "Testcase failed (operation: '%s').\n", cls? (const char*) cls : "unknown"); + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + end (NULL); + status = 1; +} + +static int identity_counter = 0; + +/** + * Function called when an identity is retrieved. + * + * @param cls Closure + * @param handle Handle of messenger service + */ +static void +on_identity (void *cls, struct GNUNET_MESSENGER_Handle *handle) +{ + if (op_task) + { + GNUNET_SCHEDULER_cancel (op_task); + op_task = NULL; + } + + const char* name = GNUNET_MESSENGER_get_name(handle); + + if (0 != strcmp(name, TESTER_NAME)) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name"); + return; + } + + struct GNUNET_IDENTITY_Ego* ego = GNUNET_IDENTITY_ego_get_anonymous(); + struct GNUNET_IDENTITY_PublicKey anonymous_key; + + GNUNET_IDENTITY_ego_get_public_key(ego, &anonymous_key); + + const struct GNUNET_IDENTITY_PublicKey* key = GNUNET_MESSENGER_get_key(handle); + + if (((!identity_counter) && (0 != GNUNET_memcmp(key, (&anonymous_key)))) || + ((identity_counter) && (0 == GNUNET_memcmp(key, (&anonymous_key))))) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key"); + return; + } + + if (identity_counter) { + GNUNET_MESSENGER_disconnect(handle); + + op_task = NULL; + messenger = NULL; + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + die_task = GNUNET_SCHEDULER_add_now (&end, NULL); + return; + } + + GNUNET_MESSENGER_update(messenger); + identity_counter++; +} + +/** + * Main function for testcase. + * + * @param cls Closure + * @param cfg Configuration + * @param peer Peer for testing + */ +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) +{ + die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL); + + identity_counter = 0; + + op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, "connect"); + messenger = GNUNET_MESSENGER_connect(cfg, TESTER_NAME, &on_identity, NULL, NULL, NULL); +} + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main(int argc, char **argv) +{ + if (0 != GNUNET_TESTING_peer_run("test-messenger", + "test_messenger_api.conf", + &run, NULL)) + return 1; + + return status; +} diff --git a/src/messenger/test_messenger_anonymous.c b/src/messenger/test_messenger_anonymous.c new file mode 100644 index 000000000..e2057acc4 --- /dev/null +++ b/src/messenger/test_messenger_anonymous.c @@ -0,0 +1,179 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file messenger/test_messenger_anonymous.c + * @author Tobias Frisch + * @brief Test for the messenger service using cadet API. + */ +#include +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib.h" +#include "gnunet_messenger_service.h" + +/** + * How long until we really give up on a particular testcase portion? + */ +#define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \ + 60) + +/** + * How long until we give up on any particular operation (and retry)? + */ +#define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + +static int status = 1; + +static struct GNUNET_SCHEDULER_Task *die_task = NULL; +static struct GNUNET_SCHEDULER_Task *op_task = NULL; + +struct GNUNET_MESSENGER_Handle *messenger = NULL; + +static void +end (void *cls) +{ + die_task = NULL; + + if (op_task) + { + GNUNET_SCHEDULER_cancel (op_task); + op_task = NULL; + } + + if (messenger) + { + GNUNET_MESSENGER_disconnect(messenger); + messenger = NULL; + } + + status = 0; +} + + +static void +end_badly (void *cls) +{ + fprintf (stderr, "Testcase failed (timeout).\n"); + + end (NULL); + status = 1; +} + +static void +end_operation (void *cls) +{ + op_task = NULL; + + fprintf (stderr, "Testcase failed (operation: '%s').\n", cls? (const char*) cls : "unknown"); + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + end (NULL); + status = 1; +} + +/** + * Function called when an identity is retrieved. + * + * @param cls Closure + * @param handle Handle of messenger service + */ +static void +on_identity (void *cls, struct GNUNET_MESSENGER_Handle *handle) +{ + if (op_task) + { + GNUNET_SCHEDULER_cancel (op_task); + op_task = NULL; + } + + const char* name = GNUNET_MESSENGER_get_name(handle); + + if (NULL != name) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name-anonymous"); + return; + } + + if (GNUNET_SYSERR != GNUNET_MESSENGER_update(handle)) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "update-fail"); + return; + } + + struct GNUNET_IDENTITY_Ego* ego = GNUNET_IDENTITY_ego_get_anonymous(); + struct GNUNET_IDENTITY_PublicKey anonymous_key; + + GNUNET_IDENTITY_ego_get_public_key(ego, &anonymous_key); + + const struct GNUNET_IDENTITY_PublicKey* key = GNUNET_MESSENGER_get_key(handle); + + if (0 != GNUNET_memcmp(key, (&anonymous_key))) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key-anonymous"); + return; + } + + GNUNET_MESSENGER_disconnect(handle); + + messenger = NULL; + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + die_task = GNUNET_SCHEDULER_add_now (&end, NULL); +} + +/** + * Main function for testcase. + * + * @param cls Closure + * @param cfg Configuration + * @param peer Peer for testing + */ +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) +{ + die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL); + + op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, "connect"); + messenger = GNUNET_MESSENGER_connect(cfg, NULL, &on_identity, NULL, NULL, NULL); +} + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main(int argc, char **argv) +{ + if (0 != GNUNET_TESTING_peer_run("test-messenger", + "test_messenger_api.conf", + &run, NULL)) + return 1; + + return status; +} diff --git a/src/messenger/test_messenger_comm0.c b/src/messenger/test_messenger_comm0.c new file mode 100644 index 000000000..631b5b2c9 --- /dev/null +++ b/src/messenger/test_messenger_comm0.c @@ -0,0 +1,252 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @file messenger/test_messenger_comm0.c + * @author Tobias Frisch + * @brief Test for the messenger service using cadet API. + */ +#include +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testbed_logger_service.h" +#include "gnunet_testbed_service.h" +#include "gnunet_testing_lib.h" +#include "gnunet_messenger_service.h" + +/** + * How long until we really give up on a particular testcase portion? + */ +#define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \ + 60) + +/** + * How long until we give up on any particular operation (and retry)? + */ +#define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + +static int status = 1; + +static struct GNUNET_SCHEDULER_Task *die_task = NULL; +static struct GNUNET_SCHEDULER_Task *op_task = NULL; + +static void +end (void *cls) +{ + die_task = NULL; + + if (op_task) + { + GNUNET_SCHEDULER_cancel (op_task); + op_task = NULL; + } + + GNUNET_SCHEDULER_shutdown (); + status = 0; +} + + +static void +end_badly (void *cls) +{ + fprintf (stderr, "Testcase failed (timeout).\n"); + + end (NULL); + status = 1; +} + +static void +end_operation (void *cls) +{ + op_task = NULL; + + fprintf (stderr, "Testcase failed (operation: '%s').\n", cls? (const char*) cls : "unknown"); + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + end (NULL); + status = 1; +} + +static void +end_error (void *cls) +{ + op_task = NULL; + + fprintf (stderr, "Testcase failed (error: '%s').\n", cls? (const char*) cls : "unknown"); + GNUNET_free(cls); + + if (die_task) + GNUNET_SCHEDULER_cancel (die_task); + + end (NULL); + status = 1; +} + +/** + * Function called whenever a message is received or sent. + * + * @param cls Closure + * @param room Room + * @param message Message + * @param hash Hash of message + */ +static void +on_message (void *cls, const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message, + const struct GNUNET_HashCode *hash) +{ + // TODO +} + +/** + * Function called when an identity is retrieved. + * + * @param cls Closure + * @param handle Handle of messenger service + */ +static void +on_identity (void *cls, struct GNUNET_MESSENGER_Handle *handle) +{ + // TODO +} + +static void +on_peer (void *cb_cls, struct GNUNET_TESTBED_Operation *op, + const struct GNUNET_TESTBED_PeerInformation *pinfo, + const char *emsg) +{ + if (emsg) + { + op_task = GNUNET_SCHEDULER_add_now (&end_error, GNUNET_strdup(emsg)); + return; + } + + if (pinfo->pit != GNUNET_TESTBED_PIT_CONFIGURATION) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "config"); + return; + } + + struct GNUNET_MESSENGER_Handle *handle; + struct GNUNET_MESSENGER_Room *room; + + fprintf (stderr, "MSG: connect\n"); + + handle = GNUNET_MESSENGER_connect(pinfo->result.cfg, "tester", &on_identity, NULL, &on_message, NULL); + + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash("test", 4, &hash); + + fprintf (stderr, "MSG: open\n"); + + room = GNUNET_MESSENGER_open_room(handle, &hash); + + fprintf (stderr, "MSG: close\n"); + + GNUNET_MESSENGER_close_room(room); + + fprintf (stderr, "MSG: disconnect\n"); + + GNUNET_MESSENGER_disconnect(handle); + + GNUNET_TESTBED_operation_done(op); + +} + +/** + * Main function for a peer of the testcase. + * + * @param cls Closure + * @param event Information about the event + */ +static void +run (void *cls, const struct GNUNET_TESTBED_EventInformation *event) +{ + if (GNUNET_TESTBED_ET_PEER_START != event->type) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "start"); + return; + } + + GNUNET_TESTBED_peer_get_information(event->details.peer_start.peer, + GNUNET_TESTBED_PIT_CONFIGURATION, + on_peer, event->details.peer_start.peer); + + fprintf (stderr, "MSG: barrier\n"); + + GNUNET_TESTBED_barrier_wait("exit", NULL, NULL); + + fprintf (stderr, "MSG: exit\n"); +} + +static void +exit_status (void *cls, const char *name, + struct GNUNET_TESTBED_Barrier *barrier, + enum GNUNET_TESTBED_BarrierStatus status, + const char *emsg) +{ + if (emsg) + { + op_task = GNUNET_SCHEDULER_add_now (&end_error, GNUNET_strdup(emsg)); + return; + } + + if (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status) + { + op_task = GNUNET_SCHEDULER_add_now (&end_operation, "exit"); + return; + } + else if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED == status) + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +static void +init (void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, unsigned int links_succeeded, + unsigned int links_failed) +{ + die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL); + + struct GNUNET_TESTBED_Controller *controller; + + controller = GNUNET_TESTBED_run_get_controller_handle(h); + + GNUNET_TESTBED_barrier_init(controller, "exit", num_peers, exit_status, NULL); +} + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main(int argc, char **argv) +{ + if (GNUNET_OK != GNUNET_TESTBED_test_run("test-messenger-comm0", + "test_messenger_api.conf", + 2, 0, + &run, NULL, + &init, NULL)) + return 1; + + return status; +} diff --git a/src/my/my_query_helper.c b/src/my/my_query_helper.c index 526e57b8b..97ea04fd1 100644 --- a/src/my/my_query_helper.c +++ b/src/my/my_query_helper.c @@ -280,14 +280,14 @@ my_conv_rsa_public_key (void *cls, MYSQL_BIND *qbind) { const struct GNUNET_CRYPTO_RsaPublicKey *rsa = qp->data; - char *buf; + void *buf; size_t buf_size; (void) cls; GNUNET_assert (1 == qp->num_params); buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa, &buf); - qbind->buffer = (void *) buf; + qbind->buffer = buf; qbind->buffer_length = buf_size; qbind->buffer_type = MYSQL_TYPE_BLOB; return 1; @@ -332,14 +332,14 @@ my_conv_rsa_signature (void *cls, MYSQL_BIND *qbind) { const struct GNUNET_CRYPTO_RsaSignature *sig = qp->data; - char *buf; + void *buf; size_t buf_size; (void) cls; GNUNET_assert (1 == qp->num_params); buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig, &buf); - qbind->buffer = (void *) buf; + qbind->buffer = buf; qbind->buffer_length = buf_size; qbind->buffer_type = MYSQL_TYPE_BLOB; return 1; diff --git a/src/namecache/Makefile.am b/src/namecache/Makefile.am index 5e80ea4c5..836a6b5d9 100644 --- a/src/namecache/Makefile.am +++ b/src/namecache/Makefile.am @@ -65,6 +65,7 @@ libgnunetnamecache_la_SOURCES = \ namecache.h libgnunetnamecache_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) libgnunetnamecache_la_LDFLAGS = \ @@ -82,6 +83,7 @@ gnunet_namecache_SOURCES = \ gnunet-namecache.c gnunet_namecache_LDADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunetnamecache.la \ $(GN_LIBINTL) @@ -91,6 +93,7 @@ gnunet_service_namecache_SOURCES = \ gnunet_service_namecache_LDADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunetnamecache.la \ @@ -107,6 +110,8 @@ libgnunet_plugin_namecache_flat_la_SOURCES = \ libgnunet_plugin_namecache_flat_la_LIBADD = \ libgnunetnamecache.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ $(LTLIBINTL) libgnunet_plugin_namecache_flat_la_LDFLAGS = \ @@ -118,6 +123,8 @@ libgnunet_plugin_namecache_sqlite_la_LIBADD = \ libgnunetnamecache.la \ $(top_builddir)/src/sq/libgnunetsq.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \ $(LTLIBINTL) libgnunet_plugin_namecache_sqlite_la_LDFLAGS = \ @@ -130,6 +137,8 @@ libgnunet_plugin_namecache_postgres_la_LIBADD = \ libgnunetnamecache.la \ $(top_builddir)/src/pq/libgnunetpq.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq \ $(LTLIBINTL) libgnunet_plugin_namecache_postgres_la_LDFLAGS = \ diff --git a/src/namecache/gnunet-namecache.c b/src/namecache/gnunet-namecache.c index 2e3c733e6..19f2a5766 100644 --- a/src/namecache/gnunet-namecache.c +++ b/src/namecache/gnunet-namecache.c @@ -51,7 +51,7 @@ static char *name; /** * Public key of the zone to look in. */ -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; /** * Public key of the zone to look in, in ASCII. @@ -177,7 +177,7 @@ run (void *cls, } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey, strlen (pkey), &pubkey)) + GNUNET_IDENTITY_public_key_from_string (pkey, &pubkey)) { fprintf (stderr, _ ("Invalid public key for zone `%s'\n"), pkey); GNUNET_SCHEDULER_shutdown (); diff --git a/src/namecache/gnunet-service-namecache.c b/src/namecache/gnunet-service-namecache.c index 7cf216ce3..07bf30de9 100644 --- a/src/namecache/gnunet-service-namecache.c +++ b/src/namecache/gnunet-service-namecache.c @@ -184,40 +184,24 @@ handle_lookup_block_it (void *cls, struct LookupBlockContext *lnc = cls; struct GNUNET_MQ_Envelope *env; struct LookupBlockResponseMessage *r; - size_t esize; size_t bsize; - bsize = ntohl (block->purpose.size); - if (bsize < - (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof(struct - GNUNET_TIME_AbsoluteNBO))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Malformed block."); - lnc->status = GNUNET_SYSERR; - return; - } - esize = ntohl (block->purpose.size) - - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - - sizeof(struct GNUNET_TIME_AbsoluteNBO); + bsize = GNUNET_GNSRECORD_block_get_size (block); env = GNUNET_MQ_msg_extra (r, - esize, + bsize, GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE); r->gns_header.r_id = htonl (lnc->request_id); - r->expire = block->expiration_time; - r->signature = block->signature; - r->derived_key = block->derived_key; GNUNET_memcpy (&r[1], - &block[1], - esize); + block, + bsize); GNUNET_STATISTICS_update (statistics, "blocks found in cache", 1, GNUNET_NO); + r->expire = GNUNET_TIME_absolute_hton ( + GNUNET_GNSRECORD_block_get_expiration (block)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending NAMECACHE_LOOKUP_BLOCK_RESPONSE message with expiration time %s\n", - GNUNET_STRINGS_absolute_time_to_string ( - GNUNET_TIME_absolute_ntoh (r->expire))); + "Sending NAMECACHE_LOOKUP_BLOCK_RESPONSE message\n"); GNUNET_MQ_send (lnc->nc->mq, env); } @@ -314,20 +298,11 @@ handle_block_cache (void *cls, GNUNET_NO); esize = ntohs (rp_msg->gns_header.header.size) - sizeof(struct BlockCacheMessage); - block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) + esize); - block->signature = rp_msg->signature; - block->derived_key = rp_msg->derived_key; - block->purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_TIME_AbsoluteNBO) - + esize); - block->expiration_time = rp_msg->expire; + block = GNUNET_malloc (esize); + memcpy (block, &rp_msg[1], esize); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received NAMECACHE_BLOCK_CACHE message with expiration time %s\n", - GNUNET_STRINGS_absolute_time_to_string ( - GNUNET_TIME_absolute_ntoh (block->expiration_time))); - GNUNET_memcpy (&block[1], - &rp_msg[1], - esize); + "Received NAMECACHE_BLOCK_CACHE message with type %u\n", + htonl (block->type)); res = GSN_database->cache_block (GSN_database->cls, block); GNUNET_free (block); diff --git a/src/namecache/namecache.h b/src/namecache/namecache.h index 1657662c2..43c8cf85f 100644 --- a/src/namecache/namecache.h +++ b/src/namecache/namecache.h @@ -92,7 +92,7 @@ struct LookupBlockResponseMessage /** * Derived public key. */ - struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; + struct GNUNET_IDENTITY_PublicKey derived_key; /* follwed by encrypted block data */ }; @@ -121,7 +121,7 @@ struct BlockCacheMessage /** * Derived public key. */ - struct GNUNET_CRYPTO_EcdsaPublicKey derived_key; + struct GNUNET_IDENTITY_PublicKey derived_key; /* follwed by encrypted block data */ }; diff --git a/src/namecache/namecache_api.c b/src/namecache/namecache_api.c index 0c904c9ed..fdbf142a7 100644 --- a/src/namecache/namecache_api.c +++ b/src/namecache/namecache_api.c @@ -225,19 +225,11 @@ handle_lookup_block_response (void *cls, size = ntohs (msg->gns_header.header.size) - sizeof(struct LookupBlockResponseMessage); { - char buf[size + sizeof(struct GNUNET_GNSRECORD_Block)] GNUNET_ALIGN; + char buf[size] GNUNET_ALIGN; struct GNUNET_GNSRECORD_Block *block; block = (struct GNUNET_GNSRECORD_Block *) buf; - block->signature = msg->signature; - block->derived_key = msg->derived_key; - block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); - block->purpose.size = htonl (size - + sizeof(struct GNUNET_TIME_AbsoluteNBO) - + sizeof(struct - GNUNET_CRYPTO_EccSignaturePurpose)); - block->expiration_time = msg->expire; - GNUNET_memcpy (&block[1], + GNUNET_memcpy (block, &msg[1], size); if (GNUNET_OK != @@ -483,11 +475,7 @@ GNUNET_NAMECACHE_block_cache (struct GNUNET_NAMECACHE_Handle *h, if (NULL == h->mq) return NULL; - blen = ntohl (block->purpose.size); - GNUNET_assert (blen > (sizeof(struct GNUNET_TIME_AbsoluteNBO) - + sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose))); - blen -= (sizeof(struct GNUNET_TIME_AbsoluteNBO) - + sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)); + blen = GNUNET_GNSRECORD_block_get_size (block); rid = get_op_id (h); qe = GNUNET_new (struct GNUNET_NAMECACHE_QueueEntry); qe->nsh = h; @@ -502,11 +490,8 @@ GNUNET_NAMECACHE_block_cache (struct GNUNET_NAMECACHE_Handle *h, blen, GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE); msg->gns_header.r_id = htonl (rid); - msg->expire = block->expiration_time; - msg->signature = block->signature; - msg->derived_key = block->derived_key; GNUNET_memcpy (&msg[1], - &block[1], + block, blen); GNUNET_MQ_send (h->mq, env); diff --git a/src/namecache/plugin_namecache_flat.c b/src/namecache/plugin_namecache_flat.c index 24f4f2570..eb7800051 100644 --- a/src/namecache/plugin_namecache_flat.c +++ b/src/namecache/plugin_namecache_flat.c @@ -207,10 +207,7 @@ store_and_free_entries (void *cls, struct GNUNET_CRYPTO_HashAsciiEncoded query; size_t block_size; - block_size = ntohl (entry->block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); - + block_size = GNUNET_GNSRECORD_block_get_size (entry->block); GNUNET_STRINGS_base64_encode ((char *) entry->block, block_size, &block_b64); @@ -277,7 +274,7 @@ expire_blocks (void *cls, struct GNUNET_TIME_Absolute expiration; now = GNUNET_TIME_absolute_get (); - expiration = GNUNET_TIME_absolute_ntoh (entry->block->expiration_time); + expiration = GNUNET_GNSRECORD_block_get_expiration (entry->block); if (0 == GNUNET_TIME_absolute_get_difference (now, expiration).rel_value_us) @@ -319,12 +316,9 @@ namecache_cache_block (void *cls, size_t block_size; namecache_expire_blocks (plugin); - GNUNET_CRYPTO_hash (&block->derived_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), - &query); - block_size = ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); + GNUNET_GNSRECORD_query_from_block (block, + &query); + block_size = GNUNET_GNSRECORD_block_get_size (block); if (block_size > 64 * 65536) { GNUNET_break (0); diff --git a/src/namecache/plugin_namecache_postgres.c b/src/namecache/plugin_namecache_postgres.c index 0e947e9c5..ae0f71a1f 100644 --- a/src/namecache/plugin_namecache_postgres.c +++ b/src/namecache/plugin_namecache_postgres.c @@ -64,15 +64,13 @@ database_setup (struct Plugin *plugin) " query BYTEA NOT NULL DEFAULT ''," " block BYTEA NOT NULL DEFAULT ''," " expiration_time BIGINT NOT NULL DEFAULT 0" - ")" - "WITH OIDS"); + ")"); struct GNUNET_PQ_ExecuteStatement es_default = GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns096blocks (" " query BYTEA NOT NULL DEFAULT ''," " block BYTEA NOT NULL DEFAULT ''," " expiration_time BIGINT NOT NULL DEFAULT 0" - ")" - "WITH OIDS"); + ")"); const struct GNUNET_PQ_ExecuteStatement *cr; if (GNUNET_YES == @@ -155,11 +153,11 @@ namecache_postgres_expire_blocks (struct Plugin *plugin) static void delete_old_block (struct Plugin *plugin, const struct GNUNET_HashCode *query, - struct GNUNET_TIME_AbsoluteNBO expiration_time) + struct GNUNET_TIME_Absolute expiration_time) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (query), - GNUNET_PQ_query_param_absolute_time_nbo (&expiration_time), + GNUNET_PQ_query_param_absolute_time (&expiration_time), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus res; @@ -184,21 +182,20 @@ namecache_postgres_cache_block (void *cls, { struct Plugin *plugin = cls; struct GNUNET_HashCode query; - size_t block_size = ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); + size_t block_size = GNUNET_GNSRECORD_block_get_size (block); + struct GNUNET_TIME_Absolute exp; + exp = GNUNET_GNSRECORD_block_get_expiration (block); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&query), GNUNET_PQ_query_param_fixed_size (block, block_size), - GNUNET_PQ_query_param_absolute_time_nbo (&block->expiration_time), + GNUNET_PQ_query_param_absolute_time (&exp), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus res; namecache_postgres_expire_blocks (plugin); - GNUNET_CRYPTO_hash (&block->derived_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), - &query); + GNUNET_GNSRECORD_query_from_block (block, + &query); if (block_size > 64 * 65536) { GNUNET_break (0); @@ -206,7 +203,7 @@ namecache_postgres_cache_block (void *cls, } delete_old_block (plugin, &query, - block->expiration_time); + exp); res = GNUNET_PQ_eval_prepared_non_select (plugin->dbh, "cache_block", @@ -265,10 +262,7 @@ namecache_postgres_lookup_block (void *cls, "Ending iteration (no more results)\n"); return GNUNET_NO; } - if ((bsize < sizeof(*block)) || - (bsize != ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature))) + if ((bsize < sizeof(*block))) { GNUNET_break (0); LOG (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/namecache/plugin_namecache_sqlite.c b/src/namecache/plugin_namecache_sqlite.c index c9d79ba2d..82008c837 100644 --- a/src/namecache/plugin_namecache_sqlite.c +++ b/src/namecache/plugin_namecache_sqlite.c @@ -332,9 +332,7 @@ namecache_sqlite_cache_block (void *cls, struct Plugin *plugin = cls; struct GNUNET_HashCode query; struct GNUNET_TIME_Absolute expiration; - size_t block_size = ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature); + size_t block_size = GNUNET_GNSRECORD_block_get_size (block); struct GNUNET_SQ_QueryParam del_params[] = { GNUNET_SQ_query_param_auto_from_type (&query), GNUNET_SQ_query_param_absolute_time (&expiration), @@ -356,10 +354,9 @@ namecache_sqlite_cache_block (void *cls, last_expire = GNUNET_TIME_absolute_get (); namecache_sqlite_expire_blocks (plugin); } - GNUNET_CRYPTO_hash (&block->derived_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), - &query); - expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time); + GNUNET_assert (GNUNET_OK == + GNUNET_GNSRECORD_query_from_block (block, &query)); + expiration = GNUNET_GNSRECORD_block_get_expiration (block); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Caching new version of block %s (expires %s)\n", GNUNET_h2s (&query), @@ -498,10 +495,7 @@ namecache_sqlite_lookup_block (void *cls, GNUNET_break (0); ret = GNUNET_SYSERR; } - else if ((block_size < sizeof(struct GNUNET_GNSRECORD_Block)) || - (ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature) != block_size)) + else if ((block_size < sizeof(struct GNUNET_GNSRECORD_Block))) { GNUNET_break (0); GNUNET_SQ_cleanup_result (rs); diff --git a/src/namecache/test_namecache_api_cache_block.c b/src/namecache/test_namecache_api_cache_block.c index 12b72d93b..310c4de42 100644 --- a/src/namecache/test_namecache_api_cache_block.c +++ b/src/namecache/test_namecache_api_cache_block.c @@ -39,9 +39,9 @@ static struct GNUNET_NAMECACHE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -172,23 +172,13 @@ run (void *cls, { struct GNUNET_GNSRECORD_Data rd; struct GNUNET_GNSRECORD_Block *block; - char *hostkey_file; const char *name = "dummy.dummy.gnunet"; endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_asprintf (&hostkey_file, - "zonefiles%s%s", - DIR_SEPARATOR_STR, - "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", - hostkey_file); - GNUNET_assert (GNUNET_SYSERR != - GNUNET_CRYPTO_ecdsa_key_from_file (hostkey_file, - GNUNET_YES, - &privkey)); - GNUNET_free (hostkey_file); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us + 10000000000; diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 40ac64197..3a92f98c9 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -131,6 +131,7 @@ libgnunet_plugin_rest_namestore_la_LIBADD = \ $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/json/libgnunetjson.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecordjson.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ $(LTLIBINTL) -ljansson $(MHD_LIBS) libgnunet_plugin_rest_namestore_la_LDFLAGS = \ @@ -144,6 +145,7 @@ libgnunetnamestore_la_SOURCES = \ namestore.h libgnunetnamestore_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) @@ -190,6 +192,7 @@ gnunet_service_namestore_SOURCES = \ gnunet_service_namestore_LDADD = \ $(top_builddir)/src/namecache/libgnunetnamecache.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ libgnunetnamestore.la \ @@ -200,7 +203,8 @@ gnunet_service_namestore_LDADD = \ libgnunet_plugin_namestore_flat_la_SOURCES = \ plugin_namestore_flat.c libgnunet_plugin_namestore_flat_la_LIBADD = \ - $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ $(LTLIBINTL) @@ -212,6 +216,7 @@ libgnunet_plugin_namestore_sqlite_la_SOURCES = \ plugin_namestore_sqlite.c libgnunet_plugin_namestore_sqlite_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/sq/libgnunetsq.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \ @@ -223,6 +228,7 @@ libgnunet_plugin_namestore_postgres_la_SOURCES = \ plugin_namestore_postgres.c libgnunet_plugin_namestore_postgres_la_LIBADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/pq/libgnunetpq.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq \ @@ -236,6 +242,7 @@ test_namestore_api_store_flat_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetnamestore.la test_namestore_api_store_sqlite_SOURCES = \ @@ -244,6 +251,7 @@ test_namestore_api_store_sqlite_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetnamestore.la test_namestore_api_store_postgres_SOURCES = \ @@ -252,6 +260,7 @@ test_namestore_api_store_postgres_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetnamestore.la test_namestore_api_store_update_flat_SOURCES = \ diff --git a/src/namestore/gnunet-namestore-fcfsd.c b/src/namestore/gnunet-namestore-fcfsd.c index 34641d22e..22d108067 100644 --- a/src/namestore/gnunet-namestore-fcfsd.c +++ b/src/namestore/gnunet-namestore-fcfsd.c @@ -164,7 +164,7 @@ struct Request */ char public_key[128]; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; }; /** @@ -211,7 +211,7 @@ static struct GNUNET_NAMESTORE_Handle *ns; /** * Private key for the fcfsd zone. */ -static struct GNUNET_CRYPTO_EcdsaPrivateKey fcfs_zone_pkey; +static struct GNUNET_IDENTITY_PrivateKey fcfs_zone_pkey; /** * Connection to identity service. @@ -306,7 +306,6 @@ zone_iteration_end (void *cls) /* return static form */ GNUNET_asprintf (&full_page, ZONEINFO_PAGE, - zr->zoneinfo, zr->zoneinfo); response = MHD_create_response_from_buffer (strlen (full_page), (void *) full_page, @@ -332,7 +331,7 @@ zone_iteration_end (void *cls) */ static void iterate_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -350,7 +349,8 @@ iterate_cb (void *cls, return; } - if (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type) + if ((GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type) && + (GNUNET_GNSRECORD_TYPE_EDKEY != rd->record_type)) { GNUNET_NAMESTORE_zone_iterator_next (zr->list_it, 1); @@ -615,13 +615,14 @@ zone_to_name_error (void *cls) */ static void zone_to_name_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct Request *request = cls; struct GNUNET_GNSRECORD_Data r; + char *rdata; (void) rd; (void) zone_key; @@ -636,10 +637,21 @@ zone_to_name_cb (void *cls, run_httpd_now (); return; } - r.data = &request->pub; - r.data_size = sizeof(request->pub); + if (GNUNET_OK != GNUNET_GNSRECORD_data_from_identity (&request->pub, + &rdata, + &r.data_size, + &r.record_type)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ ("Error creating record data.\n")); + request->phase = RP_FAIL; + MHD_resume_connection (request->con); + run_httpd_now (); + return; + } + + r.data = rdata; r.expiration_time = UINT64_MAX; - r.record_type = GNUNET_GNSRECORD_TYPE_PKEY; r.flags = GNUNET_GNSRECORD_RF_NONE; request->qe = GNUNET_NAMESTORE_records_store (ns, &fcfs_zone_pkey, @@ -647,6 +659,7 @@ zone_to_name_cb (void *cls, 1, &r, &put_continuation, request); + GNUNET_free (rdata); } @@ -677,7 +690,7 @@ lookup_it_error (void *cls) */ static void lookup_it_processor (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zonekey, + const struct GNUNET_IDENTITY_PrivateKey *zonekey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -712,9 +725,8 @@ lookup_it_finished (void *cls) return; } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key, - strlen (request->public_key), - &request->pub)) + GNUNET_IDENTITY_public_key_from_string (request->public_key, + &request->pub)) { GNUNET_break (0); request->phase = RP_FAIL; @@ -767,7 +779,7 @@ create_response (void *cls, { struct MHD_Response *response; struct Request *request; - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; MHD_RESULT ret; (void) cls; @@ -822,10 +834,8 @@ create_response (void *cls, request->pp = NULL; } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (request->public_key, - strlen ( - request->public_key), - &pub)) + GNUNET_IDENTITY_public_key_from_string (request->public_key, + &pub)) { /* parse error */ return fill_s_reply ("Failed to parse given public key", @@ -1211,7 +1221,8 @@ main (int argc, options, &run, NULL)) ? 0 : 1; GNUNET_free_nz ((void *) argv); - GNUNET_CRYPTO_ecdsa_key_clear (&fcfs_zone_pkey); + // FIXME + // GNUNET_CRYPTO_ecdsa_key_clear (&fcfs_zone_pkey); return ret; } diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 07d045b90..92d2cf627 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c @@ -59,7 +59,7 @@ static struct GNUNET_NAMESTORE_Handle *ns; /** * Private key for the our zone. */ -static struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey; +static struct GNUNET_IDENTITY_PrivateKey zone_pkey; /** * Handle to identity lookup. @@ -496,7 +496,7 @@ display_record (const char *rname, */ static void display_record_iterator (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -519,7 +519,7 @@ display_record_iterator (void *cls, */ static void display_record_monitor (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -542,7 +542,7 @@ display_record_monitor (void *cls, */ static void display_record_lookup (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -622,7 +622,7 @@ add_error_cb (void *cls) */ static void get_existing_record (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rec_name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -661,11 +661,11 @@ get_existing_record (void *cls, return; case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: fprintf ( stderr, _ ( - "A %s record exists already under `%s', no other records can be added.\n"), - "PKEY", + "A zone key record exists already under `%s', no other records can be added.\n"), rec_name); ret = 1; test_finished (); @@ -703,13 +703,13 @@ get_existing_record (void *cls, break; case GNUNET_GNSRECORD_TYPE_PKEY: + case GNUNET_GNSRECORD_TYPE_EDKEY: if (0 != rd_count) { fprintf (stderr, _ ( - "Records already exist under `%s', cannot add `%s' record.\n"), - rec_name, - "PKEY"); + "Records already exist under `%s', cannot add record.\n"), + rec_name); ret = 1; test_finished (); return; @@ -781,7 +781,7 @@ reverse_error_cb (void *cls) */ static void handle_reverse_lookup (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -826,7 +826,7 @@ del_lookup_error_cb (void *cls) */ static void del_monitor (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1187,12 +1187,11 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) } if (NULL != reverse_pkey) { - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; + struct GNUNET_IDENTITY_PublicKey pubkey; if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_pkey, - strlen (reverse_pkey), - &pubkey)) + GNUNET_IDENTITY_public_key_from_string (reverse_pkey, + &pubkey)) { fprintf (stderr, _ ("Invalid public key for reverse lookup `%s'\n"), @@ -1211,12 +1210,12 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) { char sh[105]; char sname[64]; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; GNUNET_STRINGS_utf8_tolower (uri, uri); if ((2 != (sscanf (uri, "gnunet://gns/%52s/%63s", sh, sname))) || (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (sh, strlen (sh), &pkey))) + GNUNET_IDENTITY_public_key_from_string (sh, &pkey))) { fprintf (stderr, _ ("Invalid URI `%s'\n"), uri); GNUNET_SCHEDULER_shutdown (); @@ -1242,8 +1241,8 @@ run_with_zone_pkey (const struct GNUNET_CONFIGURATION_Handle *cfg) } memset (&rd, 0, sizeof(rd)); rd.data = &pkey; - rd.data_size = sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey); - rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; + rd.data_size = GNUNET_IDENTITY_key_get_length (&pkey); + rd.record_type = ntohl (pkey.type); rd.expiration_time = etime; if (GNUNET_YES == etime_is_rel) rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; @@ -1704,11 +1703,13 @@ main (int argc, char *const *argv) NULL))) { GNUNET_free_nz ((void *) argv); - GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); + //FIXME + //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); return lret; } GNUNET_free_nz ((void *) argv); - GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); + //FIXME + //GNUNET_CRYPTO_ecdsa_key_clear (&zone_pkey); return ret; } diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index b24bb2952..d6774b37b 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -82,7 +82,7 @@ struct ZoneIteration /** * Key of the zone we are iterating over. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * Last sequence number in the zone iteration used to address next @@ -174,7 +174,7 @@ struct ZoneMonitor /** * Private key of the zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * Task active during initial iteration. @@ -314,7 +314,7 @@ struct NickCache /** * Zone the cache entry is for. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * Cached record data. @@ -336,7 +336,7 @@ static struct NickCache nick_cache[NC_SIZE]; /** * Public key of all zeros. */ -static const struct GNUNET_CRYPTO_EcdsaPrivateKey zero; +static const struct GNUNET_IDENTITY_PrivateKey zero; /** * Configuration handle. @@ -481,7 +481,7 @@ free_store_activity (struct StoreActivity *sa) static void lookup_nick_it (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, + const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -521,7 +521,7 @@ lookup_nick_it (void *cls, * @param nick nick entry to cache */ static void -cache_nick (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, +cache_nick (const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick) { struct NickCache *oldest; @@ -564,9 +564,9 @@ cache_nick (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, * @return NULL if no NICK record was found */ static struct GNUNET_GNSRECORD_Data * -get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone) +get_nick_record (const struct GNUNET_IDENTITY_PrivateKey *zone) { - struct GNUNET_CRYPTO_EcdsaPublicKey pub; + struct GNUNET_IDENTITY_PublicKey pub; struct GNUNET_GNSRECORD_Data *nick; int res; @@ -606,7 +606,7 @@ get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone) __LINE__); if (1 == do_log) { - GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub); + GNUNET_IDENTITY_key_get_public (zone, &pub); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "No nick name set for zone `%s'\n", GNUNET_GNSRECORD_z2s (&pub)); @@ -720,7 +720,7 @@ merge_with_nick_records (const struct GNUNET_GNSRECORD_Data *nick_rd, static void send_lookup_response (struct NamestoreClient *nc, uint32_t request_id, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -899,14 +899,14 @@ static void refresh_block (struct NamestoreClient *nc, struct ZoneIteration *zi, uint32_t rid, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct GNUNET_GNSRECORD_Block *block; struct CacheOperation *cop; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; struct GNUNET_GNSRECORD_Data *nick; struct GNUNET_GNSRECORD_Data *res; unsigned int res_count; @@ -946,7 +946,7 @@ refresh_block (struct NamestoreClient *nc, block = GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, res, res_count); GNUNET_assert (NULL != block); - GNUNET_CRYPTO_ecdsa_key_get_public (zone_key, &pkey); + GNUNET_IDENTITY_key_get_public (zone_key, &pkey); GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n", @@ -1214,7 +1214,7 @@ struct RecordLookupContext static void lookup_it (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, + const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1605,7 +1605,7 @@ struct ZoneToNameCtx static void handle_zone_to_name_it (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1738,7 +1738,7 @@ struct ZoneIterationProcResult static void zone_iterate_proc (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -2009,7 +2009,7 @@ monitor_iteration_next (void *cls); static void monitor_iterate_cb (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) diff --git a/src/namestore/gnunet-zoneimport.c b/src/namestore/gnunet-zoneimport.c index 5b4e41475..ce62b52d5 100644 --- a/src/namestore/gnunet-zoneimport.c +++ b/src/namestore/gnunet-zoneimport.c @@ -96,7 +96,7 @@ struct Zone /** * Private key of the zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey key; + struct GNUNET_IDENTITY_PrivateKey key; }; @@ -1405,7 +1405,7 @@ ns_lookup_error_cb (void *cls) */ static void ns_lookup_result_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, + const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 6f45ab1c1..fd9a8ed47 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -90,7 +90,7 @@ struct RecordStoreMessage /** * The private key of the authority. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by: * name with length name_len @@ -134,7 +134,7 @@ struct LabelLookupMessage /** * The private key of the zone to look up in */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /* followed by: * name with length name_len @@ -176,7 +176,7 @@ struct LabelLookupResponseMessage /** * The private key of the authority. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by: * name with length name_len @@ -198,12 +198,12 @@ struct ZoneToNameMessage /** * The private key of the zone to look up in */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * The public key of the target zone */ - struct GNUNET_CRYPTO_EcdsaPublicKey value_zone; + struct GNUNET_IDENTITY_PublicKey value_zone; }; @@ -241,7 +241,7 @@ struct ZoneToNameResponseMessage /** * The private key of the zone that contained the name. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /* followed by: * name with length name_len @@ -283,7 +283,7 @@ struct RecordResultMessage /** * The private key of the authority. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /* followed by: * name with length name_len @@ -311,7 +311,7 @@ struct ZoneMonitorStartMessage /** * Zone key. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; }; @@ -352,7 +352,7 @@ struct ZoneIterationStartMessage /** * Zone key. All zeros for "all zones". */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; }; diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index f383f8b4a..c845b5019 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -174,7 +174,7 @@ struct GNUNET_NAMESTORE_ZoneIterator /** * Private key of the zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * The operation id this zone iteration operation has @@ -493,7 +493,7 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) static int check_record_result (void *cls, const struct RecordResultMessage *msg) { - static struct GNUNET_CRYPTO_EcdsaPrivateKey priv_dummy; + static struct GNUNET_IDENTITY_PrivateKey priv_dummy; const char *name; size_t msg_len; size_t name_len; @@ -981,7 +981,7 @@ warn_delay (void *cls) struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store ( struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, @@ -1080,7 +1080,7 @@ GNUNET_NAMESTORE_records_store ( struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup ( struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, @@ -1140,8 +1140,8 @@ GNUNET_NAMESTORE_records_lookup ( struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name ( struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, + const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, @@ -1196,7 +1196,7 @@ GNUNET_NAMESTORE_zone_to_name ( struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start ( struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c index 9dc955544..6670e54ce 100644 --- a/src/namestore/namestore_api_monitor.c +++ b/src/namestore/namestore_api_monitor.c @@ -82,7 +82,7 @@ struct GNUNET_NAMESTORE_ZoneMonitor /** * Monitored zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey zone; + struct GNUNET_IDENTITY_PrivateKey zone; /** * Do we first iterate over all existing records? @@ -302,7 +302,7 @@ reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm) struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start ( const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, diff --git a/src/namestore/perf_namestore_api_zone_iteration.c b/src/namestore/perf_namestore_api_zone_iteration.c index c1012de62..f46a1c523 100644 --- a/src/namestore/perf_namestore_api_zone_iteration.c +++ b/src/namestore/perf_namestore_api_zone_iteration.c @@ -64,7 +64,7 @@ static struct GNUNET_SCHEDULER_Task *timeout_task; static struct GNUNET_SCHEDULER_Task *t; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; static struct GNUNET_NAMESTORE_ZoneIterator *zi; @@ -188,7 +188,7 @@ fail_cb (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -341,7 +341,8 @@ run (void *cls, NULL); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_assert (NULL != nsh); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); start = GNUNET_TIME_absolute_get (); t = GNUNET_SCHEDULER_add_now (&publish_record, NULL); diff --git a/src/namestore/plugin_namestore_flat.c b/src/namestore/plugin_namestore_flat.c index 60b24df67..9ccc90cfd 100644 --- a/src/namestore/plugin_namestore_flat.c +++ b/src/namestore/plugin_namestore_flat.c @@ -54,7 +54,7 @@ struct FlatFileEntry /** * Entry zone */ - struct GNUNET_CRYPTO_EcdsaPrivateKey private_key; + struct GNUNET_IDENTITY_PrivateKey private_key; /** * Record cound @@ -86,7 +86,7 @@ struct FlatFileEntry * @param h[out] initialized hash */ static void -hash_pkey_and_label (const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, +hash_pkey_and_label (const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, struct GNUNET_HashCode *h) { @@ -95,14 +95,14 @@ hash_pkey_and_label (const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, size_t key_len; label_len = strlen (label); - key_len = label_len + sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey); + key_len = label_len + sizeof(struct GNUNET_IDENTITY_PrivateKey); key = GNUNET_malloc (key_len); GNUNET_memcpy (key, label, label_len); GNUNET_memcpy (key + label_len, pkey, - sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)); + sizeof(struct GNUNET_IDENTITY_PrivateKey)); GNUNET_CRYPTO_hash (key, key_len, h); @@ -296,7 +296,7 @@ database_setup (struct Plugin *plugin) GNUNET_free (record_data); { - struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key; + struct GNUNET_IDENTITY_PrivateKey *private_key; GNUNET_STRINGS_base64_decode (zone_private_key, strlen (zone_private_key), @@ -345,7 +345,7 @@ store_and_free_entries (void *cls, (void) key; GNUNET_STRINGS_base64_encode (&entry->private_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey), + sizeof(struct GNUNET_IDENTITY_PrivateKey), &zone_private_key); data_size = GNUNET_GNSRECORD_records_get_size (entry->record_count, entry->record_data); @@ -452,7 +452,7 @@ database_shutdown (struct Plugin *plugin) static int namestore_flat_store_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -482,7 +482,7 @@ namestore_flat_store_records (void *cls, strlen (label)); GNUNET_memcpy (&entry->private_key, zone_key, - sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)); + sizeof(struct GNUNET_IDENTITY_PrivateKey)); entry->rvalue = rvalue; entry->record_count = rd_count; entry->record_data = GNUNET_new_array (rd_count, @@ -517,7 +517,7 @@ namestore_flat_store_records (void *cls, */ static int namestore_flat_lookup_records (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) @@ -574,7 +574,7 @@ struct IterateContext /** * Target zone. */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone; + const struct GNUNET_IDENTITY_PrivateKey *zone; /** * Function to call on each record. @@ -647,7 +647,7 @@ iterate_zones (void *cls, static int namestore_flat_iterate_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, @@ -674,8 +674,8 @@ namestore_flat_iterate_records (void *cls, */ struct ZoneToNameContext { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone; - const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone; + const struct GNUNET_IDENTITY_PrivateKey *zone; + const struct GNUNET_IDENTITY_PublicKey *value_zone; GNUNET_NAMESTORE_RecordIterator iter; void *iter_cls; @@ -698,11 +698,14 @@ zone_to_name (void *cls, for (unsigned int i = 0; i < entry->record_count; i++) { - if (GNUNET_GNSRECORD_TYPE_PKEY != entry->record_data[i].record_type) + if (GNUNET_NO == + GNUNET_GNSRECORD_is_zonekey_type (entry->record_data[i].record_type)) + continue; + if (ztn->value_zone->type != entry->record_data[i].record_type) continue; if (0 == memcmp (ztn->value_zone, entry->record_data[i].data, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) + entry->record_data[i].data_size)) { ztn->iter (ztn->iter_cls, i + 1, /* zero is illegal! */ @@ -730,9 +733,9 @@ zone_to_name (void *cls, */ static int namestore_flat_zone_to_name (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const struct - GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) { diff --git a/src/namestore/plugin_namestore_postgres.c b/src/namestore/plugin_namestore_postgres.c index 01dddde9e..bdbaf96b3 100644 --- a/src/namestore/plugin_namestore_postgres.c +++ b/src/namestore/plugin_namestore_postgres.c @@ -73,8 +73,7 @@ database_setup (struct Plugin *plugin) " record_data BYTEA NOT NULL DEFAULT ''," " label TEXT NOT NULL DEFAULT ''," " CONSTRAINT zl UNIQUE (zone_private_key,label)" - ")" - "WITH OIDS"); + ")"); struct GNUNET_PQ_ExecuteStatement es_default = GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records (" " seq BIGSERIAL PRIMARY KEY," @@ -85,8 +84,7 @@ database_setup (struct Plugin *plugin) " record_data BYTEA NOT NULL DEFAULT ''," " label TEXT NOT NULL DEFAULT ''," " CONSTRAINT zl UNIQUE (zone_private_key,label)" - ")" - "WITH OIDS"); + ")"); const struct GNUNET_PQ_ExecuteStatement *cr; struct GNUNET_PQ_ExecuteStatement sc = GNUNET_PQ_EXECUTE_STATEMENT_END; @@ -182,13 +180,13 @@ database_setup (struct Plugin *plugin) static int namestore_postgres_store_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct Plugin *plugin = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; uint64_t rvalue; uint32_t rd_count32 = (uint32_t) rd_count; ssize_t data_size; @@ -197,13 +195,14 @@ namestore_postgres_store_records (void *cls, 0, sizeof(pkey)); for (unsigned int i = 0; i < rd_count; i++) - if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) + if (GNUNET_YES == + GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) { - GNUNET_break (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) == - rd[i].data_size); - GNUNET_memcpy (&pkey, - rd[i].data, - rd[i].data_size); + GNUNET_break (GNUNET_OK == + GNUNET_GNSRECORD_identity_from_data (rd[i].data, + rd[i].data_size, + rd[i].record_type, + &pkey)); break; } rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, @@ -298,7 +297,7 @@ struct ParserContext /** * Zone key, NULL if part of record. */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key; + const struct GNUNET_IDENTITY_PrivateKey *zone_key; /** * Number of results still to return (counted down by @@ -332,7 +331,7 @@ parse_result_call_iterator (void *cls, size_t data_size; uint32_t record_count; char *label; - struct GNUNET_CRYPTO_EcdsaPrivateKey zk; + struct GNUNET_IDENTITY_PrivateKey zk; struct GNUNET_PQ_ResultSpec rs_with_zone[] = { GNUNET_PQ_result_spec_uint64 ("seq", &serial), GNUNET_PQ_result_spec_uint32 ("record_count", &record_count), @@ -409,7 +408,7 @@ parse_result_call_iterator (void *cls, static int namestore_postgres_lookup_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) @@ -459,7 +458,7 @@ namestore_postgres_lookup_records (void *cls, static int namestore_postgres_iterate_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, @@ -526,9 +525,9 @@ namestore_postgres_iterate_records (void *cls, static int namestore_postgres_zone_to_name (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, const struct - GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) { diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 45fb782f7..7cb9b7ed0 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c @@ -314,14 +314,14 @@ database_shutdown (struct Plugin *plugin) static int namestore_sqlite_store_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + GNUNET_IDENTITY_PrivateKey *zone_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct Plugin *plugin = cls; int n; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; uint64_t rvalue; ssize_t data_size; @@ -329,13 +329,13 @@ namestore_sqlite_store_records (void *cls, 0, sizeof(pkey)); for (unsigned int i = 0; i < rd_count; i++) - if (GNUNET_GNSRECORD_TYPE_PKEY == rd[i].record_type) + if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) { - GNUNET_break (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) == - rd[i].data_size); - GNUNET_memcpy (&pkey, - rd[i].data, - rd[i].data_size); + GNUNET_break (GNUNET_YES == + GNUNET_GNSRECORD_identity_from_data (rd[i].data, + rd[i].data_size, + rd[i].record_type, + &pkey)); break; } rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, @@ -461,7 +461,7 @@ static int get_records_and_call_iterator (struct Plugin *plugin, sqlite3_stmt *stmt, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + GNUNET_IDENTITY_PrivateKey *zone_key, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) @@ -496,7 +496,7 @@ get_records_and_call_iterator (struct Plugin *plugin, size_t data_size; void *data; char *label; - struct GNUNET_CRYPTO_EcdsaPrivateKey zk; + struct GNUNET_IDENTITY_PrivateKey zk; struct GNUNET_SQ_ResultSpec rs[] = { GNUNET_SQ_result_spec_uint64 (&seq), GNUNET_SQ_result_spec_uint32 (&record_count), @@ -578,7 +578,7 @@ get_records_and_call_iterator (struct Plugin *plugin, static int namestore_sqlite_lookup_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) @@ -629,7 +629,7 @@ namestore_sqlite_lookup_records (void *cls, static int namestore_sqlite_iterate_records (void *cls, const struct - GNUNET_CRYPTO_EcdsaPrivateKey *zone, + GNUNET_IDENTITY_PrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, @@ -695,9 +695,9 @@ namestore_sqlite_iterate_records (void *cls, */ static int namestore_sqlite_zone_to_name (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const struct - GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) { diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index 9354b9896..edcbeb874 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c @@ -30,7 +30,7 @@ #include "gnunet_namestore_service.h" #include "gnunet_identity_service.h" #include "gnunet_rest_lib.h" -#include "gnunet_json_lib.h" +#include "gnunet_gnsrecord_json_lib.h" #include "microhttpd.h" #include @@ -214,7 +214,7 @@ struct RequestHandle /** * Private key for the zone */ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey; + const struct GNUNET_IDENTITY_PrivateKey *zone_pkey; /** * IDENTITY Operation @@ -510,7 +510,7 @@ namestore_list_finished (void *cls) */ static void namestore_list_iteration (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -535,9 +535,9 @@ namestore_list_iteration (void *cls, /** Only add if not empty **/ if (j > 0) { - record_obj = GNUNET_JSON_from_gnsrecord (rname, - rd_filtered, - j); + record_obj = GNUNET_GNSRECORD_JSON_from_gnsrecord (rname, + rd_filtered, + j); json_array_append_new (handle->resp_object, record_obj); } GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1); @@ -561,7 +561,7 @@ ns_lookup_error_cb (void *cls) static void ns_get_lookup_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) @@ -587,9 +587,9 @@ ns_get_lookup_cb (void *cls, /** Only add if not empty **/ if (j > 0) { - record_obj = GNUNET_JSON_from_gnsrecord (label, - rd_filtered, - j); + record_obj = GNUNET_GNSRECORD_JSON_from_gnsrecord (label, + rd_filtered, + j); json_array_append_new (handle->resp_object, record_obj); } GNUNET_SCHEDULER_add_now (&namestore_list_finished, handle); @@ -689,7 +689,7 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle, static void ns_lookup_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -755,7 +755,7 @@ namestore_add_or_update (struct GNUNET_REST_RequestHandle *con_handle, handle->rest_handle->data_size); data_js = json_loads (term_data, JSON_DECODE_ANY, &err); struct GNUNET_JSON_Specification gnsspec[] = - { GNUNET_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count, + { GNUNET_GNSRECORD_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count, &handle->record_name), GNUNET_JSON_spec_end () }; if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)) @@ -946,7 +946,7 @@ list_ego (void *cls, const char *identifier) { struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { @@ -957,7 +957,7 @@ list_ego (void *cls, { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, @@ -983,7 +983,7 @@ list_ego (void *cls, /* Add */ ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, diff --git a/src/namestore/test_namestore_api_lookup_nick.c b/src/namestore/test_namestore_api_lookup_nick.c index 14fe7fc70..6ce969c9b 100644 --- a/src/namestore/test_namestore_api_lookup_nick.c +++ b/src/namestore/test_namestore_api_lookup_nick.c @@ -41,9 +41,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -98,7 +98,7 @@ end (void *cls) static void lookup_it (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -288,8 +288,9 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); nsh = GNUNET_NAMESTORE_connect (cfg); diff --git a/src/namestore/test_namestore_api_lookup_private.c b/src/namestore/test_namestore_api_lookup_private.c index d0ad726cc..67cf54582 100644 --- a/src/namestore/test_namestore_api_lookup_private.c +++ b/src/namestore/test_namestore_api_lookup_private.c @@ -38,9 +38,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -91,7 +91,7 @@ end (void *cls) static void lookup_it (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -187,8 +187,9 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; rd.record_type = TEST_RECORD_TYPE; diff --git a/src/namestore/test_namestore_api_lookup_public.c b/src/namestore/test_namestore_api_lookup_public.c index 039c7cbf6..5e3e7bbd8 100644 --- a/src/namestore/test_namestore_api_lookup_public.c +++ b/src/namestore/test_namestore_api_lookup_public.c @@ -42,9 +42,9 @@ static struct GNUNET_NAMECACHE_Handle *nch; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -163,7 +163,7 @@ put_cont (void *cls, int32_t success, const char *emsg) { const char *name = cls; struct GNUNET_HashCode derived_hash; - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; + struct GNUNET_IDENTITY_PublicKey pubkey; nsqe = NULL; GNUNET_assert (NULL != cls); @@ -173,8 +173,8 @@ put_cont (void *cls, int32_t success, const char *emsg) (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); /* Create derived hash */ - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); GNUNET_GNSRECORD_query_from_public_key (&pubkey, name, &derived_hash); ncqe = GNUNET_NAMECACHE_lookup_block (nch, &derived_hash, @@ -193,9 +193,10 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us + 1000000000; rd.record_type = TEST_RECORD_TYPE; diff --git a/src/namestore/test_namestore_api_lookup_shadow.c b/src/namestore/test_namestore_api_lookup_shadow.c index d399d903a..79fa4c9c6 100644 --- a/src/namestore/test_namestore_api_lookup_shadow.c +++ b/src/namestore/test_namestore_api_lookup_shadow.c @@ -44,9 +44,9 @@ static struct GNUNET_NAMECACHE_Handle *nch; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -195,7 +195,7 @@ put_cont (void *cls, int32_t success, const char *emsg) { const char *name = cls; struct GNUNET_HashCode derived_hash; - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; + struct GNUNET_IDENTITY_PublicKey pubkey; nsqe = NULL; GNUNET_assert (NULL != cls); @@ -205,8 +205,8 @@ put_cont (void *cls, int32_t success, const char *emsg) (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); /* Create derived hash */ - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); GNUNET_GNSRECORD_query_from_public_key (&pubkey, name, &derived_hash); @@ -228,9 +228,10 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us + 1000000000; rd.record_type = TEST_RECORD_TYPE; rd.data_size = TEST_RECORD_DATALEN; diff --git a/src/namestore/test_namestore_api_lookup_shadow_filter.c b/src/namestore/test_namestore_api_lookup_shadow_filter.c index 40dbeb90f..4fc197750 100644 --- a/src/namestore/test_namestore_api_lookup_shadow_filter.c +++ b/src/namestore/test_namestore_api_lookup_shadow_filter.c @@ -48,9 +48,9 @@ static struct GNUNET_SCHEDULER_Task *endbadly_task; static struct GNUNET_SCHEDULER_Task *delayed_lookup_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -66,7 +66,7 @@ static struct GNUNET_TIME_Absolute record_expiration; static struct GNUNET_HashCode derived_hash; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static void @@ -267,8 +267,8 @@ put_cont (void *cls, int32_t success, const char *emsg) (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); /* Create derived hash */ - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); GNUNET_GNSRECORD_query_from_public_key (&pubkey, TEST_NAME, &derived_hash); if (0 == GNUNET_TIME_absolute_get_remaining (record_expiration).rel_value_us) @@ -297,9 +297,10 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); record_expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), EXPIRATION); diff --git a/src/namestore/test_namestore_api_monitoring.c b/src/namestore/test_namestore_api_monitoring.c index 3f1be1403..df0c38608 100644 --- a/src/namestore/test_namestore_api_monitoring.c +++ b/src/namestore/test_namestore_api_monitoring.c @@ -37,9 +37,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneMonitor *zm; @@ -133,7 +133,7 @@ end (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -273,7 +273,8 @@ run (void *cls, struct GNUNET_TESTING_Peer *peer) { res = 1; - GNUNET_CRYPTO_ecdsa_key_create (&privkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); /* Start monitoring */ zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, &privkey, @@ -304,7 +305,8 @@ run (void *cls, return; } - GNUNET_CRYPTO_ecdsa_key_create (&privkey2); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 3\n"); diff --git a/src/namestore/test_namestore_api_monitoring_existing.c b/src/namestore/test_namestore_api_monitoring_existing.c index 728fcc25e..366f5739f 100644 --- a/src/namestore/test_namestore_api_monitoring_existing.c +++ b/src/namestore/test_namestore_api_monitoring_existing.c @@ -38,9 +38,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneMonitor *zm; @@ -129,7 +129,7 @@ end (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -302,8 +302,10 @@ run (void *cls, struct GNUNET_TESTING_Peer *peer) { res = 1; - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_create (&privkey2); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); cfg = mycfg; GNUNET_SCHEDULER_add_shutdown (&end, diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c index e575821e8..b6254e531 100644 --- a/src/namestore/test_namestore_api_remove.c +++ b/src/namestore/test_namestore_api_remove.c @@ -39,9 +39,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -158,9 +158,10 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); removed = GNUNET_NO; diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c index 75e1cc3ed..e66992909 100644 --- a/src/namestore/test_namestore_api_remove_not_existing_record.c +++ b/src/namestore/test_namestore_api_remove_not_existing_record.c @@ -38,9 +38,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -132,8 +132,9 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); diff --git a/src/namestore/test_namestore_api_store.c b/src/namestore/test_namestore_api_store.c index 9223b56a3..e0b7daa5d 100644 --- a/src/namestore/test_namestore_api_store.c +++ b/src/namestore/test_namestore_api_store.c @@ -39,9 +39,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -113,8 +113,9 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, &pubkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; diff --git a/src/namestore/test_namestore_api_store_update.c b/src/namestore/test_namestore_api_store_update.c index 7a5a69a6c..5c169734a 100644 --- a/src/namestore/test_namestore_api_store_update.c +++ b/src/namestore/test_namestore_api_store_update.c @@ -48,9 +48,9 @@ static struct GNUNET_NAMECACHE_Handle *nch; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; static int res; @@ -246,9 +246,10 @@ run (void *cls, endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + memset (&privkey, 0, sizeof (privkey)); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); rd.flags = GNUNET_GNSRECORD_RF_NONE; rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us + 1000000000; rd.record_type = TEST_RECORD_TYPE; @@ -291,7 +292,7 @@ main (int argc, SETUP_CFG (plugin_name, cfg_name); res = 1; if (0 != - GNUNET_TESTING_peer_run ("test-namestore-api-store-update", + GNUNET_TESTING_peer_run ("test--store-update", cfg_name, &run, NULL)) diff --git a/src/namestore/test_namestore_api_zone_iteration.c b/src/namestore/test_namestore_api_zone_iteration.c index 5d02b9e49..55ca901e2 100644 --- a/src/namestore/test_namestore_api_zone_iteration.c +++ b/src/namestore/test_namestore_api_zone_iteration.c @@ -37,9 +37,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneIterator *zi; @@ -142,7 +142,7 @@ fail_cb (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -331,7 +331,7 @@ create_record (unsigned int count) */ static void empty_zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -362,34 +362,11 @@ empty_zone_proc (void *cls, static void empty_zone_end (void *cls) { - char *hostkey_file; - zi = NULL; - GNUNET_asprintf (&hostkey_file, - "zonefiles%s%s", - DIR_SEPARATOR_STR, - "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using zonekey file `%s' \n", - hostkey_file); - GNUNET_assert (GNUNET_SYSERR != - GNUNET_CRYPTO_ecdsa_key_from_file (hostkey_file, - GNUNET_YES, - &privkey)); - GNUNET_free (hostkey_file); - - GNUNET_asprintf (&hostkey_file, - "zonefiles%s%s", - DIR_SEPARATOR_STR, - "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using zonekey file `%s' \n", - hostkey_file); - GNUNET_assert (GNUNET_SYSERR != - GNUNET_CRYPTO_ecdsa_key_from_file (hostkey_file, - GNUNET_YES, - &privkey2)); - GNUNET_free (hostkey_file); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); diff --git a/src/namestore/test_namestore_api_zone_iteration_nick.c b/src/namestore/test_namestore_api_zone_iteration_nick.c index 4e54a05d2..c203a63a6 100644 --- a/src/namestore/test_namestore_api_zone_iteration_nick.c +++ b/src/namestore/test_namestore_api_zone_iteration_nick.c @@ -38,9 +38,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneIterator *zi; @@ -153,7 +153,7 @@ zone_proc_end (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -345,7 +345,7 @@ nick_1_cont (void *cls, int32_t success, const char *emsg) */ static void empty_zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -379,8 +379,10 @@ empty_zone_end (void *cls) struct GNUNET_GNSRECORD_Data rd; zi = NULL; - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_create (&privkey2); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); memset (&rd, 0, sizeof(rd)); rd.data = ZONE_NICK_1; diff --git a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c index 30920713f..70097a69e 100644 --- a/src/namestore/test_namestore_api_zone_iteration_specific_zone.c +++ b/src/namestore/test_namestore_api_zone_iteration_specific_zone.c @@ -38,9 +38,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneIterator *zi; @@ -124,7 +124,7 @@ fail_cb (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -309,7 +309,7 @@ create_record (unsigned int count) */ static void empty_zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -341,8 +341,10 @@ static void empty_zone_proc_end (void *cls) { zi = NULL; - GNUNET_CRYPTO_ecdsa_key_create (&privkey); - GNUNET_CRYPTO_ecdsa_key_create (&privkey2); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); GNUNET_asprintf (&s_name_1, diff --git a/src/namestore/test_namestore_api_zone_iteration_stop.c b/src/namestore/test_namestore_api_zone_iteration_stop.c index bdcdd1706..71b36ba09 100644 --- a/src/namestore/test_namestore_api_zone_iteration_stop.c +++ b/src/namestore/test_namestore_api_zone_iteration_stop.c @@ -34,9 +34,9 @@ static struct GNUNET_NAMESTORE_Handle *nsh; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey2; +static struct GNUNET_IDENTITY_PrivateKey privkey2; static struct GNUNET_NAMESTORE_ZoneIterator *zi; @@ -112,7 +112,7 @@ fail_cb (void *cls) static void zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -318,7 +318,7 @@ create_record (unsigned int count) */ static void empty_zone_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -347,34 +347,13 @@ empty_zone_proc (void *cls, static void empty_zone_proc_end (void *cls) { - char *hostkey_file; - GNUNET_assert (nsh == cls); zi = NULL; - GNUNET_asprintf (&hostkey_file, - "zonefiles%s%s", - DIR_SEPARATOR_STR, - "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using zonekey file `%s' \n", - hostkey_file); - GNUNET_assert (GNUNET_SYSERR - != GNUNET_CRYPTO_ecdsa_key_from_file (hostkey_file, - GNUNET_YES, - &privkey)); - GNUNET_free (hostkey_file); - GNUNET_asprintf (&hostkey_file, - "zonefiles%s%s", - DIR_SEPARATOR_STR, - "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using zonekey file `%s'\n", - hostkey_file); - GNUNET_assert (GNUNET_SYSERR != - GNUNET_CRYPTO_ecdsa_key_from_file (hostkey_file, - GNUNET_YES, - &privkey2)); - GNUNET_free (hostkey_file); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); + GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record 1\n"); diff --git a/src/namestore/test_namestore_api_zone_to_name.c b/src/namestore/test_namestore_api_zone_to_name.c index 94cc5c285..3fd10e4a1 100644 --- a/src/namestore/test_namestore_api_zone_to_name.c +++ b/src/namestore/test_namestore_api_zone_to_name.c @@ -42,11 +42,11 @@ static struct GNUNET_NAMESTORE_Handle *nsh; static struct GNUNET_SCHEDULER_Task *endbadly_task; -static struct GNUNET_CRYPTO_EcdsaPrivateKey privkey; +static struct GNUNET_IDENTITY_PrivateKey privkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; +static struct GNUNET_IDENTITY_PublicKey pubkey; -static struct GNUNET_CRYPTO_EcdsaPublicKey s_zone_value; +static struct GNUNET_IDENTITY_PublicKey s_zone_value; static char *s_name; @@ -92,7 +92,7 @@ end (void *cls) static void zone_to_name_proc (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, + const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *n, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -203,20 +203,22 @@ run (void *cls, GNUNET_SCHEDULER_add_shutdown (&end, NULL); GNUNET_asprintf (&s_name, "dummy"); - GNUNET_CRYPTO_ecdsa_key_create (&privkey); + privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); + GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); /* get public key */ - GNUNET_CRYPTO_ecdsa_key_get_public (&privkey, - &pubkey); + GNUNET_IDENTITY_key_get_public (&privkey, + &pubkey); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &s_zone_value, sizeof(s_zone_value)); + s_zone_value.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); { struct GNUNET_GNSRECORD_Data rd; rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; - rd.data_size = sizeof(s_zone_value); + rd.data_size = GNUNET_IDENTITY_key_get_length (&s_zone_value); rd.data = &s_zone_value; rd.flags = 0; diff --git a/src/namestore/test_plugin_namestore.c b/src/namestore/test_plugin_namestore.c index 0f9ce97e4..baea0e444 100644 --- a/src/namestore/test_plugin_namestore.c +++ b/src/namestore/test_plugin_namestore.c @@ -85,14 +85,14 @@ load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) static void test_record (void *cls, uint64_t seq, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, + const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { int *idp = cls; int id = *idp; - struct GNUNET_CRYPTO_EcdsaPrivateKey tzone_private_key; + struct GNUNET_IDENTITY_PrivateKey tzone_private_key; char tname[64]; unsigned int trd_count = 1 + (id % 1024); @@ -123,7 +123,7 @@ get_record (struct GNUNET_NAMESTORE_PluginFunctions *nsp, int id) static void put_record (struct GNUNET_NAMESTORE_PluginFunctions *nsp, int id) { - struct GNUNET_CRYPTO_EcdsaPrivateKey zone_private_key; + struct GNUNET_IDENTITY_PrivateKey zone_private_key; char label[64]; unsigned int rd_count = 1 + (id % 1024); struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; diff --git a/src/namestore/test_plugin_rest_namestore.sh b/src/namestore/test_plugin_rest_namestore.sh index 12a7fa50c..8a45cebf5 100755 --- a/src/namestore/test_plugin_rest_namestore.sh +++ b/src/namestore/test_plugin_rest_namestore.sh @@ -84,14 +84,15 @@ gnunet-identity -C $TEST_ID -c test_namestore_api.conf test="$(gnunet-namestore -D -z $TEST_ID -c test_namestore_api.conf)" name=$TEST_ID public="$(gnunet-identity -d -c test_namestore_api.conf | grep $TEST_ID | awk 'NR==1{print $3}')" -gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf +echo "$name $public" +valgrind gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf #curl_get "${namestore_link}" "HTTP/1.1 200 OK" curl_get "${namestore_link}/$name" "HTTP/1.1 200 OK" curl_get "${namestore_link}/$public" "error" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf #Test POST with NAME -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204 No Content" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204 No Content" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 # invalid values @@ -106,29 +107,29 @@ curl_post "${namestore_link}/$name" '{"data": [{"record_type":"PKEY", "expiratio gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 #expirations -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"0d","private": false, "relative_expiration": true, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"0d","private": false, "relative_expiration": true, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"10000d","private": false, "relative_expiration": true, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"10000d","private": false, "relative_expiration": true, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "HTTP/1.1 204" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"now","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "error" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"now","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "error" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time_missing":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "error" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time_missing":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":"test_entry"}' "error" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 #record_name -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":""}' "error" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name":""}' "error" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 -curl_post "${namestore_link}/$name" '{"data": [{"value":"HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name_missing":"test_entry"}' "error" +curl_post "${namestore_link}/$name" '{"data": [{"value":"000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8", "record_type":"PKEY", "expiration_time":"1d","private": false, "relative_expiration": false, "supplemental": false, "shadow": false}],"record_name_missing":"test_entry"}' "error" gnunet-namestore -z $name -d -n "test_entry" -c test_namestore_api.conf > /dev/null 2>&1 #Test DELETE -gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf +gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf curl_delete "${namestore_link}/$name/test_entry" "HTTP/1.1 204" curl_delete "${namestore_link}/$name/test_entry" "error" -gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "HVX38H2CB7WJM0WCPWT9CFX6GASMYJVR65RN75SJSSKAYVYXHMRG" -t "PKEY" -c test_namestore_api.conf +gnunet-namestore -z $name -p -a -n "test_entry" -e "1d" -V "000G006WVZ8HQ5YTVFNX09HK0VJVVQ9ZCBYDSCH3ERT04N5ZRBKEB82EP8" -t "PKEY" -c test_namestore_api.conf curl_delete "${namestore_link}/$public/test_entry" "error" gnunet-arm -e -c test_namestore_api.conf diff --git a/src/nse/gnunet-nse-profiler.c b/src/nse/gnunet-nse-profiler.c index 81a16b245..f653a716e 100644 --- a/src/nse/gnunet-nse-profiler.c +++ b/src/nse/gnunet-nse-profiler.c @@ -317,7 +317,7 @@ handle_estimate (void *cls, } size = GNUNET_snprintf (output_buffer, sizeof(output_buffer), - "%p %llu %llu %f %f %f\n", + "%p %u %llu %f %f %f\n", peer, peers_running, (unsigned long long) timestamp.abs_value_us, diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 739249a93..987c7c3a0 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c @@ -338,9 +338,9 @@ print_address (void *cls, ar->pc = pc; ar->expiration = expiration; GNUNET_asprintf (&ar->result, - "%s:%u:%u", + "%s:%lu:%u", address->transport_name, - address->address_length, + (unsigned long) address->address_length, address->local_info); ar->atsc = GNUNET_TRANSPORT_address_to_string (cfg, address, diff --git a/src/peerinfo-tool/plugin_rest_peerinfo.c b/src/peerinfo-tool/plugin_rest_peerinfo.c index 99cec7e58..4bbc7442e 100644 --- a/src/peerinfo-tool/plugin_rest_peerinfo.c +++ b/src/peerinfo-tool/plugin_rest_peerinfo.c @@ -554,9 +554,9 @@ print_address (void *cls, ar->pc = pc; ar->expiration = expiration; GNUNET_asprintf (&ar->result, - "%s:%u:%u", + "%s:%lu:%u", address->transport_name, - address->address_length, + (unsigned long) address->address_length, address->local_info); ar->atsc = GNUNET_TRANSPORT_address_to_string (cfg, address, diff --git a/src/pq/pq.c b/src/pq/pq.c index eca097e58..e9c960e33 100644 --- a/src/pq/pq.c +++ b/src/pq/pq.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2014, 2015, 2016, 2017, 2019 GNUnet e.V. + Copyright (C) 2014, 2015, 2016, 2017, 2019, 2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -27,14 +27,7 @@ #include "platform.h" #include "pq.h" -/** - * Execute a prepared statement. - * - * @param db database handle - * @param name name of the prepared statement - * @param params parameters to the statement - * @return postgres result - */ + PGresult * GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, const char *name, @@ -120,12 +113,6 @@ GNUNET_PQ_exec_prepared (struct GNUNET_PQ_Context *db, } -/** - * Free all memory that was allocated in @a rs during - * #GNUNET_PQ_extract_result(). - * - * @param rs reult specification to clean up - */ void GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) { @@ -136,17 +123,6 @@ GNUNET_PQ_cleanup_result (struct GNUNET_PQ_ResultSpec *rs) } -/** - * Extract results from a query result according to the given - * specification. - * - * @param result result to process - * @param[in,out] rs result specification to extract for - * @param row row from the result to extract - * @return - * #GNUNET_YES if all results could be extracted - * #GNUNET_SYSERR if a result was invalid (non-existing field) - */ int GNUNET_PQ_extract_result (PGresult *result, struct GNUNET_PQ_ResultSpec *rs, @@ -160,6 +136,23 @@ GNUNET_PQ_extract_result (PGresult *result, int ret; spec = &rs[i]; + if (spec->is_nullable) + { + int fnum; + + fnum = PQfnumber (result, + spec->fname); + if (PQgetisnull (result, + row, + fnum)) + { + if (NULL != spec->is_null) + *spec->is_null = true; + continue; + } + if (NULL != spec->is_null) + *spec->is_null = false; + } ret = spec->conv (spec->cls, result, row, diff --git a/src/pq/pq_eval.c b/src/pq/pq_eval.c index 5bcf8ca0e..8d8b5b0f2 100644 --- a/src/pq/pq_eval.c +++ b/src/pq/pq_eval.c @@ -263,6 +263,7 @@ GNUNET_PQ_eval_prepared_singleton_select (struct GNUNET_PQ_Context *db, { PGresult *result; enum GNUNET_DB_QueryStatus qs; + int ntuples; result = GNUNET_PQ_exec_prepared (db, statement_name, @@ -277,12 +278,13 @@ GNUNET_PQ_eval_prepared_singleton_select (struct GNUNET_PQ_Context *db, PQclear (result); return qs; } - if (0 == PQntuples (result)) + ntuples = PQntuples (result); + if (0 == ntuples) { PQclear (result); return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; } - if (1 != PQntuples (result)) + if (1 != ntuples) { /* more than one result, but there must be at most one */ GNUNET_break (0); diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index a36848f3a..cee84d203 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -27,6 +27,56 @@ #include "gnunet_pq_lib.h" +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param[out] param_values SQL data to set + * @param[out] param_lengths SQL length data to set + * @param[out] param_formats SQL format data to set + * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays + * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() + * @param scratch_length number of entries left in @a scratch + * @return -1 on error, number of offsets used in @a scratch otherwise + */ +static int +qconv_null (void *cls, + const void *data, + size_t data_len, + void *param_values[], + int param_lengths[], + int param_formats[], + unsigned int param_length, + void *scratch[], + unsigned int scratch_length) +{ + (void) scratch; + (void) scratch_length; + (void) data; + (void) data_len; + GNUNET_break (NULL == cls); + if (1 != param_length) + return -1; + param_values[0] = NULL; + param_lengths[0] = 0; + param_formats[0] = 1; + return 0; +} + + +struct GNUNET_PQ_QueryParam +GNUNET_PQ_query_param_null (void) +{ + struct GNUNET_PQ_QueryParam res = { + &qconv_null, NULL, NULL, 0, 1 + }; + + return res; +} + + /** * Function called to convert input argument into SQL parameters. * @@ -64,33 +114,23 @@ qconv_fixed (void *cls, } -/** - * Generate query parameter for a buffer @a ptr of - * @a ptr_size bytes. - * - * @param ptr pointer to the query parameter to pass - * @oaran ptr_size number of bytes in @a ptr - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_fixed_size (const void *ptr, size_t ptr_size) { - struct GNUNET_PQ_QueryParam res = - { &qconv_fixed, NULL, ptr, ptr_size, 1 }; + struct GNUNET_PQ_QueryParam res = { + &qconv_fixed, NULL, ptr, ptr_size, 1 + }; return res; } -/** - * Generate query parameter for a string. - * - * @param ptr pointer to the string query parameter to pass - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_string (const char *ptr) { - return GNUNET_PQ_query_param_fixed_size (ptr, strlen (ptr)); + return GNUNET_PQ_query_param_fixed_size (ptr, + strlen (ptr)); } @@ -137,11 +177,6 @@ qconv_uint16 (void *cls, } -/** - * Generate query parameter for an uint16_t in host byte order. - * - * @param x pointer to the query parameter to pass - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint16 (const uint16_t *x) { @@ -195,11 +230,6 @@ qconv_uint32 (void *cls, } -/** - * Generate query parameter for an uint32_t in host byte order. - * - * @param x pointer to the query parameter to pass - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint32 (const uint32_t *x) { @@ -253,11 +283,6 @@ qconv_uint64 (void *cls, } -/** - * Generate query parameter for an uint64_t in host byte order. - * - * @param x pointer to the query parameter to pass - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_uint64 (const uint64_t *x) { @@ -310,13 +335,6 @@ qconv_rsa_public_key (void *cls, } -/** - * Generate query parameter for an RSA public key. The - * database must contain a BLOB type in the respective position. - * - * @param x the query parameter to pass - * @return array entry for the query parameters to use - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x) @@ -370,13 +388,6 @@ qconv_rsa_signature (void *cls, } -/** - * Generate query parameter for an RSA signature. The - * database must contain a BLOB type in the respective position. - * - * @param x the query parameter to pass - * @return array entry for the query parameters to use - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) { @@ -432,13 +443,6 @@ qconv_rel_time (void *cls, } -/** - * Generate query parameter for a relative time value. - * The database must store a 64-bit integer. - * - * @param x pointer to the query parameter to pass - * @return array entry for the query parameters to use - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_relative_time (const struct GNUNET_TIME_Relative *x) { @@ -494,29 +498,17 @@ qconv_abs_time (void *cls, } -/** - * Generate query parameter for an absolute time value. - * The database must store a 64-bit integer. - * - * @param x pointer to the query parameter to pass - * @return array entry for the query parameters to use - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) { - struct GNUNET_PQ_QueryParam res = - { &qconv_abs_time, NULL, x, sizeof(*x), 1 }; + struct GNUNET_PQ_QueryParam res = { + &qconv_abs_time, NULL, x, sizeof(*x), 1 + }; return res; } -/** - * Generate query parameter for an absolute time value. - * The database must store a 64-bit integer. - * - * @param x pointer to the query parameter to pass - */ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x) diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index f764593b0..546822e45 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2014, 2015, 2016 GNUnet e.V. + Copyright (C) 2014, 2015, 2016, 2020 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -27,6 +27,19 @@ #include "gnunet_pq_lib.h" +struct GNUNET_PQ_ResultSpec +GNUNET_PQ_result_spec_allow_null (struct GNUNET_PQ_ResultSpec rs, + bool *is_null) +{ + struct GNUNET_PQ_ResultSpec rsr; + + rsr = rs; + rsr.is_nullable = true; + rsr.is_null = is_null; + return rsr; +} + + /** * Function called to clean up memory allocated * by a #GNUNET_PQ_ResultConverter. @@ -112,14 +125,6 @@ extract_varsize_blob (void *cls, } -/** - * Variable-size result expected. - * - * @param name name of the field in the table - * @param[out] dst where to store the result, allocated - * @param[out] sptr where to store the size of @a dst - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_variable_size (const char *name, void **dst, @@ -196,14 +201,6 @@ extract_fixed_blob (void *cls, } -/** - * Fixed-size result expected. - * - * @param name name of the field in the table - * @param[out] dst where to store the result - * @param dst_size number of bytes in @a dst - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_fixed_size (const char *name, void *dst, @@ -301,13 +298,6 @@ clean_rsa_public_key (void *cls, } -/** - * RSA public key expected. - * - * @param name name of the field in the table - * @param[out] rsa where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_rsa_public_key (const char *name, struct GNUNET_CRYPTO_RsaPublicKey **rsa) @@ -405,13 +395,6 @@ clean_rsa_signature (void *cls, } -/** - * RSA signature expected. - * - * @param name name of the field in the table - * @param[out] sig where to store the result; - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_rsa_signature (const char *name, struct GNUNET_CRYPTO_RsaSignature **sig) @@ -509,13 +492,6 @@ clean_string (void *cls, } -/** - * 0-terminated string expected. - * - * @param name name of the field in the table - * @param[out] dst where to store the result, allocated - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_string (const char *name, char **dst) @@ -595,13 +571,6 @@ extract_rel_time (void *cls, } -/** - * Relative time expected. - * - * @param name name of the field in the table - * @param[out] at where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_relative_time (const char *name, struct GNUNET_TIME_Relative *rt) @@ -685,13 +654,6 @@ extract_abs_time (void *cls, } -/** - * Absolute time expected. - * - * @param name name of the field in the table - * @param[out] at where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time (const char *name, struct GNUNET_TIME_Absolute *at) @@ -706,13 +668,6 @@ GNUNET_PQ_result_spec_absolute_time (const char *name, } -/** - * Absolute time in network byte order expected. - * - * @param name name of the field in the table - * @param[out] at where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_absolute_time_nbo (const char *name, struct GNUNET_TIME_AbsoluteNBO *at) @@ -786,13 +741,6 @@ extract_uint16 (void *cls, } -/** - * uint16_t expected. - * - * @param name name of the field in the table - * @param[out] u16 where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint16 (const char *name, uint16_t *u16) @@ -869,13 +817,6 @@ extract_uint32 (void *cls, } -/** - * uint32_t expected. - * - * @param name name of the field in the table - * @param[out] u32 where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint32 (const char *name, uint32_t *u32) @@ -952,22 +893,16 @@ extract_uint64 (void *cls, } -/** - * uint64_t expected. - * - * @param name name of the field in the table - * @param[out] u64 where to store the result - * @return array entry for the result specification to use - */ struct GNUNET_PQ_ResultSpec GNUNET_PQ_result_spec_uint64 (const char *name, uint64_t *u64) { - struct GNUNET_PQ_ResultSpec res = - { &extract_uint64, + struct GNUNET_PQ_ResultSpec res = { + &extract_uint64, NULL, NULL, - (void *) u64, sizeof(*u64), (name), NULL }; + (void *) u64, sizeof(*u64), (name), NULL + }; return res; } diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index b09354af8..e588da45d 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -47,10 +47,11 @@ postgres_prepare (struct GNUNET_PQ_Context *db) ",u16" ",u32" ",u64" + ",unn" ") VALUES " "($1, $2, $3, $4, $5, $6," - "$7, $8, $9);", - 9), + "$7, $8, $9, $10);", + 10), GNUNET_PQ_make_prepare ("test_select", "SELECT" " pub" @@ -62,6 +63,7 @@ postgres_prepare (struct GNUNET_PQ_Context *db) ",u16" ",u32" ",u64" + ",unn" " FROM test_pq" " ORDER BY abs_time DESC " " LIMIT 1;", @@ -106,7 +108,8 @@ run_queries (struct GNUNET_PQ_Context *db) uint32_t u322; uint64_t u64; uint64_t u642; - + uint64_t uzzz = 42; + priv = GNUNET_CRYPTO_rsa_private_key_create (1024); pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); memset (&hmsg, 42, sizeof(hmsg)); @@ -127,11 +130,13 @@ run_queries (struct GNUNET_PQ_Context *db) GNUNET_PQ_query_param_uint16 (&u16), GNUNET_PQ_query_param_uint32 (&u32), GNUNET_PQ_query_param_uint64 (&u64), + GNUNET_PQ_query_param_null (), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params_select[] = { GNUNET_PQ_query_param_end }; + bool got_null = false; struct GNUNET_PQ_ResultSpec results_select[] = { GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2), GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2), @@ -142,6 +147,9 @@ run_queries (struct GNUNET_PQ_Context *db) GNUNET_PQ_result_spec_uint16 ("u16", &u162), GNUNET_PQ_result_spec_uint32 ("u32", &u322), GNUNET_PQ_result_spec_uint64 ("u64", &u642), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_uint64 ("unn", &uzzz), + &got_null), GNUNET_PQ_result_spec_end }; @@ -197,6 +205,8 @@ run_queries (struct GNUNET_PQ_Context *db) GNUNET_break (16 == u162); GNUNET_break (32 == u322); GNUNET_break (64 == u642); + GNUNET_break (42 == uzzz); + GNUNET_break (got_null); GNUNET_PQ_cleanup_result (results_select); PQclear (result); } @@ -225,6 +235,7 @@ main (int argc, ",u16 INT2 NOT NULL" ",u32 INT4 NOT NULL" ",u64 INT8 NOT NULL" + ",unn INT8" ")"), GNUNET_PQ_EXECUTE_STATEMENT_END }; diff --git a/src/pt/test_gns_vpn.c b/src/pt/test_gns_vpn.c index cf0455477..7b4abaec2 100644 --- a/src/pt/test_gns_vpn.c +++ b/src/pt/test_gns_vpn.c @@ -560,7 +560,7 @@ identity_cb (void *cls, void **ctx, const char *name) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key; + const struct GNUNET_IDENTITY_PrivateKey *zone_key; struct GNUNET_GNSRECORD_Data rd; char *rd_string; char *peername; diff --git a/src/reclaim/Makefile.am b/src/reclaim/Makefile.am index a58127abf..9463f19d9 100644 --- a/src/reclaim/Makefile.am +++ b/src/reclaim/Makefile.am @@ -103,6 +103,7 @@ gnunet_service_reclaim_SOURCES = \ gnunet-service-reclaim_tickets.h gnunet_service_reclaim_LDADD = \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c index b9306b802..cefb66b8f 100644 --- a/src/reclaim/gnunet-reclaim.c +++ b/src/reclaim/gnunet-reclaim.c @@ -152,12 +152,12 @@ static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator; /** * ego private key */ -static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey; +static const struct GNUNET_IDENTITY_PrivateKey *pkey; /** * rp public key */ -static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key; +static struct GNUNET_IDENTITY_PublicKey rp_key; /** * Ticket to consume @@ -261,7 +261,7 @@ store_cont (void *cls, int32_t success, const char *emsg) static void process_attrs (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *presentation) { @@ -346,7 +346,7 @@ ticket_iter (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) aud = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); ref = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd)); tkt = GNUNET_STRINGS_data_to_string_alloc (ticket, @@ -511,7 +511,7 @@ iter_finished (void *cls) static void iter_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr) { struct GNUNET_RECLAIM_AttributeListEntry *le; @@ -653,7 +653,7 @@ cred_iter_finished (void *cls) static void cred_iter_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred) { char *cred_str; @@ -734,7 +734,7 @@ start_process () if ((NULL != rp) && (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (rp, strlen (rp), &rp_key)) ) + GNUNET_IDENTITY_public_key_from_string (rp, &rp_key)) ) { fprintf (stderr, "%s is not a public key!\n", rp); cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index d2cdc62a2..0774fecea 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -110,7 +110,7 @@ struct Iterator /** * Key of the zone we are iterating over. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Namestore iterator @@ -266,7 +266,7 @@ struct AttributeDeleteHandle /** * Identity */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** @@ -334,12 +334,12 @@ struct AttributeStoreHandle /** * Identity */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Identity pubkey */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; + struct GNUNET_IDENTITY_PublicKey identity_pkey; /** * QueueEntry @@ -862,7 +862,7 @@ handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm) */ static void consume_result_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, int32_t success, @@ -1082,7 +1082,7 @@ handle_attribute_store_message (void *cls, ash->r_id = ntohl (sam->id); ash->identity = sam->identity; ash->exp.rel_value_us = GNUNET_ntohll (sam->exp); - GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey); + GNUNET_IDENTITY_key_get_public (&sam->identity, &ash->identity_pkey); GNUNET_SERVICE_client_continue (idp->client); ash->client = idp; @@ -1157,7 +1157,7 @@ cred_error (void *cls) */ static void cred_add_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1266,7 +1266,7 @@ handle_credential_store_message (void *cls, ash->r_id = ntohl (sam->id); ash->identity = sam->identity; ash->exp.rel_value_us = GNUNET_ntohll (sam->exp); - GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey); + GNUNET_IDENTITY_key_get_public (&sam->identity, &ash->identity_pkey); GNUNET_SERVICE_client_continue (idp->client); ash->client = idp; @@ -1311,7 +1311,7 @@ send_delete_response (struct AttributeDeleteHandle *adh, int32_t success) */ static void ticket_iter (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1739,7 +1739,7 @@ attr_iter_error (void *cls) */ static void attr_iter_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1764,7 +1764,7 @@ attr_iter_cb (void *cls, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT); arm->id = htonl (ai->request_id); arm->attr_len = htons (rd->data_size); - GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); + GNUNET_IDENTITY_key_get_public (zone, &arm->identity); data_tmp = (char *) &arm[1]; GNUNET_memcpy (data_tmp, rd->data, rd->data_size); GNUNET_MQ_send (ai->client->mq, env); @@ -1923,7 +1923,7 @@ cred_iter_error (void *cls) */ static void cred_iter_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1948,7 +1948,7 @@ cred_iter_cb (void *cls, GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT); arm->id = htonl (ai->request_id); arm->credential_len = htons (rd->data_size); - GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity); + GNUNET_IDENTITY_key_get_public (zone, &arm->identity); data_tmp = (char *) &arm[1]; GNUNET_memcpy (data_tmp, rd->data, rd->data_size); diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index 4dd8100f9..0b1730bec 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c @@ -86,12 +86,12 @@ struct RECLAIM_TICKETS_ConsumeHandle /** * Audience Key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Audience Key */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; + struct GNUNET_IDENTITY_PublicKey identity_pub; /** * Lookup DLL @@ -180,7 +180,7 @@ struct TicketIssueHandle /** * Issuer Key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Ticket to issue @@ -263,7 +263,7 @@ struct RECLAIM_TICKETS_RevokeHandle /** * Issuer Key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Callback @@ -490,7 +490,7 @@ rvk_ticket_update_finished (void *cls) */ static void rvk_ticket_update (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -665,7 +665,7 @@ move_attr_finished (void *cls, int32_t success, const char *emsg) */ static void rvk_move_attr_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -850,7 +850,7 @@ remove_ticket_cont (void *cls, int32_t success, const char *emsg) */ static void revoke_attrs_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -913,7 +913,7 @@ rvk_attrs_err_cb (void *cls) */ struct RECLAIM_TICKETS_RevokeHandle * RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls) { @@ -925,7 +925,7 @@ RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket, rvk->cb_cls = cb_cls; rvk->identity = *identity; rvk->ticket = *ticket; - GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity); + GNUNET_IDENTITY_key_get_public (&rvk->identity, &rvk->ticket.identity); /** Get shared attributes **/ label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(ticket->rnd)); @@ -1184,7 +1184,7 @@ lookup_authz_cb (void *cls, * @return handle to the operation */ struct RECLAIM_TICKETS_ConsumeHandle * -RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, +RECLAIM_TICKETS_consume (const struct GNUNET_IDENTITY_PrivateKey *id, const struct GNUNET_RECLAIM_Ticket *ticket, RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls) @@ -1195,7 +1195,7 @@ RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle); cth->identity = *id; - GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub); + GNUNET_IDENTITY_key_get_public (&cth->identity, &cth->identity_pub); cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList); cth->presentations = GNUNET_new (struct GNUNET_RECLAIM_PresentationList); cth->ticket = *ticket; @@ -1453,7 +1453,7 @@ filter_tickets_error_cb (void *cls) */ static void filter_tickets_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1489,7 +1489,7 @@ filter_tickets_cb (void *cls, // cmp audience if (0 == memcmp (&tih->ticket.audience, &ticket->audience, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) + sizeof(struct GNUNET_IDENTITY_PublicKey))) { tih->ticket = *ticket; continue; @@ -1602,7 +1602,7 @@ filter_tickets_finished_cb (void *cls) { struct TicketIssueHandle *tih = cls; - GNUNET_CRYPTO_ecdsa_key_get_public (&tih->identity, &tih->ticket.identity); + GNUNET_IDENTITY_key_get_public (&tih->identity, &tih->ticket.identity); GNUNET_RECLAIM_id_generate (&tih->ticket.rnd); issue_ticket (tih); } @@ -1620,9 +1620,9 @@ filter_tickets_finished_cb (void *cls) * FIXME: Return handle?? */ void -RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, +RECLAIM_TICKETS_issue (const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, + const struct GNUNET_IDENTITY_PublicKey *audience, RECLAIM_TICKETS_TicketResult cb, void *cb_cls) { @@ -1680,7 +1680,7 @@ cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter) */ static void collect_tickets_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) @@ -1765,7 +1765,7 @@ RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter) */ struct RECLAIM_TICKETS_Iterator * RECLAIM_TICKETS_iteration_start ( - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, RECLAIM_TICKETS_TicketIter cb, void *cb_cls) { diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h b/src/reclaim/gnunet-service-reclaim_tickets.h index 0dd790fc7..9c31a6143 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.h +++ b/src/reclaim/gnunet-service-reclaim_tickets.h @@ -138,7 +138,7 @@ typedef void (*RECLAIM_TICKETS_TicketResult) ( */ typedef void (*RECLAIM_TICKETS_ConsumeCallback) ( void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_AttributeList *attributes, const struct GNUNET_RECLAIM_PresentationList *presentations, int32_t success, @@ -167,7 +167,7 @@ typedef void (*RECLAIM_TICKETS_RevokeCallback) (void *cls, int32_t success); */ struct RECLAIM_TICKETS_RevokeHandle * RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls); @@ -193,7 +193,7 @@ RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh); * @return handle to the operation */ struct RECLAIM_TICKETS_ConsumeHandle * -RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, +RECLAIM_TICKETS_consume (const struct GNUNET_IDENTITY_PrivateKey *id, const struct GNUNET_RECLAIM_Ticket *ticket, RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls); @@ -220,9 +220,9 @@ RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth); * FIXME: Return handle?? */ void -RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, +RECLAIM_TICKETS_issue (const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, + const struct GNUNET_IDENTITY_PublicKey *audience, RECLAIM_TICKETS_TicketResult cb, void *cb_cls); @@ -255,7 +255,7 @@ RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter); */ struct RECLAIM_TICKETS_Iterator * RECLAIM_TICKETS_iteration_start ( - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, RECLAIM_TICKETS_TicketIter cb, void *cb_cls); diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c index b307a358c..c6d56e02d 100644 --- a/src/reclaim/oidc_helper.c +++ b/src/reclaim/oidc_helper.c @@ -154,10 +154,12 @@ fix_base64 (char *str) replace_char (str, '/', '_'); } + static json_t* -generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, - const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_RECLAIM_PresentationList *presentations) +generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key, + const struct GNUNET_RECLAIM_AttributeList *attrs, + const struct + GNUNET_RECLAIM_PresentationList *presentations) { struct GNUNET_RECLAIM_AttributeListEntry *le; struct GNUNET_RECLAIM_PresentationListEntry *ple; @@ -180,7 +182,7 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, subject = GNUNET_STRINGS_data_to_string_alloc (sub_key, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); body = json_object (); aggr_names = json_object (); aggr_sources = json_object (); @@ -206,7 +208,8 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, ple->presentation->data, ple->presentation->data_size); json_object_set_new (aggr_sources_jwt, - GNUNET_RECLAIM_presentation_number_to_typename (ple->presentation->type), + GNUNET_RECLAIM_presentation_number_to_typename ( + ple->presentation->type), json_string (pres_val_str) ); json_object_set_new (aggr_sources, source_name, aggr_sources_jwt); GNUNET_free (pres_val_str); @@ -286,6 +289,7 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, return body; } + /** * Generate userinfo JSON as string * @@ -295,14 +299,15 @@ generate_userinfo_json(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, * @return Userinfo JSON */ char * -OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, +OIDC_generate_userinfo (const struct GNUNET_IDENTITY_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_RECLAIM_PresentationList *presentations) + const struct + GNUNET_RECLAIM_PresentationList *presentations) { char *body_str; - json_t* body = generate_userinfo_json (sub_key, - attrs, - presentations); + json_t*body = generate_userinfo_json (sub_key, + attrs, + presentations); body_str = json_dumps (body, JSON_INDENT (0) | JSON_COMPACT); json_decref (body); return body_str; @@ -321,10 +326,11 @@ OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, * @return a new base64-encoded JWT string. */ char * -OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, +OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key, + const struct GNUNET_IDENTITY_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_RECLAIM_PresentationList *presentations, + const struct + GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key) @@ -356,11 +362,11 @@ OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, subject = GNUNET_STRINGS_data_to_string_alloc (sub_key, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); audience = GNUNET_STRINGS_data_to_string_alloc (aud_key, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); header = create_jwt_header (); // aud REQUIRED public key client_id must be there @@ -438,10 +444,11 @@ OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, * @return a new authorization code (caller must free) */ char * -OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, +OIDC_build_authz_code (const struct GNUNET_IDENTITY_PrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_AttributeList *attrs, - const struct GNUNET_RECLAIM_PresentationList *presentations, + const struct + GNUNET_RECLAIM_PresentationList *presentations, const char *nonce_str, const char *code_challenge) { @@ -525,7 +532,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, // Get length code_payload_len = sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + payload_len + sizeof(struct - GNUNET_CRYPTO_EcdsaSignature); + GNUNET_IDENTITY_Signature); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Length of data to encode: %lu\n", code_payload_len); @@ -544,10 +551,10 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, buf_ptr += payload_len; // Sign and store signature if (GNUNET_SYSERR == - GNUNET_CRYPTO_ecdsa_sign_ (issuer, - purpose, - (struct GNUNET_CRYPTO_EcdsaSignature *) - buf_ptr)) + GNUNET_IDENTITY_sign_ (issuer, + purpose, + (struct GNUNET_IDENTITY_Signature *) + buf_ptr)) { GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to sign code\n"); @@ -576,7 +583,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int -OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, +OIDC_parse_authz_code (const struct GNUNET_IDENTITY_PublicKey *audience, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, @@ -593,7 +600,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, char *code_challenge; char *code_verifier_hash; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; - struct GNUNET_CRYPTO_EcdsaSignature *signature; + struct GNUNET_IDENTITY_Signature *signature; uint32_t code_challenge_len; uint32_t attrs_ser_len; uint32_t pres_ser_len; @@ -609,7 +616,7 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, (void **) &code_payload); if (code_payload_len < sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof(struct OIDC_Parameters) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature)) + + sizeof(struct GNUNET_IDENTITY_Signature)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Authorization code malformed\n"); GNUNET_free (code_payload); @@ -620,10 +627,10 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, plaintext_len = code_payload_len; plaintext_len -= sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose); ptr = (char *) &purpose[1]; - plaintext_len -= sizeof(struct GNUNET_CRYPTO_EcdsaSignature); + plaintext_len -= sizeof(struct GNUNET_IDENTITY_Signature); plaintext = ptr; ptr += plaintext_len; - signature = (struct GNUNET_CRYPTO_EcdsaSignature *) ptr; + signature = (struct GNUNET_IDENTITY_Signature *) ptr; params = (struct OIDC_Parameters *) plaintext; // cmp code_challenge code_verifier @@ -684,10 +691,11 @@ OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, return GNUNET_SYSERR; } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, - purpose, - signature, - &ticket->identity)) + GNUNET_IDENTITY_signature_verify_ ( + GNUNET_SIGNATURE_PURPOSE_RECLAIM_CODE_SIGN, + purpose, + signature, + &(ticket->identity))) { GNUNET_free (code_payload); if (NULL != *nonce_str) @@ -840,7 +848,8 @@ OIDC_check_scopes_for_claim_request (const char*scopes, } } - } else if (0 == strcmp (attr, scope_variable)) + } + else if (0 == strcmp (attr, scope_variable)) { /** attribute matches requested scope **/ GNUNET_free (scope_variables); diff --git a/src/reclaim/oidc_helper.h b/src/reclaim/oidc_helper.h index 10a6f3d1f..eb1022423 100644 --- a/src/reclaim/oidc_helper.h +++ b/src/reclaim/oidc_helper.h @@ -50,8 +50,8 @@ * @return a new base64-encoded JWT string. */ char* -OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, - const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, +OIDC_generate_id_token (const struct GNUNET_IDENTITY_PublicKey *aud_key, + const struct GNUNET_IDENTITY_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, @@ -71,7 +71,7 @@ OIDC_generate_id_token (const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, * @return a new authorization code (caller must free) */ char* -OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, +OIDC_build_authz_code (const struct GNUNET_IDENTITY_PrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, @@ -93,7 +93,7 @@ OIDC_build_authz_code (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, * @return GNUNET_OK if successful, else GNUNET_SYSERR */ int -OIDC_parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *ecdsa_pub, +OIDC_parse_authz_code (const struct GNUNET_IDENTITY_PublicKey *ecdsa_pub, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, @@ -152,7 +152,7 @@ OIDC_check_scopes_for_claim_request (const char *scopes, * @return Userinfo JSON */ char * -OIDC_generate_userinfo (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, +OIDC_generate_userinfo (const struct GNUNET_IDENTITY_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations); diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c index 5b0bb2b6f..7a8a886bd 100644 --- a/src/reclaim/plugin_rest_openid_connect.c +++ b/src/reclaim/plugin_rest_openid_connect.c @@ -300,7 +300,7 @@ struct OIDC_Variables /** * The RP client public key */ - struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey; + struct GNUNET_IDENTITY_PublicKey client_pkey; /** * The OIDC client id of the RP @@ -411,7 +411,7 @@ struct RequestHandle /** * Pointer to ego private key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; + struct GNUNET_IDENTITY_PrivateKey priv_key; /** * OIDC variables @@ -972,7 +972,7 @@ oidc_ticket_issue_cb (void *cls, (NULL != handle->tld)) { GNUNET_asprintf (&redirect_uri, - "%s.%s/%s?%s=%s&state=%s", + "%s.%s/%s%s%s=%s&state=%s", handle->redirect_prefix, handle->tld, handle->redirect_suffix, @@ -1087,7 +1087,7 @@ oidc_cred_collect_finished_cb (void *cls) */ static void oidc_cred_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred) { struct RequestHandle *handle = cls; @@ -1211,7 +1211,7 @@ attr_in_userinfo_request (struct RequestHandle *handle, */ static void oidc_attr_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr) { struct RequestHandle *handle = cls; @@ -1260,8 +1260,8 @@ code_redirect (void *cls) struct RequestHandle *handle = cls; struct GNUNET_TIME_Absolute current_time; struct GNUNET_TIME_Absolute *relog_time; - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; - struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey; + struct GNUNET_IDENTITY_PublicKey pubkey; + struct GNUNET_IDENTITY_PublicKey ego_pkey; struct GNUNET_HashCode cache_key; char *identity_cookie; @@ -1281,11 +1281,8 @@ code_redirect (void *cls) if (current_time.abs_value_us <= relog_time->abs_value_us) { if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc + GNUNET_IDENTITY_public_key_from_string (handle->oidc ->login_identity, - strlen ( - handle->oidc - ->login_identity), &pubkey)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_COOKIE); @@ -1376,7 +1373,7 @@ lookup_redirect_uri_result (void *cls, char *tmp; char *tmp_key_str; char *pos; - struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone; + struct GNUNET_IDENTITY_PublicKey redirect_zone; handle->gns_op = NULL; if (0 == rd_count) @@ -1608,10 +1605,10 @@ static void tld_iter (void *cls, const char *section, const char *option, const char *value) { struct RequestHandle *handle = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_IDENTITY_PublicKey pkey; if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (value, strlen (value), &pkey)) + GNUNET_IDENTITY_public_key_from_string (value, &pkey)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value); return; @@ -1635,8 +1632,8 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, { struct RequestHandle *handle = cls; struct EgoEntry *tmp_ego; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; + struct GNUNET_IDENTITY_PublicKey pkey; cookie_identity_interpretation (handle); @@ -1664,9 +1661,7 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, } if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id, - strlen ( - handle->oidc->client_id), + GNUNET_IDENTITY_public_key_from_string (handle->oidc->client_id, &handle->oidc->client_pkey)) { handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT); @@ -1682,7 +1677,7 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) { priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego); - GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey); + GNUNET_IDENTITY_key_get_public (priv_key, &pkey); if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) { handle->tld = GNUNET_strdup (tmp_ego->identifier); @@ -1865,7 +1860,7 @@ parse_credentials_post_body (struct RequestHandle *handle, static int check_authorization (struct RequestHandle *handle, - struct GNUNET_CRYPTO_EcdsaPublicKey *cid) + struct GNUNET_IDENTITY_PublicKey *cid) { char *expected_pass; char *received_cid; @@ -1902,7 +1897,7 @@ check_authorization (struct RequestHandle *handle, GNUNET_STRINGS_string_to_data (received_cid, strlen (received_cid), cid, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + sizeof(struct GNUNET_IDENTITY_PublicKey)); GNUNET_free (received_cid); return GNUNET_OK; @@ -1948,7 +1943,7 @@ check_authorization (struct RequestHandle *handle, GNUNET_STRINGS_string_to_data (received_cid, strlen (received_cid), cid, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + sizeof(struct GNUNET_IDENTITY_PublicKey)); GNUNET_free (received_cpw); GNUNET_free (received_cid); @@ -1958,10 +1953,10 @@ check_authorization (struct RequestHandle *handle, const struct EgoEntry * find_ego (struct RequestHandle *handle, - struct GNUNET_CRYPTO_EcdsaPublicKey *test_key) + struct GNUNET_IDENTITY_PublicKey *test_key) { struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; + struct GNUNET_IDENTITY_PublicKey pub_key; for (ego_entry = ego_head; NULL != ego_entry; ego_entry = ego_entry->next) @@ -1992,7 +1987,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, struct GNUNET_RECLAIM_AttributeList *cl = NULL; struct GNUNET_RECLAIM_PresentationList *pl = NULL; struct GNUNET_RECLAIM_Ticket ticket; - struct GNUNET_CRYPTO_EcdsaPublicKey cid; + struct GNUNET_IDENTITY_PublicKey cid; struct GNUNET_HashCode cache_key; struct MHD_Response *resp; char *grant_type; @@ -2145,7 +2140,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, */ static void consume_ticket (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *pres) { @@ -2225,7 +2220,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, char *authorization_type; char *authorization_access_token; const struct EgoEntry *aud_ego; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + const struct GNUNET_IDENTITY_PrivateKey *privkey; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n"); GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, @@ -2349,7 +2344,7 @@ list_ego (void *cls, const char *identifier) { struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { @@ -2362,7 +2357,7 @@ list_ego (void *cls, { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, @@ -2389,7 +2384,7 @@ list_ego (void *cls, /* Add */ ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c index ff11d2a56..022744c82 100644 --- a/src/reclaim/plugin_rest_reclaim.c +++ b/src/reclaim/plugin_rest_reclaim.c @@ -172,7 +172,7 @@ struct RequestHandle /** * Pointer to ego private key */ - struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; + struct GNUNET_IDENTITY_PrivateKey priv_key; /** * Rest connection @@ -440,14 +440,14 @@ ticket_collect (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); value = json_string (tmp); json_object_set_new (json_resource, "issuer", value); GNUNET_free (tmp); tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, sizeof(struct - GNUNET_CRYPTO_EcdsaPublicKey)); + GNUNET_IDENTITY_PublicKey)); value = json_string (tmp); json_object_set_new (json_resource, "audience", value); GNUNET_free (tmp); @@ -465,7 +465,7 @@ add_credential_cont (struct GNUNET_REST_RequestHandle *con_handle, void *cls) { struct RequestHandle *handle = cls; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const struct GNUNET_IDENTITY_PrivateKey *identity_priv; const char *identity; struct EgoEntry *ego_entry; struct GNUNET_RECLAIM_Credential *attribute; @@ -545,7 +545,7 @@ add_credential_cont (struct GNUNET_REST_RequestHandle *con_handle, */ static void cred_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred) { struct RequestHandle *handle = cls; @@ -631,7 +631,7 @@ list_credential_cont (struct GNUNET_REST_RequestHandle *con_handle, void *cls) { struct RequestHandle *handle = cls; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; struct EgoEntry *ego_entry; char *identity; @@ -688,7 +688,7 @@ delete_credential_cont (struct GNUNET_REST_RequestHandle *con_handle, void *cls) { struct RequestHandle *handle = cls; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; struct GNUNET_RECLAIM_Credential attr; struct EgoEntry *ego_entry; char *identity_id_str; @@ -754,7 +754,7 @@ list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; char *identity; @@ -801,7 +801,7 @@ add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const struct GNUNET_IDENTITY_PrivateKey *identity_priv; const char *identity; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; @@ -949,7 +949,7 @@ parse_jwt (const struct GNUNET_RECLAIM_Credential *cred, */ static void attr_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr) { struct RequestHandle *handle = cls; @@ -996,7 +996,7 @@ list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; char *identity; @@ -1050,7 +1050,7 @@ delete_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + const struct GNUNET_IDENTITY_PrivateKey *priv_key; struct RequestHandle *handle = cls; struct GNUNET_RECLAIM_Attribute attr; struct EgoEntry *ego_entry; @@ -1108,11 +1108,11 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const struct GNUNET_IDENTITY_PrivateKey *identity_priv; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_RECLAIM_Ticket *ticket = NULL; - struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; + struct GNUNET_IDENTITY_PublicKey tmp_pk; char term_data[handle->rest_handle->data_size + 1]; json_t *data_json; json_error_t err; @@ -1156,7 +1156,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); if (0 == memcmp (&ticket->identity, &tmp_pk, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) + sizeof(struct GNUNET_IDENTITY_PublicKey))) break; } if (NULL == ego_entry) @@ -1178,7 +1178,7 @@ revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, static void consume_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_IDENTITY_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *pres) { @@ -1215,11 +1215,11 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls) { - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const struct GNUNET_IDENTITY_PrivateKey *identity_priv; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct GNUNET_RECLAIM_Ticket *ticket; - struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; + struct GNUNET_IDENTITY_PublicKey tmp_pk; char term_data[handle->rest_handle->data_size + 1]; json_t *data_json; json_error_t err; @@ -1259,7 +1259,7 @@ consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &tmp_pk); if (0 == memcmp (&ticket->audience, &tmp_pk, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) + sizeof(struct GNUNET_IDENTITY_PublicKey))) break; } if (NULL == ego_entry) @@ -1343,7 +1343,7 @@ list_ego (void *cls, const char *identifier) { struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; if ((NULL == ego) && (ID_REST_STATE_INIT == state)) { @@ -1354,7 +1354,7 @@ list_ego (void *cls, { ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, @@ -1380,7 +1380,7 @@ list_ego (void *cls, /* Add */ ego_entry = GNUNET_new (struct EgoEntry); GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->keystring = GNUNET_IDENTITY_public_key_to_string (&pk); ego_entry->ego = ego; ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail (ego_head, diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h index bc7f34365..aae8ee89a 100644 --- a/src/reclaim/reclaim.h +++ b/src/reclaim/reclaim.h @@ -29,7 +29,7 @@ #define RECLAIM_H #include "gnunet_common.h" - +#include "gnunet_identity_service.h" GNUNET_NETWORK_STRUCT_BEGIN @@ -62,7 +62,7 @@ struct AttributeStoreMessage /** * Identity */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /* followed by the serialized attribute */ }; @@ -91,7 +91,7 @@ struct AttributeDeleteMessage /** * Identity */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /* followed by the serialized attribute */ }; @@ -151,7 +151,7 @@ struct AttributeResultMessage /** * The public key of the identity. */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; + struct GNUNET_IDENTITY_PublicKey identity; /* followed by: * serialized attribute data @@ -186,7 +186,7 @@ struct CredentialResultMessage /** * The public key of the identity. */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; + struct GNUNET_IDENTITY_PublicKey identity; /* followed by: * serialized credential data @@ -212,7 +212,7 @@ struct AttributeIterationStartMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; }; @@ -251,7 +251,7 @@ struct CredentialIterationStartMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; }; @@ -323,7 +323,7 @@ struct TicketIterationStartMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; }; @@ -379,12 +379,12 @@ struct IssueTicketMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * Requesting party. */ - struct GNUNET_CRYPTO_EcdsaPublicKey rp; + struct GNUNET_IDENTITY_PublicKey rp; /** * length of serialized attribute list @@ -412,7 +412,7 @@ struct RevokeTicketMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * length of serialized attribute list @@ -493,7 +493,7 @@ struct ConsumeTicketMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * The ticket to consume @@ -539,7 +539,7 @@ struct ConsumeTicketResultMessage /** * The public key of the identity. */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; + struct GNUNET_IDENTITY_PublicKey identity; /* followed by: * serialized attributes data diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index 1e0251519..f4f2b946a 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -235,7 +235,7 @@ struct GNUNET_RECLAIM_AttributeIterator /** * Private key of the zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * The operation id this zone iteration operation has @@ -302,7 +302,7 @@ struct GNUNET_RECLAIM_CredentialIterator /** * Private key of the zone. */ - struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + struct GNUNET_IDENTITY_PrivateKey identity; /** * The operation id this zone iteration operation has @@ -704,7 +704,7 @@ check_attribute_result (void *cls, const struct AttributeResultMessage *msg) static void handle_attribute_result (void *cls, const struct AttributeResultMessage *msg) { - static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; + static struct GNUNET_IDENTITY_PrivateKey identity_dummy; struct GNUNET_RECLAIM_Handle *h = cls; struct GNUNET_RECLAIM_AttributeIterator *it; struct GNUNET_RECLAIM_Operation *op; @@ -806,7 +806,7 @@ static void handle_credential_result (void *cls, const struct CredentialResultMessage *msg) { - static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; + static struct GNUNET_IDENTITY_PrivateKey identity_dummy; struct GNUNET_RECLAIM_Handle *h = cls; struct GNUNET_RECLAIM_CredentialIterator *it; struct GNUNET_RECLAIM_Operation *op; @@ -1134,7 +1134,7 @@ GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h) struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_store ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_TIME_Relative *exp_interval, GNUNET_RECLAIM_ContinuationWithStatus cont, @@ -1181,7 +1181,7 @@ GNUNET_RECLAIM_attribute_store ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_attribute_delete ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Attribute *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls) @@ -1226,7 +1226,7 @@ GNUNET_RECLAIM_attribute_delete ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_credential_store ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Credential *attr, const struct GNUNET_TIME_Relative *exp_interval, GNUNET_RECLAIM_ContinuationWithStatus cont, @@ -1273,7 +1273,7 @@ GNUNET_RECLAIM_credential_store ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_credential_delete ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, + const struct GNUNET_IDENTITY_PrivateKey *pkey, const struct GNUNET_RECLAIM_Credential *attr, GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls) @@ -1330,7 +1330,7 @@ GNUNET_RECLAIM_credential_delete ( struct GNUNET_RECLAIM_AttributeIterator * GNUNET_RECLAIM_get_attributes_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_AttributeResult proc, @@ -1439,7 +1439,7 @@ GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it) struct GNUNET_RECLAIM_CredentialIterator * GNUNET_RECLAIM_get_credentials_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_CredentialResult proc, @@ -1541,8 +1541,8 @@ GNUNET_RECLAIM_get_credentials_stop (struct struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, - const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, + const struct GNUNET_IDENTITY_PrivateKey *iss, + const struct GNUNET_IDENTITY_PublicKey *rp, const struct GNUNET_RECLAIM_AttributeList *attrs, GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls) @@ -1590,7 +1590,7 @@ GNUNET_RECLAIM_ticket_issue ( struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls) @@ -1636,7 +1636,7 @@ GNUNET_RECLAIM_ticket_consume ( struct GNUNET_RECLAIM_TicketIterator * GNUNET_RECLAIM_ticket_iteration_start ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_TicketCallback proc, @@ -1731,7 +1731,7 @@ GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it) struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_revoke ( struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + const struct GNUNET_IDENTITY_PrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_ContinuationWithStatus cb, void *cb_cls) diff --git a/src/reclaim/test_reclaim_attribute.c b/src/reclaim/test_reclaim_attribute.c index f71d86b56..f8faf8021 100644 --- a/src/reclaim/test_reclaim_attribute.c +++ b/src/reclaim/test_reclaim_attribute.c @@ -9,12 +9,10 @@ main (int argc, char *argv[]) struct GNUNET_RECLAIM_AttributeList *al; struct GNUNET_RECLAIM_AttributeList *al_two; struct GNUNET_RECLAIM_AttributeListEntry *ale; - struct GNUNET_RECLAIM_Attribute *attr; char attrname[100]; char attrdata[100]; size_t ser_len_claimed; size_t ser_len_actual; - ssize_t deser_len; char *ser_data; int count = 0; diff --git a/src/regex/regex_block_lib.c b/src/regex/regex_block_lib.c index a309c2305..159e8bf8a 100644 --- a/src/regex/regex_block_lib.c +++ b/src/regex/regex_block_lib.c @@ -352,14 +352,14 @@ REGEX_BLOCK_iterate (const struct RegexBlock *block, } off = len; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Start iterating block of size %u, proof %u, off %u edges %u\n", - size, len, off, n); + "Start iterating block of size %lu, proof %u, off %lu edges %u\n", + (unsigned long) size, len, (unsigned long) off, n); /* &aux[off] always points to our token */ for (n = 0; n < num_edges; n++) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Edge %u/%u, off %u tokenlen %u (%.*s)\n", - n + 1, num_edges, off, + "Edge %u/%u, off %lu tokenlen %u (%.*s)\n", + n + 1, num_edges, (unsigned long) off, ntohs (edges[n].token_length), ntohs (edges[n].token_length), &aux[off]); if (NULL != iterator) diff --git a/src/regex/regex_internal_dht.c b/src/regex/regex_internal_dht.c index d2c69f131..39d7cd847 100644 --- a/src/regex/regex_internal_dht.c +++ b/src/regex/regex_internal_dht.c @@ -427,8 +427,7 @@ regex_find_path (const struct GNUNET_HashCode *key, LOG (GNUNET_ERROR_TYPE_DEBUG, "Accept state found, now searching for paths to %s\n", - GNUNET_h2s (key), - (unsigned int) ctx->position); + GNUNET_h2s (key)); get_h = GNUNET_DHT_get_start (ctx->info->dht, /* handle */ GNUNET_BLOCK_TYPE_REGEX_ACCEPT, /* type */ key, /* key to search */ @@ -534,8 +533,8 @@ regex_result_iterator (void *cls, return GNUNET_YES; // We found an accept state! } LOG (GNUNET_ERROR_TYPE_DEBUG, - "* %u, %u, [%u]\n", - ctx->position, + "* %lu, %lu, [%u]\n", + (unsigned long) ctx->position, strlen (ctx->info->description), GNUNET_BLOCK_is_accepting (block, result->size)); regex_next_edge (block, result->size, ctx); @@ -729,7 +728,7 @@ REGEX_INTERNAL_search (struct GNUNET_DHT_Handle *dht, "Initial key for `%s' is %s (based on `%.*s')\n", string, GNUNET_h2s (&key), - size, + (int) size, string); ctx = GNUNET_new (struct RegexSearchContext); ctx->position = size; diff --git a/src/regex/regex_test_graph.c b/src/regex/regex_test_graph.c index 8e1e00fd4..c8efae772 100644 --- a/src/regex/regex_test_graph.c +++ b/src/regex/regex_test_graph.c @@ -177,8 +177,7 @@ REGEX_TEST_automaton_save_graph_step (void *cls, unsigned int count, } else { - GNUNET_asprintf (&s_acc, "\"%s\" [shape=doublecircle];\n", name, - s->scc_id); + GNUNET_asprintf (&s_acc, "\"%s\" [shape=doublecircle];\n", name); } } else if (GNUNET_YES == ctx->coloring) @@ -189,7 +188,7 @@ REGEX_TEST_automaton_save_graph_step (void *cls, unsigned int count, } else { - GNUNET_asprintf (&s_acc, "\"%s\" [shape=circle];\n", name, s->scc_id); + GNUNET_asprintf (&s_acc, "\"%s\" [shape=circle];\n", name); } GNUNET_assert (NULL != s_acc); @@ -228,7 +227,7 @@ REGEX_TEST_automaton_save_graph_step (void *cls, unsigned int count, else { GNUNET_asprintf (&s_tran, "\"%s\" -> \"%s\" [label = \"ε\"];\n", name, - to_name, s->scc_id); + to_name); } } else @@ -242,7 +241,7 @@ REGEX_TEST_automaton_save_graph_step (void *cls, unsigned int count, else { GNUNET_asprintf (&s_tran, "\"%s\" -> \"%s\" [label = \"%s\"];\n", name, - to_name, ctran->label, s->scc_id); + to_name, ctran->label); } } diff --git a/src/revocation/Makefile.am b/src/revocation/Makefile.am index 9d98502a6..b1a079a0d 100644 --- a/src/revocation/Makefile.am +++ b/src/revocation/Makefile.am @@ -30,6 +30,7 @@ libgnunet_plugin_block_revocation_la_LIBADD = \ $(top_builddir)/src/block/libgnunetblockgroup.la \ $(top_builddir)/src/block/libgnunetblock.la \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(LTLIBINTL) libgnunet_plugin_block_revocation_la_DEPENDENCIES = \ libgnunetrevocation.la \ @@ -63,6 +64,7 @@ libgnunetrevocation_la_SOURCES = \ revocation_api.c revocation.h libgnunetrevocation_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(LIBGCRYPT_LIBS) \ $(GN_LIBINTL) $(XLIB) -lgcrypt libgnunetrevocation_la_LDFLAGS = \ @@ -80,6 +82,7 @@ gnunet_service_revocation_LDADD = \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/setu/libgnunetsetu.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ -lm \ $(GN_LIBINTL) diff --git a/src/revocation/gnunet-revocation-tvg.c b/src/revocation/gnunet-revocation-tvg.c index 29df1bb4d..cb5e31fcd 100644 --- a/src/revocation/gnunet-revocation-tvg.c +++ b/src/revocation/gnunet-revocation-tvg.c @@ -65,25 +65,34 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_CRYPTO_EcdsaPrivateKey id_priv; - struct GNUNET_CRYPTO_EcdsaPublicKey id_pub; - struct GNUNET_REVOCATION_PowP pow; + struct GNUNET_IDENTITY_PrivateKey id_priv; + struct GNUNET_IDENTITY_PublicKey id_pub; + struct GNUNET_REVOCATION_PowP *pow; struct GNUNET_REVOCATION_PowCalculationHandle *ph; struct GNUNET_TIME_Relative exp; - - GNUNET_CRYPTO_ecdsa_key_create (&id_priv); - GNUNET_CRYPTO_ecdsa_key_get_public (&id_priv, - &id_pub); - fprintf (stdout, "Zone private key (d, little-endian scalar):\n"); - print_bytes (&id_priv, sizeof(id_priv), 0); + char ztld[128]; + + id_priv.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA); + GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key); + GNUNET_IDENTITY_key_get_public (&id_priv, + &id_pub); + GNUNET_STRINGS_data_to_string (&id_pub, + GNUNET_IDENTITY_key_get_length (&id_pub), + ztld, + sizeof (ztld)); + fprintf (stdout, "Zone private key (d, little-endian scalar, with ztype prepended):\n"); + print_bytes (&id_priv, sizeof(id_priv), 8); + fprintf (stdout, "\n"); + fprintf (stdout, "Zone identifier (zid):\n"); + print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); fprintf (stdout, "\n"); - fprintf (stdout, "Zone public key (zk):\n"); - print_bytes (&id_pub, sizeof(id_pub), 0); + fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n"); + fprintf (stdout, "%s\n", ztld); fprintf (stdout, "\n"); - memset (&pow, 0, sizeof (pow)); + pow = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE); GNUNET_REVOCATION_pow_init (&id_priv, - &pow); - ph = GNUNET_REVOCATION_pow_start (&pow, + pow); + ph = GNUNET_REVOCATION_pow_start (pow, TEST_EPOCHS, TEST_DIFFICULTY); fprintf (stdout, "Difficulty (%d base difficulty + %d epochs): %d\n\n", @@ -97,12 +106,12 @@ run (void *cls, } exp = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS, TEST_EPOCHS); - GNUNET_assert (GNUNET_OK == GNUNET_REVOCATION_check_pow (&pow, + GNUNET_assert (GNUNET_OK == GNUNET_REVOCATION_check_pow (pow, TEST_DIFFICULTY, exp)); fprintf (stdout, "Proof:\n"); - print_bytes (&pow, - sizeof (pow), + print_bytes (pow, + GNUNET_REVOCATION_proof_get_size (pow), 8); } diff --git a/src/revocation/gnunet-revocation.c b/src/revocation/gnunet-revocation.c index 0e1e482ab..d59ea7c81 100644 --- a/src/revocation/gnunet-revocation.c +++ b/src/revocation/gnunet-revocation.c @@ -101,7 +101,7 @@ static struct GNUNET_SCHEDULER_Task *pow_task; /** * Proof-of-work object */ -static struct GNUNET_REVOCATION_PowP proof_of_work; +static struct GNUNET_REVOCATION_PowP *proof_of_work; /** * Function run if the user aborts with CTRL-C. @@ -213,7 +213,7 @@ static void perform_revocation () { h = GNUNET_REVOCATION_revoke (cfg, - &proof_of_work, + proof_of_work, &print_revocation_result, NULL); } @@ -228,11 +228,12 @@ perform_revocation () static void sync_pow () { + size_t psize = GNUNET_REVOCATION_proof_get_size (proof_of_work); if ((NULL != filename) && - (sizeof(struct GNUNET_REVOCATION_PowP) != + (psize != GNUNET_DISK_fn_write (filename, - &proof_of_work, - sizeof(struct GNUNET_REVOCATION_PowP), + proof_of_work, + psize, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); @@ -269,6 +270,7 @@ static void calculate_pow (void *cls) { struct GNUNET_REVOCATION_PowCalculationHandle *ph = cls; + size_t psize; /* store temporary results */ pow_task = NULL; @@ -277,11 +279,12 @@ calculate_pow (void *cls) /* actually do POW calculation */ if (GNUNET_OK == GNUNET_REVOCATION_pow_round (ph)) { + psize = GNUNET_REVOCATION_proof_get_size (proof_of_work); if ((NULL != filename) && - (sizeof(struct GNUNET_REVOCATION_PowP) != + (psize != GNUNET_DISK_fn_write (filename, - &proof_of_work, - sizeof(struct GNUNET_REVOCATION_PowP), + proof_of_work, + psize, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", filename); @@ -325,9 +328,10 @@ calculate_pow (void *cls) static void ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego) { - struct GNUNET_CRYPTO_EcdsaPublicKey key; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + struct GNUNET_IDENTITY_PublicKey key; + const struct GNUNET_IDENTITY_PrivateKey *privkey; struct GNUNET_REVOCATION_PowCalculationHandle *ph = NULL; + size_t psize; el = NULL; if (NULL == ego) @@ -338,12 +342,15 @@ ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego) } GNUNET_IDENTITY_ego_get_public_key (ego, &key); privkey = GNUNET_IDENTITY_ego_get_private_key (ego); - memset (&proof_of_work, 0, sizeof (proof_of_work)); + proof_of_work = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE); if ((NULL != filename) && (GNUNET_YES == GNUNET_DISK_file_test (filename)) && - (sizeof(proof_of_work) == - GNUNET_DISK_fn_read (filename, &proof_of_work, sizeof(proof_of_work)))) + (0 < (psize = + GNUNET_DISK_fn_read (filename, proof_of_work, + GNUNET_REVOCATION_MAX_PROOF_SIZE)))) { - if (0 != GNUNET_memcmp (&proof_of_work.key, &key)) + size_t ksize = GNUNET_IDENTITY_key_get_length (&key); + if (((psize - sizeof (*proof_of_work)) < ksize) || // Key too small + (0 != memcmp (&proof_of_work[1], &key, ksize))) // Keys do not match { fprintf (stderr, _ ("Error: revocation certificate in `%s' is not for `%s'\n"), @@ -352,7 +359,7 @@ ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego) return; } if (GNUNET_YES == - GNUNET_REVOCATION_check_pow (&proof_of_work, + GNUNET_REVOCATION_check_pow (proof_of_work, (unsigned int) matching_bits, epoch_duration)) { @@ -369,7 +376,7 @@ ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego) fprintf (stderr, "%s", _ ("Continuing calculation where left off...\n")); - ph = GNUNET_REVOCATION_pow_start (&proof_of_work, + ph = GNUNET_REVOCATION_pow_start (proof_of_work, epochs, matching_bits); } @@ -379,8 +386,8 @@ ego_callback (void *cls, struct GNUNET_IDENTITY_Ego *ego) if (NULL == ph) { GNUNET_REVOCATION_pow_init (privkey, - &proof_of_work); - ph = GNUNET_REVOCATION_pow_start (&proof_of_work, + proof_of_work); + ph = GNUNET_REVOCATION_pow_start (proof_of_work, epochs, /* Epochs */ matching_bits); } @@ -403,15 +410,15 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNUNET_IDENTITY_PublicKey pk; + size_t psize; cfg = c; if (NULL != test_ego) { if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (test_ego, - strlen (test_ego), - &pk)) + GNUNET_IDENTITY_public_key_from_string (test_ego, + &pk)) { fprintf (stderr, _ ("Public key `%s' malformed\n"), test_ego); return; @@ -463,23 +470,33 @@ run (void *cls, } if ((NULL != filename) && (perform)) { - if (sizeof(proof_of_work) != GNUNET_DISK_fn_read (filename, - &proof_of_work, - sizeof(proof_of_work))) + size_t bread; + proof_of_work = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE); + if (0 < (bread = GNUNET_DISK_fn_read (filename, + proof_of_work, + GNUNET_REVOCATION_MAX_PROOF_SIZE))) { fprintf (stderr, _ ("Failed to read revocation certificate from `%s'\n"), filename); return; } + psize = GNUNET_REVOCATION_proof_get_size (proof_of_work); + if (bread != psize) + { + fprintf (stderr, + _ ("Revocation certificate corrupted in `%s'\n"), + filename); + return; + } GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); if (GNUNET_YES != - GNUNET_REVOCATION_check_pow (&proof_of_work, + GNUNET_REVOCATION_check_pow (proof_of_work, (unsigned int) matching_bits, epoch_duration)) { struct GNUNET_REVOCATION_PowCalculationHandle *ph; - ph = GNUNET_REVOCATION_pow_start (&proof_of_work, + ph = GNUNET_REVOCATION_pow_start (proof_of_work, epochs, /* Epochs */ matching_bits); diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index ddebb38ad..0fa92f4a6 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c @@ -172,7 +172,8 @@ new_peer_entry (const struct GNUNET_PeerIdentity *peer) static int verify_revoke_message (const struct RevokeMessage *rm) { - if (GNUNET_YES != GNUNET_REVOCATION_check_pow (&rm->proof_of_work, + struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; + if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow, (unsigned int) revocation_work_required, epoch_duration)) @@ -236,7 +237,7 @@ handle_query_message (void *cls, int res; GNUNET_CRYPTO_hash (&qm->key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), + sizeof(struct GNUNET_IDENTITY_PublicKey), &hc); res = GNUNET_CONTAINER_multihashmap_contains (revocation_map, &hc); @@ -276,9 +277,11 @@ do_flood (void *cls, return GNUNET_OK; /* peer connected to us via SET, but we have no direct CORE connection for flooding */ - e = GNUNET_MQ_msg (cp, + e = GNUNET_MQ_msg_extra (cp, + htonl (rm->pow_size), GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); *cp = *rm; + memcpy (&cp[1], &rm[1], htonl (rm->pow_size)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Flooding revocation to `%s'\n", GNUNET_i2s (target)); @@ -303,9 +306,12 @@ publicize_rm (const struct RevokeMessage *rm) struct RevokeMessage *cp; struct GNUNET_HashCode hc; struct GNUNET_SETU_Element e; + const struct GNUNET_IDENTITY_PublicKey *pk; - GNUNET_CRYPTO_hash (&rm->proof_of_work.key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), + struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + GNUNET_CRYPTO_hash (pk, + GNUNET_IDENTITY_key_get_length (pk), &hc); if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (revocation_map, @@ -371,6 +377,23 @@ publicize_rm (const struct RevokeMessage *rm) } +static int +check_revoke_message (void *cls, + const struct RevokeMessage *rm) +{ + uint16_t size; + + size = ntohs (rm->header.size); + if (size <= sizeof(struct RevokeMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + +} + + /** * Handle REVOKE message from client. * @@ -403,6 +426,23 @@ handle_revoke_message (void *cls, } +static int +check_p2p_revoke (void *cls, + const struct RevokeMessage *rm) +{ + uint16_t size; + + size = ntohs (rm->header.size); + if (size <= sizeof(struct RevokeMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + +} + + /** * Core handler for flooded revocation messages. * @@ -784,16 +824,17 @@ run (void *cls, struct GNUNET_SERVICE_Handle *service) { struct GNUNET_MQ_MessageHandler core_handlers[] = { - GNUNET_MQ_hd_fixed_size (p2p_revoke, - GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, - struct RevokeMessage, - NULL), + GNUNET_MQ_hd_var_size (p2p_revoke, + GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, + struct RevokeMessage, + NULL), GNUNET_MQ_handler_end () }; char *fn; uint64_t left; struct RevokeMessage *rm; struct GNUNET_HashCode hc; + const struct GNUNET_IDENTITY_PublicKey *pk; GNUNET_CRYPTO_hash ("revocation-set-union-application-id", strlen ("revocation-set-union-application-id"), @@ -892,9 +933,11 @@ run (void *cls, GNUNET_free (fn); return; } - GNUNET_break (0 == ntohl (rm->reserved)); - GNUNET_CRYPTO_hash (&rm->proof_of_work.key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), + struct GNUNET_REVOCATION_PowP *pow = (struct + GNUNET_REVOCATION_PowP *) &rm[1]; + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + GNUNET_CRYPTO_hash (pk, + GNUNET_IDENTITY_key_get_length (pk), &hc); GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (revocation_map, @@ -939,10 +982,10 @@ GNUNET_SERVICE_MAIN GNUNET_MESSAGE_TYPE_REVOCATION_QUERY, struct QueryMessage, NULL), - GNUNET_MQ_hd_fixed_size (revoke_message, - GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, - struct RevokeMessage, - NULL), + GNUNET_MQ_hd_var_size (revoke_message, + GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, + struct RevokeMessage, + NULL), GNUNET_MQ_handler_end ()); diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c index 291c56f70..3c9344a49 100644 --- a/src/revocation/plugin_block_revocation.c +++ b/src/revocation/plugin_block_revocation.c @@ -143,16 +143,18 @@ block_plugin_revocation_evaluate (void *cls, GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - if (0 >= - GNUNET_REVOCATION_check_pow (&rm->proof_of_work, - ic->matching_bits, - ic->epoch_duration)) + struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; + const struct GNUNET_IDENTITY_PublicKey *pk; + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + if (GNUNET_YES != GNUNET_REVOCATION_check_pow (pow, + ic->matching_bits, + ic->epoch_duration)) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } - GNUNET_CRYPTO_hash (&rm->proof_of_work.key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), + GNUNET_CRYPTO_hash (pk, + GNUNET_IDENTITY_key_get_length (pk), &chash); if (GNUNET_YES == GNUNET_BLOCK_GROUP_bf_test_and_set (group, @@ -182,13 +184,16 @@ block_plugin_revocation_get_key (void *cls, { const struct RevokeMessage *rm = block; - if (block_size != sizeof(*rm)) + if (block_size <= sizeof(*rm)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - GNUNET_CRYPTO_hash (&rm->proof_of_work.key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), + struct GNUNET_REVOCATION_PowP *pow = (struct GNUNET_REVOCATION_PowP *) &rm[1]; + const struct GNUNET_IDENTITY_PublicKey *pk; + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + GNUNET_CRYPTO_hash (pk, + GNUNET_IDENTITY_key_get_length (pk), key); return GNUNET_OK; } diff --git a/src/revocation/revocation.h b/src/revocation/revocation.h index 635c56cfc..c3a9c9e6b 100644 --- a/src/revocation/revocation.h +++ b/src/revocation/revocation.h @@ -49,7 +49,7 @@ struct QueryMessage /** * Key to check. */ - struct GNUNET_CRYPTO_EcdsaPublicKey key; + struct GNUNET_IDENTITY_PublicKey key; }; @@ -85,14 +85,11 @@ struct RevokeMessage struct GNUNET_MessageHeader header; /** - * For alignment. + * Length of PoW with signature. */ - uint32_t reserved GNUNET_PACKED; + uint32_t pow_size GNUNET_PACKED; - /** - * Number that causes a hash collision with the @e public_key. - */ - struct GNUNET_REVOCATION_PowP proof_of_work; + /** Followed by the PoW **/ }; diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index 75cfd8761..791c3d008 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c @@ -160,7 +160,7 @@ handle_revocation_query_response (void *cls, */ struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_CRYPTO_EcdsaPublicKey *key, + const struct GNUNET_IDENTITY_PublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls) { @@ -359,10 +359,12 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, } h->func = func; h->func_cls = func_cls; - env = GNUNET_MQ_msg (rm, - GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); - rm->reserved = htonl (0); - rm->proof_of_work = *pow; + size_t extra_len = GNUNET_REVOCATION_proof_get_size (pow); + env = GNUNET_MQ_msg_extra (rm, + extra_len, + GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE); + rm->pow_size = htonl (extra_len); + memcpy (&rm[1], pow, extra_len); GNUNET_MQ_send (h->mq, env); return h; @@ -420,6 +422,51 @@ calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph) } +enum GNUNET_GenericReturnValue +check_signature_identity (const struct GNUNET_REVOCATION_PowP *pow, + const struct GNUNET_IDENTITY_PublicKey *key) +{ + struct GNUNET_REVOCATION_SignaturePurposePS *spurp; + struct GNUNET_IDENTITY_Signature *sig; + const struct GNUNET_IDENTITY_PublicKey *pk; + size_t ksize; + + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + ksize = GNUNET_IDENTITY_key_get_length (pk); + + spurp = GNUNET_malloc (sizeof (*spurp) + ksize); + spurp->timestamp = pow->timestamp; + spurp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); + spurp->purpose.size = htonl (sizeof(*spurp) + ksize); + GNUNET_IDENTITY_write_key_to_buffer (pk, + (char*) &spurp[1], + ksize); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Expected signature payload len: %u\n", + ntohl (spurp->purpose.size)); + sig = (struct GNUNET_IDENTITY_Signature *) ((char*) &pow[1] + ksize); + if (GNUNET_OK != + GNUNET_IDENTITY_signature_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION, + &spurp->purpose, + sig, + key)) + { + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +enum GNUNET_GenericReturnValue +check_signature (const struct GNUNET_REVOCATION_PowP *pow) +{ + const struct GNUNET_IDENTITY_PublicKey *pk; + + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + return check_signature_identity (pow, pk); +} + + /** * Check if the given proof-of-work is valid. * @@ -433,10 +480,9 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, unsigned int difficulty, struct GNUNET_TIME_Relative epoch_duration) { - char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) + char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + sizeof (uint64_t)] GNUNET_ALIGN; - struct GNUNET_REVOCATION_SignaturePurposePS spurp; struct GNUNET_HashCode result; struct GNUNET_TIME_Absolute ts; struct GNUNET_TIME_Absolute exp; @@ -446,25 +492,18 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, unsigned int tmp_score = 0; unsigned int epochs; uint64_t pow_val; + const struct GNUNET_IDENTITY_PublicKey *pk; + + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; /** * Check if signature valid */ - spurp.key = pow->key; - spurp.timestamp = pow->timestamp; - spurp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); - spurp.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof (struct GNUNET_TIME_AbsoluteNBO)); - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION, - &spurp.purpose, - &pow->signature, - &pow->key)) + if (GNUNET_OK != check_signature (pow)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Proof of work signature invalid!\n"); - return GNUNET_NO; + return GNUNET_SYSERR; } /** @@ -479,8 +518,8 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, &pow->timestamp, sizeof (uint64_t)); GNUNET_memcpy (&buf[sizeof(uint64_t) * 2], - &pow->key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + pk, + GNUNET_IDENTITY_key_get_length (pk)); for (unsigned int i = 0; i < POW_COUNT; i++) { pow_val = GNUNET_ntohll (pow->pow[i]); @@ -529,18 +568,15 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_REVOCATION_PowP *pow, } -/** - * Initializes a fresh PoW computation. - * - * @param key the key to calculate the PoW for. - * @param[out] pow starting point for PoW calculation (not yet valid) - */ -void -GNUNET_REVOCATION_pow_init (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, - struct GNUNET_REVOCATION_PowP *pow) +enum GNUNET_GenericReturnValue +sign_pow_identity (const struct GNUNET_IDENTITY_PrivateKey *key, + struct GNUNET_REVOCATION_PowP *pow) { struct GNUNET_TIME_Absolute ts = GNUNET_TIME_absolute_get (); - struct GNUNET_REVOCATION_SignaturePurposePS rp; + struct GNUNET_REVOCATION_SignaturePurposePS *rp; + const struct GNUNET_IDENTITY_PublicKey *pk; + size_t ksize; + char *sig; /** * Predate the validity period to prevent rejections due to @@ -548,19 +584,53 @@ GNUNET_REVOCATION_pow_init (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, */ ts = GNUNET_TIME_absolute_subtract (ts, GNUNET_TIME_UNIT_WEEKS); - + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + ksize = GNUNET_IDENTITY_key_get_length (pk); pow->timestamp = GNUNET_TIME_absolute_hton (ts); - rp.timestamp = pow->timestamp; - rp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); - rp.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) - + sizeof (struct GNUNET_TIME_AbsoluteNBO)); - GNUNET_CRYPTO_ecdsa_key_get_public (key, &pow->key); - rp.key = pow->key; - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_ecdsa_sign_ (key, - &rp.purpose, - &pow->signature)); + rp = GNUNET_malloc (sizeof (*rp) + ksize); + rp->timestamp = pow->timestamp; + rp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); + rp->purpose.size = htonl (sizeof(*rp) + ksize); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Signature payload len: %u\n", + ntohl (rp->purpose.size)); + GNUNET_IDENTITY_write_key_to_buffer (pk, + ((char*) &rp[1]), + ksize); + sig = ((char*) &pow[1]) + ksize; + int result = GNUNET_IDENTITY_sign_ (key, + &rp->purpose, + (void*) sig); + if (result == GNUNET_SYSERR) + return GNUNET_NO; + else + return result; +} + + +enum GNUNET_GenericReturnValue +sign_pow (const struct GNUNET_IDENTITY_PrivateKey *key, + struct GNUNET_REVOCATION_PowP *pow) +{ + struct GNUNET_IDENTITY_PublicKey *pk; + + pk = (struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + GNUNET_IDENTITY_key_get_public (key, pk); + return sign_pow_identity (key, pow); +} + + +/** + * Initializes a fresh PoW computation. + * + * @param key the key to calculate the PoW for. + * @param[out] pow starting point for PoW calculation (not yet valid) + */ +void +GNUNET_REVOCATION_pow_init (const struct GNUNET_IDENTITY_PrivateKey *key, + struct GNUNET_REVOCATION_PowP *pow) +{ + GNUNET_assert (GNUNET_OK == sign_pow (key, pow)); } @@ -622,15 +692,17 @@ cmp_pow_value (const void *a, const void *b) enum GNUNET_GenericReturnValue GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc) { - char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) + char buf[sizeof(struct GNUNET_IDENTITY_PublicKey) + sizeof (uint64_t) + sizeof (uint64_t)] GNUNET_ALIGN; struct GNUNET_HashCode result; + const struct GNUNET_IDENTITY_PublicKey *pk; unsigned int zeros; int ret; uint64_t pow_nbo; pc->current_pow++; + pk = (const struct GNUNET_IDENTITY_PublicKey *) &(pc->pow[1]); /** * Do not try duplicates @@ -644,8 +716,8 @@ GNUNET_REVOCATION_pow_round (struct GNUNET_REVOCATION_PowCalculationHandle *pc) &pc->pow->timestamp, sizeof (uint64_t)); GNUNET_memcpy (&buf[sizeof(uint64_t) * 2], - &pc->pow->key, - sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); + pk, + GNUNET_IDENTITY_key_get_length (pk)); GNUNET_CRYPTO_pow_hash (&salt, buf, sizeof(buf), @@ -690,4 +762,22 @@ GNUNET_REVOCATION_pow_stop (struct GNUNET_REVOCATION_PowCalculationHandle *pc) } +size_t +GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow) +{ + size_t size; + size_t ksize; + const struct GNUNET_IDENTITY_PublicKey *pk; + const struct GNUNET_IDENTITY_Signature *sig; + + size = sizeof (struct GNUNET_REVOCATION_PowP); + pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1]; + ksize = GNUNET_IDENTITY_key_get_length (pk); + size += ksize; + sig = (struct GNUNET_IDENTITY_Signature *) ((char*) &pow[1] + ksize); + size += GNUNET_IDENTITY_signature_get_length (sig); + return size; +} + + /* end of revocation_api.c */ diff --git a/src/revocation/test_revocation.c b/src/revocation/test_revocation.c index b65567d79..c6457016f 100644 --- a/src/revocation/test_revocation.c +++ b/src/revocation/test_revocation.c @@ -38,8 +38,8 @@ struct TestPeer struct GNUNET_TESTBED_Operation *core_op; struct GNUNET_IDENTITY_Handle *idh; const struct GNUNET_CONFIGURATION_Handle *cfg; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; - struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; + const struct GNUNET_IDENTITY_PrivateKey *privkey; + struct GNUNET_IDENTITY_PublicKey pubkey; struct GNUNET_CRYPTO_EcdsaSignature sig; struct GNUNET_IDENTITY_Operation *create_id_op; struct GNUNET_IDENTITY_EgoLookup *ego_lookup; @@ -142,13 +142,13 @@ revocation_cb (void *cls, enum GNUNET_GenericReturnValue is_valid) } -static struct GNUNET_REVOCATION_PowP proof_of_work; +static struct GNUNET_REVOCATION_PowP *proof_of_work; static void ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) { static int completed = 0; - const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + const struct GNUNET_IDENTITY_PrivateKey *privkey; if ((NULL != ego) && (cls == &testpeers[0])) { @@ -164,10 +164,10 @@ ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) GNUNET_IDENTITY_ego_get_public_key (ego, &testpeers[1].pubkey); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Calculating proof of work...\n"); privkey = GNUNET_IDENTITY_ego_get_private_key (ego); - memset (&proof_of_work, 0, sizeof (proof_of_work)); + proof_of_work = GNUNET_malloc (GNUNET_REVOCATION_MAX_PROOF_SIZE); GNUNET_REVOCATION_pow_init (privkey, - &proof_of_work); - testpeers[1].pow = GNUNET_REVOCATION_pow_start (&proof_of_work, + proof_of_work); + testpeers[1].pow = GNUNET_REVOCATION_pow_start (proof_of_work, 1, 5); int res = @@ -184,7 +184,7 @@ ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Egos retrieved\n"); testpeers[1].revok_handle = GNUNET_REVOCATION_revoke (testpeers[1].cfg, - &proof_of_work, + proof_of_work, &revocation_cb, NULL); GNUNET_REVOCATION_pow_stop (testpeers[1].pow); @@ -194,7 +194,7 @@ ego_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego) static void identity_create_cb (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk, + const struct GNUNET_IDENTITY_PrivateKey *pk, const char *emsg) { static int completed = 0; @@ -238,11 +238,13 @@ identity_completion_cb (void *cls, testpeers[0].create_id_op = GNUNET_IDENTITY_create (testpeers[0].idh, "client", NULL, + GNUNET_IDENTITY_TYPE_ECDSA, &identity_create_cb, &testpeers[0]); testpeers[1].create_id_op = GNUNET_IDENTITY_create (testpeers[1].idh, "toberevoked", NULL, + GNUNET_IDENTITY_TYPE_ECDSA, &identity_create_cb, &testpeers[1]); } diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index 87c6faf98..931d7e753 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c @@ -563,8 +563,8 @@ prepare_ibf_iterator (void *cls, struct IBF_Key salted_key; LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] inserting %lx (hash %s) into ibf\n", - (void *) op, + "[OP %p] inserting %lx (hash %s) into ibf\n", + op, (unsigned long) ke->ibf_key.key_val, GNUNET_h2s (&ke->element->element_hash)); salt_key (&ke->ibf_key, @@ -929,7 +929,7 @@ handle_union_p2p_strata_estimator (void *cls, (0 == other_size)) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Deciding to go for full set transmission (diff=%d, own set=%u)\n", + "Deciding to go for full set transmission (diff=%d, own set=%llu)\n", diff, op->state->initial_size); GNUNET_STATISTICS_update (_GSS_statistics, @@ -1004,8 +1004,8 @@ send_offers_iterator (void *cls, GNUNET_assert (NULL != ev); *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash; LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] sending element offer (%s) to peer\n", - (void *) op, + "[OP %p] sending element offer (%s) to peer\n", + op, GNUNET_h2s (&ke->element->element_hash)); GNUNET_MQ_send (op->mq, ev); return GNUNET_YES; @@ -2004,8 +2004,8 @@ handle_union_p2p_demand (void *cls, emsg->reserved = htons (0); emsg->element_type = htons (ee->element.element_type); LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] Sending demanded element (size %u, hash %s) to peer\n", - (void *) op, + "[OP %p] Sending demanded element (size %u, hash %s) to peer\n", + op, (unsigned int) ee->element.size, GNUNET_h2s (&ee->element_hash)); GNUNET_MQ_send (op->mq, ev); @@ -2120,8 +2120,8 @@ handle_union_p2p_offer (void *cls, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] Requesting element (hash %s)\n", - (void *) op, GNUNET_h2s (hash)); + "[OP %p] Requesting element (hash %s)\n", + op, GNUNET_h2s (hash)); ev = GNUNET_MQ_msg_header_extra (demands, sizeof(struct GNUNET_HashCode), GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND); diff --git a/src/set/set_api.c b/src/set/set_api.c index ce4b1c965..a082c23c1 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c @@ -630,8 +630,7 @@ create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg, else { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Creating new set (lazy copy)\n", - op); + "Creating new set (lazy copy)\n"); mqm = GNUNET_MQ_msg (copy_msg, GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT); copy_msg->cookie = *cookie; diff --git a/src/setu/gnunet-service-setu.c b/src/setu/gnunet-service-setu.c index 326589186..d00303ca7 100644 --- a/src/setu/gnunet-service-setu.c +++ b/src/setu/gnunet-service-setu.c @@ -1049,8 +1049,8 @@ prepare_ibf_iterator (void *cls, struct IBF_Key salted_key; LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] inserting %lx (hash %s) into ibf\n", - (void *) op, + "[OP %p] inserting %lx (hash %s) into ibf\n", + op, (unsigned long) ke->ibf_key.key_val, GNUNET_h2s (&ke->element->element_hash)); salt_key (&ke->ibf_key, @@ -1429,7 +1429,7 @@ handle_union_p2p_strata_estimator (void *cls, (0 == other_size)) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Deciding to go for full set transmission (diff=%d, own set=%u)\n", + "Deciding to go for full set transmission (diff=%d, own set=%llu)\n", diff, op->initial_size); GNUNET_STATISTICS_update (_GSS_statistics, @@ -1504,8 +1504,8 @@ send_offers_iterator (void *cls, GNUNET_assert (NULL != ev); *(struct GNUNET_HashCode *) &mh[1] = ke->element->element_hash; LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] sending element offer (%s) to peer\n", - (void *) op, + "[OP %p] sending element offer (%s) to peer\n", + op, GNUNET_h2s (&ke->element->element_hash)); GNUNET_MQ_send (op->mq, ev); return GNUNET_YES; @@ -2403,8 +2403,8 @@ handle_union_p2p_demand (void *cls, emsg->reserved = htons (0); emsg->element_type = htons (ee->element.element_type); LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] Sending demanded element (size %u, hash %s) to peer\n", - (void *) op, + "[OP %p] Sending demanded element (size %u, hash %s) to peer\n", + op, (unsigned int) ee->element.size, GNUNET_h2s (&ee->element_hash)); GNUNET_MQ_send (op->mq, ev); @@ -2502,8 +2502,8 @@ handle_union_p2p_offer (void *cls, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); LOG (GNUNET_ERROR_TYPE_DEBUG, - "[OP %x] Requesting element (hash %s)\n", - (void *) op, GNUNET_h2s (hash)); + "[OP %p] Requesting element (hash %s)\n", + op, GNUNET_h2s (hash)); ev = GNUNET_MQ_msg_header_extra (demands, sizeof(struct GNUNET_HashCode), GNUNET_MESSAGE_TYPE_SETU_P2P_DEMAND); @@ -2787,8 +2787,6 @@ check_incoming_msg (void *cls, * * @param cls the operation state * @param msg the received message - * @return #GNUNET_OK if the channel should be kept alive, - * #GNUNET_SYSERR to destroy the channel */ static void handle_incoming_msg (void *cls, diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c index 12c09b7d2..bf0a90b45 100644 --- a/src/statistics/statistics_api.c +++ b/src/statistics/statistics_api.c @@ -472,7 +472,7 @@ handle_statistics_value (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, "Received valid statistic on `%s:%s': %llu\n", service, name, - GNUNET_ntohll (smsg->value)); + (unsigned long long) GNUNET_ntohll (smsg->value)); if (GNUNET_OK != h->current->proc (h->current->cls, service, diff --git a/src/testbed-logger/gnunet-service-testbed-logger.c b/src/testbed-logger/gnunet-service-testbed-logger.c index 81652fa4f..bc2f0abe0 100644 --- a/src/testbed-logger/gnunet-service-testbed-logger.c +++ b/src/testbed-logger/gnunet-service-testbed-logger.c @@ -198,7 +198,7 @@ logger_run (void *cls, GNUNET_asprintf (&fn, "%s/%.*s_%jd.dat", dir, - hname_len, + (int) hname_len, hname, (intmax_t) pid); GNUNET_free (hname); diff --git a/src/testbed/gnunet-service-testbed_cpustatus.c b/src/testbed/gnunet-service-testbed_cpustatus.c index 70b865c73..440f2c24f 100644 --- a/src/testbed/gnunet-service-testbed_cpustatus.c +++ b/src/testbed/gnunet-service-testbed_cpustatus.c @@ -608,7 +608,7 @@ GST_stats_init (const struct GNUNET_CONFIGURATION_Handle *cfg) return; } fn = NULL; - (void) GNUNET_asprintf (&fn, "%s/%.*s-%jd.dat", stats_dir, len, + (void) GNUNET_asprintf (&fn, "%s/%.*s-%jd.dat", stats_dir, (int)len, hostname, (intmax_t) getpid ()); GNUNET_free (stats_dir); GNUNET_free (hostname); diff --git a/src/testbed/test_testbed_api_template.conf b/src/testbed/test_testbed_api_template.conf index 255c1b766..ae0368a8b 100644 --- a/src/testbed/test_testbed_api_template.conf +++ b/src/testbed/test_testbed_api_template.conf @@ -32,7 +32,7 @@ WAN_QUOTA_IN = 3932160 USE_EPHEMERAL_KEYS = NO IMMEDIATE_START = YES -[transport-udp] +[transport-tcp] TIMEOUT = 300 s [PATHS] diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 697783d96..09752ba28 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -448,7 +448,7 @@ handle_opsuccess ( uint64_t op_id; op_id = GNUNET_ntohll (msg->operation_id); - LOG_DEBUG ("Operation %lu successful\n", op_id); + LOG_DEBUG ("Operation %llu successful\n", op_id); if (NULL == (opc = find_opc (c, op_id))) { LOG_DEBUG ("Operation not found\n"); diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c index 1d765af92..a9a340e99 100644 --- a/src/testbed/testbed_api_topology.c +++ b/src/testbed/testbed_api_topology.c @@ -1089,7 +1089,7 @@ gen_topo_from_file (struct TopologyContext *tc, if (tc->num_peers <= peer_id) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Topology file needs more peers than given ones\n"), filename); + _ ("Topology file needs more peers than given ones\n")); goto _exit; } state = OTHER_PEER_INDEX; @@ -1114,7 +1114,7 @@ gen_topo_from_file (struct TopologyContext *tc, if (tc->num_peers <= other_peer_id) { LOG (GNUNET_ERROR_TYPE_ERROR, - _ ("Topology file needs more peers than given ones\n"), filename); + _ ("Topology file needs more peers than given ones\n")); goto _exit; } if (peer_id != other_peer_id) @@ -1150,7 +1150,7 @@ gen_topo_from_file (struct TopologyContext *tc, } else LOG (GNUNET_ERROR_TYPE_WARNING, - _ ("Ignoring to connect peer %u to peer %u\n"), + _ ("Ignoring to connect peer %lu to peer %lu\n"), peer_id, other_peer_id); while (('\n' != data[offset]) && ('|' != data[offset]) && (offset < fs)) diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 5ca5a4e86..e967e8e9a 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c @@ -75,6 +75,9 @@ */ #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS +#define WORKING_QUEUE_INTERVALL \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1) + /** * AES key size. */ @@ -90,6 +93,8 @@ */ #define GCM_TAG_SIZE (128 / 8) +#define GENERATE_AT_ONCE 2 + /** * If we fall below this number of available KCNs, * we generate additional ACKs until we reach @@ -129,7 +134,7 @@ * sense. Might make sense to adapt to RTT if we had * a good measurement... */ -#define MAX_SECRETS 128 +#define MAX_SECRETS 128000 /** * How often do we rekey based on number of bytes transmitted? @@ -250,6 +255,12 @@ struct UDPAck */ uint32_t sequence_max GNUNET_PACKED; + /** + * Sequence acknowledgement limit. Specifies current maximum sequence + * number supported by receiver. + */ + uint32_t acks_available GNUNET_PACKED; + /** * CMAC of the base key being acknowledged. */ @@ -499,6 +510,12 @@ struct SenderAddress */ unsigned int num_secrets; + /** + * Number of BOX keys from ACKs we have currently + * available for this sender. + */ + unsigned int acks_available; + /** * Which network type does this queue use? */ @@ -653,6 +670,15 @@ struct BroadcastInterface int found; }; +/** + * Timeout for this receiver address. + */ +struct GNUNET_TIME_Absolute *rekey_timeout; + +/** + * Shared secret we finished the last kce working queue for. + */ +struct SharedSecret *ss_finished; /** * Cache of pre-generated key IDs. @@ -669,6 +695,16 @@ static struct GNUNET_SCHEDULER_Task *read_task; */ static struct GNUNET_SCHEDULER_Task *timeout_task; +/** + * ID of kce working queue task + */ +static struct GNUNET_SCHEDULER_Task *kce_task; + +/** + * Is the kce_task finished? + */ +static int kce_task_finished = GNUNET_NO; + /** * ID of master broadcast task */ @@ -847,6 +883,7 @@ kce_destroy (struct KeyCacheEntry *kce) struct SharedSecret *ss = kce->ss; ss->active_kce_count--; + ss->sender->acks_available--; GNUNET_CONTAINER_DLL_remove (ss->kce_head, ss->kce_tail, kce); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (key_cache, &kce->kid, @@ -902,6 +939,7 @@ kce_generate (struct SharedSecret *ss, uint32_t seq) get_kid (&ss->master, seq, &kce->kid); GNUNET_CONTAINER_DLL_insert (ss->kce_head, ss->kce_tail, kce); ss->active_kce_count++; + ss->sender->acks_available++; (void) GNUNET_CONTAINER_multishortmap_put ( key_cache, &kce->kid, @@ -920,12 +958,20 @@ kce_generate (struct SharedSecret *ss, uint32_t seq) * @param ss shared secret to destroy */ static void -secret_destroy (struct SharedSecret *ss) +secret_destroy (struct SharedSecret *ss, int withoutKce) { struct SenderAddress *sender; struct ReceiverAddress *receiver; struct KeyCacheEntry *kce; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "secret destroy %u %u\n", + withoutKce, + ss->sequence_allowed); + + if (withoutKce && (ss->sequence_allowed > 0)) + return; + if (NULL != (sender = ss->sender)) { GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss); @@ -935,7 +981,9 @@ secret_destroy (struct SharedSecret *ss) { GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); receiver->num_secrets--; + // Uncomment this for alternativ 1 of backchannel functionality receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used); + // Until here for alternativ 1 } while (NULL != (kce = ss->kce_head)) kce_destroy (kce); @@ -1284,8 +1332,11 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) { const struct UDPAck *ack = cls; struct ReceiverAddress *receiver = value; + struct SharedSecret *pos; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "in handle ack\n"); + struct SharedSecret *ss_to_destroy; (void) pid; for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) @@ -1301,9 +1352,12 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) if (allowed > ss->sequence_allowed) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%u > %u (%u)\n", allowed, ss->sequence_allowed, - receiver->acks_available); - + "%u > %u (%u %u) for secrect %s\n", allowed, + ss->sequence_allowed, + receiver->acks_available, + ack->acks_available, + GNUNET_h2s (&ss->master)); + // Uncomment this for alternativ 1 of backchannel functionality receiver->acks_available += (allowed - ss->sequence_allowed); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Tell transport we have more acks!\n"); @@ -1312,11 +1366,33 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) (allowed - ss->sequence_allowed), 1); + // Until here for alternativ 1 ss->sequence_allowed = allowed; /* move ss to head to avoid discarding it anytime soon! */ GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); + pos = receiver->ss_head; + while ( NULL != pos) + { + ss_to_destroy = pos; + pos = pos->next; + + secret_destroy (ss_to_destroy, GNUNET_YES); + } } + + // Uncomment this for alternativ 2 of backchannel functionality + /*if (receiver->acks_available != ack->acks_available) + { + receiver->acks_available = ack->acks_available; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Tell transport we have different number of acks!\n"); + GNUNET_TRANSPORT_communicator_mq_update (ch, + receiver->d_qh, + receiver->acks_available, + 1); + }*/ + // Until here for alternativ 2 return GNUNET_NO; } } @@ -1370,6 +1446,36 @@ try_handle_plaintext (struct SenderAddress *sender, } } +static void +kce_generate_cb (void *cls) +{ + struct SharedSecret *ss = cls; + + + + if (ss->sender->acks_available < KCN_TARGET) + { + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Precomputing keys\n"); + + for (int i = 0; i < GENERATE_AT_ONCE; i++) + kce_generate (ss, ++ss->sequence_allowed); + + kce_task = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, + kce_generate_cb, + ss); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "We have enough keys.\n"); + ss_finished = ss; + kce_task_finished = GNUNET_YES; + } + + +} /** * We established a shared secret with a sender. We should try to send @@ -1378,21 +1484,81 @@ try_handle_plaintext (struct SenderAddress *sender, * recently). * * @param ss shared secret to generate ACKs for + * @param intial The SharedSecret came with initial KX. */ static void -consider_ss_ack (struct SharedSecret *ss) +consider_ss_ack (struct SharedSecret *ss, int initial) { + struct SharedSecret *ss_to_destroy; + struct SharedSecret *pos; + GNUNET_assert (NULL != ss->sender); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering SS UDPAck %s\n", GNUNET_i2s_full (&ss->sender->target)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "We have %u acks available.\n", + ss->sender->acks_available); /* drop ancient KeyCacheEntries */ while ((NULL != ss->kce_head) && (MAX_SQN_DELTA < ss->kce_head->sequence_number - ss->kce_tail->sequence_number)) kce_destroy (ss->kce_tail); - if (ss->active_kce_count < KCN_THRESHOLD) + + + if (GNUNET_NO == initial) + kce_generate (ss, ++ss->sequence_allowed); + + /*if (0 == ss->sender->acks_available) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Generating keys\n"); + while (ss->active_kce_count < KCN_TARGET) + kce_generate (ss, ++ss->sequence_allowed); + }*/ + + if (((NULL != kce_task) && kce_task_finished) || (GNUNET_NO == initial)) + { + struct UDPAck ack; + + ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); + ack.header.size = htons (sizeof(ack)); + ack.sequence_max = htonl (ss_finished->sequence_allowed); + ack.acks_available = ss->sender->acks_available; + ack.cmac = ss_finished->cmac; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Notifying transport of UDPAck %s with intial %u\n", + GNUNET_i2s_full (&ss_finished->sender->target), + initial); + GNUNET_TRANSPORT_communicator_notify (ch, + &ss_finished->sender->target, + COMMUNICATOR_ADDRESS_PREFIX, + &ack.header); + pos = ss->sender->ss_head; + while ( NULL != pos) + { + ss_to_destroy = pos; + pos = pos->next; + secret_destroy (ss_to_destroy, GNUNET_YES); + } + kce_task = NULL; + } + else if (((NULL == kce_task) && (KCN_THRESHOLD > + ss->sender->acks_available)) || + (ss->sender->num_secrets > MAX_SECRETS) ) + { + + // kce_generate (ss, ++ss->sequence_allowed); + // kce_generate (ss, ++ss->sequence_allowed); + kce_task = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, + kce_generate_cb, + ss); + + } + + + /*if (ss->active_kce_count < KCN_THRESHOLD) { struct UDPAck ack; @@ -1402,11 +1568,13 @@ consider_ss_ack (struct SharedSecret *ss) * For the initial KX (active_kce_count==0), * we only generate a single KCE to prevent * unnecessary overhead. - */ - if (0 < ss->active_kce_count) { + + if (0 < ss->active_kce_count) + { while (ss->active_kce_count < KCN_TARGET) kce_generate (ss, ++ss->sequence_allowed); - } else { + } + else { kce_generate (ss, ++ss->sequence_allowed); } ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK); @@ -1420,7 +1588,7 @@ consider_ss_ack (struct SharedSecret *ss) &ss->sender->target, COMMUNICATOR_ADDRESS_PREFIX, &ack.header); - } + }*/ } @@ -1459,8 +1627,11 @@ decrypt_box (const struct UDPBox *box, "# bytes decrypted with BOX", sizeof(out_buf), GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "decrypted UDPBox with kid %s\n", + GNUNET_sh2s (&box->kid)); try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); - consider_ss_ack (ss); + consider_ss_ack (ss, GNUNET_NO); } @@ -1530,8 +1701,8 @@ setup_sender (const struct GNUNET_PeerIdentity *target, { struct SenderAddress *sender; struct SearchContext sc = { .address = address, - .address_len = address_len, - .sender = NULL }; + .address_len = address_len, + .sender = NULL }; GNUNET_CONTAINER_multipeermap_get_multiple (senders, target, @@ -1547,10 +1718,10 @@ setup_sender (const struct GNUNET_PeerIdentity *target, sender->address = GNUNET_memdup (address, address_len); sender->address_len = address_len; (void) GNUNET_CONTAINER_multipeermap_put ( - senders, - &sender->target, - sender, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + senders, + &sender->target, + sender, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GNUNET_STATISTICS_set (stats, "# senders active", GNUNET_CONTAINER_multipeermap_size (receivers), @@ -1587,10 +1758,10 @@ verify_confirmation (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, uhs.ephemeral = *ephemeral; uhs.monotonic_time = uc->monotonic_time; return GNUNET_CRYPTO_eddsa_verify ( - GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, - &uhs, - &uc->sender_sig, - &uc->sender.public_key); + GNUNET_SIGNATURE_COMMUNICATOR_UDP_HANDSHAKE, + &uhs, + &uc->sender_sig, + &uc->sender.public_key); } @@ -1610,22 +1781,22 @@ sockaddr_to_udpaddr_string (const struct sockaddr *address, switch (address->sa_family) { - case AF_INET: - GNUNET_asprintf (&ret, - "%s-%s", - COMMUNICATOR_ADDRESS_PREFIX, - GNUNET_a2s (address, address_len)); - break; + case AF_INET: + GNUNET_asprintf (&ret, + "%s-%s", + COMMUNICATOR_ADDRESS_PREFIX, + GNUNET_a2s (address, address_len)); + break; - case AF_INET6: - GNUNET_asprintf (&ret, - "%s-%s", - COMMUNICATOR_ADDRESS_PREFIX, - GNUNET_a2s (address, address_len)); - break; + case AF_INET6: + GNUNET_asprintf (&ret, + "%s-%s", + COMMUNICATOR_ADDRESS_PREFIX, + GNUNET_a2s (address, address_len)); + break; - default: - GNUNET_assert (0); + default: + GNUNET_assert (0); } return ret; } @@ -1744,10 +1915,10 @@ sock_read (void *cls) "Unable to decrypt tag, dropping...\n"); GNUNET_free (ss); GNUNET_STATISTICS_update ( - stats, - "# messages dropped (no kid, AEAD decryption failed)", - 1, - GNUNET_NO); + stats, + "# messages dropped (no kid, AEAD decryption failed)", + 1, + GNUNET_NO); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1778,9 +1949,9 @@ sock_read (void *cls) 1, GNUNET_NO); try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc)); - consider_ss_ack (ss); - if (sender->num_secrets > MAX_SECRETS) - secret_destroy (sender->ss_tail); + consider_ss_ack (ss, GNUNET_YES); + /*if (sender->num_secrets > MAX_SECRETS) + secret_destroy (sender->ss_tail);*/ } } @@ -1859,9 +2030,9 @@ udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len) else { GNUNET_log ( - GNUNET_ERROR_TYPE_ERROR, - "BINDTO specification `%s' invalid: last ':' not followed by number\n", - bindto); + GNUNET_ERROR_TYPE_ERROR, + "BINDTO specification `%s' invalid: last ':' not followed by number\n", + bindto); GNUNET_free (cp); return NULL; } @@ -1939,8 +2110,8 @@ do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size) memcpy (pad, &hdr, sizeof(hdr)); } GNUNET_assert ( - 0 == - gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad))); + 0 == + gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad))); } @@ -1967,6 +2138,19 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, size_t dpos; gcry_cipher_hd_t out_cipher; struct SharedSecret *ss; + struct SharedSecret *ss_to_destroy; + struct SharedSecret *pos; + + if (receiver->num_secrets > MAX_SECRETS) + { + pos = receiver->ss_head; + while ( NULL != pos) + { + ss_to_destroy = pos; + pos = pos->next; + secret_destroy (ss_to_destroy, GNUNET_YES); + } + } GNUNET_assert (mq == receiver->kx_mq); @@ -2007,13 +2191,13 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq, dpos += sizeof(uc); /* Append encrypted payload to dgram */ GNUNET_assert ( - 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); + 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); dpos += msize; do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); /* Datagram starts with kx */ kx.ephemeral = uhs.ephemeral; GNUNET_assert ( - 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); + 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); gcry_cipher_close (out_cipher); memcpy (dgram, &kx, sizeof(kx)); if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, @@ -2044,6 +2228,8 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, { struct ReceiverAddress *receiver = impl_state; uint16_t msize = ntohs (msg->size); + struct GNUNET_TIME_Relative rt; + struct SharedSecret *pos; GNUNET_assert (mq == receiver->d_mq); if ((msize > receiver->d_mtu) || @@ -2058,7 +2244,18 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, /* begin "BOX" encryption method, scan for ACKs from tail! */ for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev) { + if (0 < ss->sequence_used) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n", + GNUNET_h2s (&ss->master), + ss->sequence_used, + ss->sequence_allowed); + // Uncomment this for alternativ 1 of backchannel functionality if (ss->sequence_used >= ss->sequence_allowed) + // Until here for alternativ 1 + // Uncomment this for alternativ 2 of backchannel functionality + // if (0 == ss->sequence_allowed) + // Until here for alternativ 2 { continue; } @@ -2074,7 +2271,7 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, /* Append encrypted payload to dgram */ dpos = sizeof(struct UDPBox); GNUNET_assert ( - 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); + 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); dpos += msize; do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos); GNUNET_assert (0 == gcry_cipher_gettag (out_cipher, @@ -2087,14 +2284,43 @@ mq_send_d (struct GNUNET_MQ_Handle *mq, receiver->address, receiver->address_len)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending UDPBox to %s\n", GNUNET_a2s (receiver->address, + receiver->address_len)); GNUNET_MQ_impl_send_continue (mq); - receiver->acks_available--; + // receiver->acks_available--; if (0 == receiver->acks_available) { /* We have no more ACKs */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more acks\n"); } + + /* (NULL == rekey_timeout) + rekey_timeout = GNUNET_TIME_relative_to_absolute (REKEY_TIME_INTERVAL); + else + { + rt = GNUNET_TIME_absolute_get_remaining (rekey_timeout); + if (0 == rt.rel_value_us) + { + rekey_timeout = NULL; + pos = receiver->ss_head; + while ( NULL != pos) + { + ss_to_destroy = pos; + pos = pos->next; + secret_destroy (ss_to_destroy, GNUNET_NO); + } + if (0 != receiver->acks_available) + GNUNET_TRANSPORT_communicator_mq_update (ch, + receiver->d_qh, + // TODO We can not do this. But how can we signal this queue is not able to handle a message. Test code interprets q-len as additional length. + -receiver->acks_available, + 1); + } + }*/ + + return; } } @@ -2205,25 +2431,25 @@ setup_receiver_mq (struct ReceiverAddress *receiver) // GNUNET_assert (NULL == receiver->mq); switch (receiver->address->sa_family) { - case AF_INET: - base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ - - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */ - - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; - break; + case AF_INET: + base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ + - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */ + - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; + break; - case AF_INET6: - base_mtu = 1280 /* Minimum MTU required by IPv6 */ - - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */ - - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; - break; + case AF_INET6: + base_mtu = 1280 /* Minimum MTU required by IPv6 */ + - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */ + - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */; + break; - default: - GNUNET_assert (0); - break; + default: + GNUNET_assert (0); + break; } /* MTU based on full KX messages */ receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */ - - sizeof(struct UDPConfirmation); /* 104 */ + - sizeof(struct UDPConfirmation); /* 104 */ /* MTU based on BOXed messages */ receiver->d_mtu = base_mtu - sizeof(struct UDPBox); @@ -2314,10 +2540,10 @@ mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address) receiver->target = *peer; receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len); (void) GNUNET_CONTAINER_multipeermap_put ( - receivers, - &receiver->target, - receiver, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + receivers, + &receiver->target, + receiver, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added %s to receivers\n", GNUNET_i2s_full (&receiver->target)); @@ -2553,55 +2779,55 @@ ifc_broadcast (void *cls) switch (bi->sa->sa_family) { - case AF_INET: { - static int yes = 1; - static int no = 0; - ssize_t sent; - - if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, - SOL_SOCKET, - SO_BROADCAST, - &yes, - sizeof(int))) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); - sent = GNUNET_NETWORK_socket_sendto (udp_sock, - &bi->bcm, - sizeof(bi->bcm), - bi->ba, - bi->salen); - if (-1 == sent) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); - if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, - SOL_SOCKET, - SO_BROADCAST, - &no, - sizeof(int))) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); - break; - } - - case AF_INET6: { - ssize_t sent; - struct sockaddr_in6 dst; - - dst.sin6_family = AF_INET6; - dst.sin6_port = htons (my_port); - dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr; - dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id; - - sent = GNUNET_NETWORK_socket_sendto (udp_sock, - &bi->bcm, - sizeof(bi->bcm), - (const struct sockaddr *) &dst, - sizeof(dst)); - if (-1 == sent) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); - break; - } - - default: - GNUNET_break (0); - break; + case AF_INET: { + static int yes = 1; + static int no = 0; + ssize_t sent; + + if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, + SOL_SOCKET, + SO_BROADCAST, + &yes, + sizeof(int))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + sent = GNUNET_NETWORK_socket_sendto (udp_sock, + &bi->bcm, + sizeof(bi->bcm), + bi->ba, + bi->salen); + if (-1 == sent) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); + if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (udp_sock, + SOL_SOCKET, + SO_BROADCAST, + &no, + sizeof(int))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + break; + } + + case AF_INET6: { + ssize_t sent; + struct sockaddr_in6 dst; + + dst.sin6_family = AF_INET6; + dst.sin6_port = htons (my_port); + dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr; + dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id; + + sent = GNUNET_NETWORK_socket_sendto (udp_sock, + &bi->bcm, + sizeof(bi->bcm), + (const struct sockaddr *) &dst, + sizeof(dst)); + if (-1 == sent) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); + break; + } + + default: + GNUNET_break (0); + break; } } @@ -2683,7 +2909,7 @@ iface_proc (void *cls, (const struct sockaddr_in6 *) broadcast_addr; GNUNET_assert ( - 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr)); + 1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr)); /* http://tools.ietf.org/html/rfc2553#section-5.2: * @@ -2820,17 +3046,17 @@ run (void *cls, GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len)); switch (in->sa_family) { - case AF_INET: - my_port = ntohs (((struct sockaddr_in *) in)->sin_port); - break; + case AF_INET: + my_port = ntohs (((struct sockaddr_in *) in)->sin_port); + break; - case AF_INET6: - my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port); - break; + case AF_INET6: + my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port); + break; - default: - GNUNET_break (0); - my_port = 0; + default: + GNUNET_break (0); + my_port = 0; } stats = GNUNET_STATISTICS_create ("C-UDP", cfg); senders = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); @@ -2845,9 +3071,9 @@ run (void *cls, if (NULL == my_private_key) { GNUNET_log ( - GNUNET_ERROR_TYPE_ERROR, - _ ( - "Transport service is lacking key configuration settings. Exiting.\n")); + GNUNET_ERROR_TYPE_ERROR, + _ ( + "Transport service is lacking key configuration settings. Exiting.\n")); GNUNET_SCHEDULER_shutdown (); return; } @@ -2923,8 +3149,8 @@ main (int argc, char *const *argv) options, &run, NULL)) - ? 0 - : 1; + ? 0 + : 1; GNUNET_free_nz ((void *) argv); return ret; } diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 207c17f2f..92e37a91c 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -700,6 +700,7 @@ handle_send_transmit_continuation (void *cls, delay = GNUNET_TIME_absolute_get_duration (stcc->send_time); addr = GST_neighbour_get_current_address (&stcc->target); +#ifdef ENABLE_TTD if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "It took us %s to send %u/%u bytes to %s (%d, %s)\n", @@ -718,6 +719,7 @@ handle_send_transmit_continuation (void *cls, GNUNET_i2s (&stcc->target), success, (NULL != addr) ? addr->transport_name : "%"); +#endif if (GNUNET_NO == stcc->down) { diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 92ed2fe52..219fae57b 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c @@ -769,10 +769,10 @@ http_client_plugin_send (void *cls, char *stat_txt; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p/request %p: Sending message with %u to peer `%s' \n", + "Session %p/request %p: Sending message with %lu to peer `%s' \n", s, s->put.easyhandle, - msgbuf_size, + (unsigned long) msgbuf_size, GNUNET_i2s (&s->address->peer)); /* create new message and schedule */ @@ -1087,11 +1087,10 @@ client_send_cb (void *stream, if (msg->pos == msg->size) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p/request %p: sent message with %u bytes sent, removing message from queue\n", + "Session %p/request %p: sent message with %lu bytes sent, removing message from queue\n", s, s->put.easyhandle, - msg->size, - msg->pos); + (unsigned long) msg->size); /* Calling transmit continuation */ GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, @@ -1249,10 +1248,10 @@ client_receive (void *stream, size_t len = size * nmemb; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p / request %p: Received %u bytes from peer `%s'\n", + "Session %p / request %p: Received %lu bytes from peer `%s'\n", s, s->get.easyhandle, - len, + (unsigned long) len, GNUNET_i2s (&s->address->peer)); now = GNUNET_TIME_absolute_get (); if (now.abs_value_us < s->next_receive.abs_value_us) @@ -1346,7 +1345,7 @@ client_run (void *cls) /* Log status of terminated request */ if ((0 != msg->data.result) || (http_statuscode != 200)) LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p/request %p: %s request to `%s' ended with status %i reason %i: `%s'\n", + "Session %p/request %p: %s request to `%s' ended with status %li reason %i: `%s'\n", s, msg->easy_handle, (GNUNET_YES == put_request) ? "PUT" : "GET", GNUNET_i2s (&s->address->peer), diff --git a/src/transport/plugin_transport_http_common.c b/src/transport/plugin_transport_http_common.c index d81d6db9c..0e3778837 100644 --- a/src/transport/plugin_transport_http_common.c +++ b/src/transport/plugin_transport_http_common.c @@ -629,7 +629,7 @@ http_common_plugin_address_to_string (const char *plugin, if (addr_str[ntohl (address->urlen) - 1] != '\0') return NULL; GNUNET_asprintf (&res, "%s.%u.%s", plugin, ntohl (address->options), - &address[1]); + (char*)&address[1]); if (strlen (res) + 1 < 500) { GNUNET_memcpy (rbuf, res, strlen (res) + 1); diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index d1b21ba9c..6e95ca00c 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -745,10 +745,10 @@ http_server_plugin_send (void *cls, char *stat_txt; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p/request %p: Sending message with %u to peer `%s'\n", + "Session %p/request %p: Sending message with %lu to peer `%s'\n", session, session->server_send, - msgbuf_size, + (unsigned long) msgbuf_size, GNUNET_i2s (&session->target)); /* create new message and schedule */ @@ -1270,8 +1270,8 @@ server_parse_url (struct HTTP_Server_Plugin *plugin, if (hash_length != plugin->peer_id_length) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "URL target is %u bytes, expecting %u\n", - hash_length, plugin->peer_id_length); + "URL target is %lu bytes, expecting %u\n", + (unsigned long) hash_length, plugin->peer_id_length); return GNUNET_SYSERR; } if (GNUNET_OK != @@ -1616,8 +1616,8 @@ server_send_callback (void *cls, { sc->connected = GNUNET_YES; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Sent %u bytes to peer `%s' with session %p \n", - bytes_read, + "Sent %lu bytes to peer `%s' with session %p \n", + (unsigned long) bytes_read, GNUNET_i2s (&s->target), s); GNUNET_asprintf (&stat_txt, @@ -1761,14 +1761,14 @@ server_access_cb (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, _ ( - "Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %u\n"), + "Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %lu\n"), sc, plugin->cur_request, plugin->max_request, method, version, url, - (*upload_data_size)); + (unsigned long) (*upload_data_size)); if (NULL == sc) { /* CORS pre-flight request */ @@ -1868,19 +1868,19 @@ server_access_cb (void *cls, /* (*upload_data_size > 0) for every segment received */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %u bytes\n", + "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %lu bytes\n", s, sc, GNUNET_i2s (&s->target), http_common_plugin_address_to_string (plugin->protocol, s->address->address, s->address->address_length), - *upload_data_size); + (unsigned long) *upload_data_size); delay = GNUNET_TIME_absolute_get_remaining (s->next_receive); if (0 == delay.rel_value_us) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "PUT with %u bytes forwarded to MST\n", - *upload_data_size); + "PUT with %lu bytes forwarded to MST\n", + (unsigned long) *upload_data_size); if (s->msg_tk == NULL) { s->msg_tk = GNUNET_MST_create (&server_receive_mst_cb, diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index e3bc21543..8378a64dd 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -2010,8 +2010,8 @@ do_transmit (void *cls, size_t size, void *buf) GNUNET_assert (pos->message_size <= session->bytes_in_queue); session->bytes_in_queue -= pos->message_size; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Failed to transmit %u byte message to `%s'.\n", - pos->message_size, + "Failed to transmit %lu byte message to `%s'.\n", + (unsigned long) pos->message_size, GNUNET_i2s (&session->target)); ret += pos->message_size; GNUNET_CONTAINER_DLL_insert_after (hd, tl, tl, pos); @@ -2067,9 +2067,9 @@ do_transmit (void *cls, size_t size, void *buf) session->bytes_in_queue -= pos->message_size; GNUNET_assert (size >= pos->message_size); LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmitting message of type %u size %u to peer %s at %s\n", + "Transmitting message of type %u size %lu to peer %s at %s\n", ntohs (((struct GNUNET_MessageHeader *) pos->msg)->type), - pos->message_size, + (unsigned long) pos->message_size, GNUNET_i2s (&session->target), tcp_plugin_address_to_string (session->plugin, session->address->address, @@ -2192,8 +2192,8 @@ tcp_plugin_send (void *cls, pm->transmit_cont_cls = cont_cls; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to transmit %u bytes to `%s', added message to list.\n", - msgbuf_size, + "Asked to transmit %lu bytes to `%s', added message to list.\n", + (unsigned long) msgbuf_size, GNUNET_i2s (&session->target)); if (GNUNET_YES == diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index ec3a0edd8..49e84dfe7 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -1821,7 +1821,8 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) struct GNUNET_ATS_Session *session = frag_ctx->session; size_t msg_len = ntohs (msg->size); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueuing fragment with %u bytes\n", msg_len); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Enqueuing fragment with %lu bytes\n", + (unsigned long) msg_len); udpw = GNUNET_malloc (sizeof(struct UDP_MessageWrapper) + msg_len); udpw->session = session; udpw->msg_buf = (char *) &udpw[1]; @@ -1996,8 +1997,8 @@ udp_plugin_send (void *cls, return GNUNET_SYSERR; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "UDP transmits %u-byte message to `%s' using address `%s'\n", - udpmlen, + "UDP transmits %lu-byte message to `%s' using address `%s'\n", + (unsigned long) udpmlen, GNUNET_i2s (&s->target), udp_address_to_string (plugin, s->address->address, @@ -3113,18 +3114,18 @@ remove_timeout_messages_and_select (struct Plugin *plugin, { /* this message is not delayed */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Message for peer `%s' (%u bytes) is not delayed \n", + "Message for peer `%s' (%lu bytes) is not delayed \n", GNUNET_i2s (&udpw->session->target), - udpw->payload_size); + (unsigned long) udpw->payload_size); break; /* Found message to send, break */ } else { /* Message is delayed, try next */ LOG (GNUNET_ERROR_TYPE_DEBUG, - "Message for peer `%s' (%u bytes) is delayed for %s\n", + "Message for peer `%s' (%lu bytes) is delayed for %s\n", GNUNET_i2s (&udpw->session->target), - udpw->payload_size, + (unsigned long) udpw->payload_size, GNUNET_STRINGS_relative_time_to_string (remaining, GNUNET_YES)); udpw = udpw->next; } diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 9d3e7d354..2324914c9 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c @@ -1304,8 +1304,8 @@ unix_plugin_send (void *cls, return GNUNET_SYSERR; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "Sending %u bytes with session for peer `%s' `%s'\n", - msgbuf_size, + "Sending %lu bytes with session for peer `%s' `%s'\n", + (unsigned long) msgbuf_size, GNUNET_i2s (&session->target), unix_plugin_address_to_string (NULL, session->address->address, diff --git a/src/transport/tcp_connection_legacy.c b/src/transport/tcp_connection_legacy.c index 3e173b8a4..924362ef2 100644 --- a/src/transport/tcp_connection_legacy.c +++ b/src/transport/tcp_connection_legacy.c @@ -1142,9 +1142,9 @@ RETRY: return; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "receive_ready read %u/%u bytes from `%s' (%p)!\n", - (unsigned int) ret, - connection->max, + "receive_ready read %lu/%lu bytes from `%s' (%p)!\n", + (unsigned long) ret, + (unsigned long) connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection); GNUNET_assert (NULL != (receiver = connection->receiver)); @@ -1327,8 +1327,8 @@ connect_error (void *cls) GNUNET_CONNECTION_TransmitReadyNotify notify; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmission request of size %u fails (%s/%u), connection failed (%p).\n", - connection->nth.notify_size, + "Transmission request of size %lu fails (%s/%u), connection failed (%p).\n", + (unsigned long) connection->nth.notify_size, connection->hostname, connection->port, connection); @@ -1423,9 +1423,9 @@ RETRY: return; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection transmitted %u/%u bytes to `%s' (%p)\n", - (unsigned int) ret, - have, + "Connection transmitted %lu/%lu bytes to `%s' (%p)\n", + (unsigned long) ret, + (unsigned long) have, GNUNET_a2s (connection->addr, connection->addrlen), connection); connection->write_buffer_pos += ret; diff --git a/src/transport/tcp_service_legacy.c b/src/transport/tcp_service_legacy.c index 12dce3993..8606b353b 100644 --- a/src/transport/tcp_service_legacy.c +++ b/src/transport/tcp_service_legacy.c @@ -1433,7 +1433,7 @@ LEGACY_SERVICE_run (int argc, { clock_offset = skew_offset - skew_variance; GNUNET_TIME_set_offset (clock_offset); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); + LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %lld ms\n", clock_offset); } /* actually run service */ err = 0; diff --git a/src/transport/test_communicator_basic.c b/src/transport/test_communicator_basic.c index e3573ac2c..8251a5169 100644 --- a/src/transport/test_communicator_basic.c +++ b/src/transport/test_communicator_basic.c @@ -82,6 +82,11 @@ static struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *my_tc; static unsigned int iterations_left = TOTAL_ITERATIONS; +#define TIMEOUT_MULTIPLIER 1 + +#define DELAY \ + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,50) + #define SHORT_BURST_WINDOW \ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2) @@ -97,13 +102,21 @@ enum TestPhase }; -static size_t num_sent = 0; +static size_t num_sent_short = 0; + +static size_t num_sent_long = 0; + +static size_t num_sent_size = 0; static uint32_t ack = 0; static enum TestPhase phase; -static size_t num_received = 0; +static size_t num_received_short = 0; + +static size_t num_received_long = 0; + +static size_t num_received_size = 0; static uint64_t avg_latency = 0; @@ -230,6 +243,10 @@ make_payload (size_t payload_size) static void latency_timeout (void *cls) { + + size_t num_sent = 0; + size_t num_received = 0; + to_task = NULL; if (GNUNET_TIME_absolute_get_remaining (timeout).rel_value_us > 0) { @@ -239,6 +256,21 @@ latency_timeout (void *cls) return; } + switch (phase) + { + case TP_BURST_SHORT: + num_sent = num_sent_short; + num_received = num_received_short; + break; + case TP_BURST_LONG: + num_sent = num_sent_long; + num_received = num_received_long; + break; + case TP_SIZE_CHECK: + num_sent = num_sent_size; + num_received = num_received_size; + break; + } LOG (GNUNET_ERROR_TYPE_ERROR, "Latency too high. Test failed. (Phase: %d. Sent: %lu, Received: %lu)\n", phase, num_sent, num_received); @@ -246,6 +278,8 @@ latency_timeout (void *cls) GNUNET_SCHEDULER_shutdown (); } +/*static void + size_test (void *cls);*/ static void size_test (void *cls) @@ -253,6 +287,9 @@ size_test (void *cls) char *payload; size_t max_size = 64000; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "size_test_cb %u\n", + num_sent_size); GNUNET_assert (TP_SIZE_CHECK == phase); if (LONG_MESSAGE_SIZE != long_message_size) max_size = long_message_size; @@ -260,7 +297,7 @@ size_test (void *cls) return; /* Leave some room for our protocol, so not 2^16 exactly */ ack += 10; payload = make_payload (ack); - num_sent++; + num_sent_size++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, (ack < max_size) ? &size_test @@ -269,47 +306,98 @@ size_test (void *cls) payload, ack); GNUNET_free (payload); - timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); + timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER)); } +/*static void +size_test (void *cls) +{ + GNUNET_SCHEDULER_add_delayed (DELAY, + &size_test_cb, + NULL); + }*/ + +static void +long_test (void *cls); static void -long_test (void *cls) +long_test_cb (void *cls) { char *payload; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "long_test_cb %u/%u\n", + num_sent_long, + num_received_long); payload = make_payload (long_message_size); - num_sent++; + num_sent_long++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, - (BURST_PACKETS == - num_sent) + ((BURST_PACKETS + * 0.91 == + num_received_long) || + (BURST_PACKETS == + num_sent_long)) ? NULL : &long_test, NULL, payload, long_message_size); GNUNET_free (payload); - timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); + timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER)); } +static void +long_test (void *cls) +{ + /*LOG (GNUNET_ERROR_TYPE_DEBUG, + "long_test %u\n", + num_sent_long);*/ + GNUNET_SCHEDULER_add_delayed (DELAY, + &long_test_cb, + NULL); +} static void -short_test (void *cls) +short_test (void *cls); + +static void +short_test_cb (void *cls) { char *payload; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "short_test_cb %u/%u\n", + num_sent_short, + num_received_short); payload = make_payload (SHORT_MESSAGE_SIZE); - num_sent++; + num_sent_short++; GNUNET_TRANSPORT_TESTING_transport_communicator_send (my_tc, - (BURST_PACKETS == - num_sent) + ((BURST_PACKETS + * 0.91 == + num_received_short) || + (BURST_PACKETS == + num_sent_short)) ? NULL : &short_test, NULL, payload, SHORT_MESSAGE_SIZE); GNUNET_free (payload); - timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); + timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER)); +} + +static void +short_test (void *cls) +{ + GNUNET_SCHEDULER_add_delayed (DELAY, + &short_test_cb, + NULL); } @@ -373,12 +461,17 @@ add_queue_cb (void *cls, else long_message_size = LONG_MESSAGE_SIZE; phase = TP_BURST_SHORT; - timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); + timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER)); GNUNET_assert (NULL == to_task); - to_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, + to_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER), &latency_timeout, NULL); - prepare_test (NULL); + // prepare_test (NULL); + short_test (NULL); } @@ -388,10 +481,26 @@ update_avg_latency (const char*payload) struct GNUNET_TIME_AbsoluteNBO *ts_n; struct GNUNET_TIME_Absolute ts; struct GNUNET_TIME_Relative latency; + size_t num_received = 0; ts_n = (struct GNUNET_TIME_AbsoluteNBO *) payload; ts = GNUNET_TIME_absolute_ntoh (*ts_n); latency = GNUNET_TIME_absolute_get_duration (ts); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Latency of received packet: %u\n", + latency); + switch (phase) + { + case TP_BURST_SHORT: + num_received = num_received_short; + break; + case TP_BURST_LONG: + num_received = num_received_long; + break; + case TP_SIZE_CHECK: + num_received = num_received_size; + break; + } if (1 >= num_received) avg_latency = latency.rel_value_us; else @@ -400,7 +509,6 @@ update_avg_latency (const char*payload) } - /** * @brief Handle an incoming message * @@ -412,7 +520,8 @@ update_avg_latency (const char*payload) */ static void incoming_message_cb (void *cls, - struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle + struct + GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h, const char*payload, size_t payload_len) @@ -424,7 +533,9 @@ incoming_message_cb (void *cls, return; } /* Reset timeout */ - timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS); + timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply ( + GNUNET_TIME_UNIT_SECONDS, + TIMEOUT_MULTIPLIER)); switch (phase) { case TP_INIT: @@ -433,30 +544,31 @@ incoming_message_cb (void *cls, case TP_BURST_SHORT: { GNUNET_assert (SHORT_MESSAGE_SIZE == payload_len); - num_received++; + num_received_short++; duration = GNUNET_TIME_absolute_get_duration (start_short); update_avg_latency (payload); - if (num_received == BURST_PACKETS) + if (num_received_short == BURST_PACKETS * 0.91) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Short size packet test done.\n"); char *goodput = GNUNET_STRINGS_byte_size_fancy ((SHORT_MESSAGE_SIZE - * num_received * 1000 + * num_received_short + * 1000 * 1000) / duration.rel_value_us); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets in %llu us (%s/s) -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_short, + (unsigned long) num_sent_short, (unsigned long long) duration.rel_value_us, goodput, (unsigned long long) avg_latency); GNUNET_free (goodput); start_long = GNUNET_TIME_absolute_get (); phase = TP_BURST_LONG; - num_sent = 0; + // num_sent_short = 0; avg_latency = 0; - num_received = 0; + // num_received = 0; long_test (NULL); } break; @@ -467,32 +579,34 @@ incoming_message_cb (void *cls, { LOG (GNUNET_ERROR_TYPE_WARNING, "Ignoring packet with wrong length\n"); - return; // Ignore + return; // Ignore } - num_received++; + num_received_long++; duration = GNUNET_TIME_absolute_get_duration (start_long); update_avg_latency (payload); - if (num_received == BURST_PACKETS) + if (num_received_long == BURST_PACKETS * 0.91) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Long size packet test done.\n"); char *goodput = GNUNET_STRINGS_byte_size_fancy ((long_message_size - * num_received * 1000 + * num_received_long + * 1000 * 1000) - / duration.rel_value_us); + / duration. + rel_value_us); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets in %llu us (%s/s) -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_long, + (unsigned long) num_sent_long, (unsigned long long) duration.rel_value_us, goodput, (unsigned long long) avg_latency); GNUNET_free (goodput); ack = 0; phase = TP_SIZE_CHECK; - num_received = 0; - num_sent = 0; + // num_received = 0; + // num_sent_long = 0; avg_latency = 0; size_test (NULL); } @@ -505,25 +619,29 @@ incoming_message_cb (void *cls, GNUNET_assert (TP_SIZE_CHECK == phase); if (LONG_MESSAGE_SIZE != long_message_size) max_size = long_message_size; - num_received++; + num_received_size++; update_avg_latency (payload); - if (num_received >= (max_size) / 10) + if (num_received_size >= (max_size) / 10) { LOG (GNUNET_ERROR_TYPE_MESSAGE, "Size packet test done.\n"); LOG (GNUNET_ERROR_TYPE_MESSAGE, "%lu/%lu packets -- avg latency: %llu us\n", - (unsigned long) num_received, - (unsigned long) num_sent, + (unsigned long) num_received_size, + (unsigned long) num_sent_size, (unsigned long long) avg_latency); - num_received = 0; - num_sent = 0; + num_received_size = 0; + num_sent_size = 0; avg_latency = 0; iterations_left--; if (0 != iterations_left) { start_short = GNUNET_TIME_absolute_get (); phase = TP_BURST_SHORT; + num_sent_short = 0; + num_sent_long = 0; + num_received_short = 0; + num_received_long = 0; short_test (NULL); break; } @@ -561,8 +679,8 @@ static void run (void *cls) { ret = 0; - num_received = 0; - num_sent = 0; + // num_received = 0; + // num_sent = 0; for (unsigned int i = 0; i < NUM_PEERS; i++) { tc_hs[i] = GNUNET_TRANSPORT_TESTING_transport_communicator_service_start ( diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c index 98cfd5e29..076fbf331 100644 --- a/src/transport/transport-testing2.c +++ b/src/transport/transport-testing2.c @@ -553,7 +553,12 @@ handle_update_queue_message (void *cls, tc_queue->mtu = ntohl (msg->mtu); tc_queue->cs = msg->cs; tc_queue->priority = ntohl (msg->priority); + // Uncomment this for alternativ 1 of backchannel functionality tc_queue->q_len += GNUNET_ntohll (msg->q_len); + // Until here for alternativ 1 + // Uncomment this for alternativ 2 of backchannel functionality + // tc_queue->q_len = GNUNET_ntohll (msg->q_len); + // Until here for alternativ 2 GNUNET_SERVICE_client_continue (client->client); } @@ -1130,8 +1135,10 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_send } } GNUNET_assert (NULL != tc_queue); + // Uncomment this for alternativ 1 of backchannel functionality if (tc_queue->q_len != GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED) tc_queue->q_len--; + // Until here for alternativ 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message\n"); inbox_size = sizeof (struct GNUNET_MessageHeader) + payload_size; diff --git a/src/util/bio.c b/src/util/bio.c index 39050bb87..43a2abc89 100644 --- a/src/util/bio.c +++ b/src/util/bio.c @@ -356,10 +356,10 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, if (big > max_length) { GNUNET_asprintf (&h->emsg, - _ ("String `%s' longer than allowed (%u > %u)"), + _ ("String `%s' longer than allowed (%u > %lu)"), what, big, - max_length); + (unsigned long) max_length); return GNUNET_SYSERR; } buf = GNUNET_malloc (big); diff --git a/src/util/client.c b/src/util/client.c index 86dabe664..2df439175 100644 --- a/src/util/client.c +++ b/src/util/client.c @@ -654,7 +654,7 @@ try_connect_using_address (void *cls, "Trying to connect using address `%s:%u'\n", GNUNET_a2s (addr, addrlen), - cstate->port); + (unsigned int) cstate->port); ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen); ap->addr = (const struct sockaddr *) &ap[1]; GNUNET_memcpy (&ap[1], diff --git a/src/util/configuration_loader.c b/src/util/configuration_loader.c index b9e5cb67f..a59477b25 100644 --- a/src/util/configuration_loader.c +++ b/src/util/configuration_loader.c @@ -47,7 +47,8 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, base_config_varname = GNUNET_OS_project_data_get ()->base_config_varname; - if (NULL != (baseconfig = getenv (base_config_varname))) + if (NULL != base_config_varname + && NULL != (baseconfig = getenv (base_config_varname))) { baseconfig = GNUNET_strdup (baseconfig); } @@ -62,14 +63,16 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free (ipath); } - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_load_from (cfg, - baseconfig)) + char *dname = GNUNET_STRINGS_filename_expand (baseconfig); + GNUNET_free (baseconfig); + + if (GNUNET_YES == GNUNET_DISK_directory_test (dname, GNUNET_YES) && + GNUNET_SYSERR == GNUNET_CONFIGURATION_load_from (cfg, dname)) { - GNUNET_free (baseconfig); + GNUNET_free (dname); return GNUNET_SYSERR; /* no configuration at all found */ } - GNUNET_free (baseconfig); + GNUNET_free (dname); if ((NULL != filename) && (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename))) { diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 34b88d761..1f2dd2e5b 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -150,6 +150,8 @@ get_path_from_proc_maps () FILE *f; char *lgu; + if (NULL == current_pd->libname) + return NULL; GNUNET_snprintf (fn, sizeof(fn), "/proc/%u/maps", getpid ()); if (NULL == (f = fopen (fn, "r"))) return NULL; diff --git a/src/util/program.c b/src/util/program.c index 8bda34b4f..b5484855c 100644 --- a/src/util/program.c +++ b/src/util/program.c @@ -232,15 +232,20 @@ GNUNET_PROGRAM_run2 (int argc, sizeof(struct GNUNET_GETOPT_CommandLineOption), &cmd_sorter); loglev = NULL; - xdg = getenv ("XDG_CONFIG_HOME"); - if (NULL != xdg) - GNUNET_asprintf (&cfg_fn, - "%s%s%s", - xdg, - DIR_SEPARATOR_STR, - pd->config_file); + if (NULL != pd->config_file && NULL != pd->user_config_file) + { + xdg = getenv ("XDG_CONFIG_HOME"); + if (NULL != xdg) + GNUNET_asprintf (&cfg_fn, + "%s%s%s", + xdg, + DIR_SEPARATOR_STR, + pd->config_file); + else + cfg_fn = GNUNET_strdup (pd->user_config_file); + } else - cfg_fn = GNUNET_strdup (pd->user_config_file); + cfg_fn = NULL; lpfx = GNUNET_strdup (binaryName); if (NULL != (spc = strstr (lpfx, " "))) *spc = '\0'; @@ -269,7 +274,7 @@ GNUNET_PROGRAM_run2 (int argc, } else { - if (GNUNET_YES == GNUNET_DISK_file_test (cfg_fn)) + if (NULL != cfg_fn && GNUNET_YES == GNUNET_DISK_file_test (cfg_fn)) { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_fn)) { @@ -284,7 +289,7 @@ GNUNET_PROGRAM_run2 (int argc, goto cleanup; } } - else + else if (NULL != cfg_fn) { GNUNET_free (cfg_fn); cfg_fn = NULL; diff --git a/src/util/service.c b/src/util/service.c index ddd31181d..4c647430d 100644 --- a/src/util/service.c +++ b/src/util/service.c @@ -2120,7 +2120,9 @@ GNUNET_SERVICE_run_ (int argc, { clock_offset = skew_offset - skew_variance; GNUNET_TIME_set_offset (clock_offset); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Skewing clock by %lld ms\n", + (long long) clock_offset); } GNUNET_RESOLVER_connect (sh.cfg); diff --git a/src/util/strings.c b/src/util/strings.c index 9d6f4039e..0fb6eaf0c 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -176,7 +176,7 @@ GNUNET_STRINGS_buffer_tokenize (const char *buffer, char * GNUNET_STRINGS_byte_size_fancy (unsigned long long size) { - const char *unit = _ (/* size unit */ "b"); + const char *unit = /* size unit */ "b"; char *ret; if (size > 5 * 1024) @@ -703,43 +703,44 @@ GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta, int do_round) { static GNUNET_THREAD_LOCAL char buf[128]; - const char *unit = _ (/* time unit */ "µs"); + const char *unit = /* time unit */ "µs"; uint64_t dval = delta.rel_value_us; if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == delta.rel_value_us) - return _ ("forever"); + return "forever"; if (0 == delta.rel_value_us) - return _ ("0 ms"); + return "0 ms"; if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000))) { dval = dval / 1000; - unit = _ (/* time unit */ "ms"); + unit = /* time unit */ "ms"; if (((GNUNET_YES == do_round) && (dval > 5 * 1000)) || (0 == (dval % 1000))) { dval = dval / 1000; - unit = _ (/* time unit */ "s"); + unit = /* time unit */ "s"; if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) { dval = dval / 60; - unit = _ (/* time unit */ "m"); + unit = /* time unit */ "m"; if (((GNUNET_YES == do_round) && (dval > 5 * 60)) || (0 == (dval % 60))) { dval = dval / 60; - unit = _ (/* time unit */ "h"); + unit = /* time unit */ "h"; if (((GNUNET_YES == do_round) && (dval > 5 * 24)) || (0 == (dval % 24))) { dval = dval / 24; if (1 == dval) - unit = _ (/* time unit */ "day"); + unit = /* time unit */ "day"; else - unit = _ (/* time unit */ "days"); + unit = /* time unit */ "days"; } } } } } - GNUNET_snprintf (buf, sizeof(buf), "%llu %s", dval, unit); + GNUNET_snprintf (buf, sizeof(buf), "%llu %s", + (unsigned long long) dval, unit); return buf; } @@ -761,7 +762,7 @@ GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t) struct tm *tp; if (t.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) - return _ ("end of time"); + return "end of time"; tt = t.abs_value_us / 1000LL / 1000LL; tp = localtime (&tt); /* This is hacky, but i don't know a way to detect libc character encoding. diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am index 3d248efd8..f2d569c75 100644 --- a/src/zonemaster/Makefile.am +++ b/src/zonemaster/Makefile.am @@ -24,6 +24,7 @@ gnunet_service_zonemaster_SOURCES = \ gnunet_service_zonemaster_LDADD = \ $(top_builddir)/src/dht/libgnunetdht.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la \ @@ -32,10 +33,10 @@ gnunet_service_zonemaster_LDADD = \ gnunet_service_zonemaster_monitor_SOURCES = \ gnunet-service-zonemaster-monitor.c - gnunet_service_zonemaster_monitor_LDADD = \ $(top_builddir)/src/dht/libgnunetdht.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la \ diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c index 4a368048e..c6dd2b6ca 100644 --- a/src/zonemaster/gnunet-service-zonemaster-monitor.c +++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c @@ -240,7 +240,7 @@ convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, * @return DHT PUT handle, NULL on error */ static struct GNUNET_DHT_PutHandle * -perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd_public, unsigned int rd_public_count, @@ -271,9 +271,7 @@ perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, GNUNET_break (0); return NULL; /* whoops */ } - block_size = ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey); + block_size = GNUNET_GNSRECORD_block_get_size (block); GNUNET_GNSRECORD_query_from_private_key (key, label, &query); @@ -314,7 +312,7 @@ perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, */ static void handle_monitor_event (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c index c5aab8d92..11fa9921d 100644 --- a/src/zonemaster/gnunet-service-zonemaster.c +++ b/src/zonemaster/gnunet-service-zonemaster.c @@ -579,7 +579,7 @@ convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, * @return DHT PUT handle, NULL on error */ static struct GNUNET_DHT_PutHandle * -perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, +perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, const struct GNUNET_GNSRECORD_Data *rd_public, unsigned int rd_public_count, @@ -610,9 +610,7 @@ perform_dht_put (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, GNUNET_break (0); return NULL; /* whoops */ } - block_size = ntohl (block->purpose.size) - + sizeof(struct GNUNET_CRYPTO_EcdsaSignature) - + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey); + block_size = GNUNET_GNSRECORD_block_get_size (block); GNUNET_GNSRECORD_query_from_private_key (key, label, &query); @@ -725,7 +723,7 @@ zone_iteration_finished (void *cls) */ static void put_gns_record (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, + const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) -- cgit v1.2.3