aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/gnunet-service-core.c86
-rw-r--r--src/core/gnunet-service-core_kx.c23
-rw-r--r--src/core/gnunet-service-core_kx.h3
-rw-r--r--src/fs/fs_uri.c3
-rw-r--r--src/include/gnunet_crypto_lib.h11
-rw-r--r--src/include/gnunet_server_lib.h18
-rw-r--r--src/mesh/gnunet-service-mesh.c154
-rw-r--r--src/nse/gnunet-service-nse.c195
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c14
-rw-r--r--src/transport/gnunet-service-transport.c109
-rw-r--r--src/transport/test_plugin_transport.c68
-rw-r--r--src/util/crypto_random.c37
-rw-r--r--src/util/crypto_rsa.c46
-rw-r--r--src/util/gnunet-rsa.c10
-rw-r--r--src/util/server.c95
15 files changed, 576 insertions, 296 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 59d938364d..f5d01cd27e 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -48,21 +48,39 @@ const struct GNUNET_CONFIGURATION_Handle *GSC_cfg;
*/
struct GNUNET_STATISTICS_Handle *GSC_stats;
+/**
+ * Handle to the server of the core service.
+ */
+static struct GNUNET_SERVER_Handle *GSC_server;
+
+/**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
+
/**
* Last task run during shutdown. Disconnects us from
* the transport.
+ *
+ * @param cls NULL, unused
+ * @param tc scheduler context, unused
*/
static void
-cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
+ if (NULL != GST_keygen)
+ {
+ GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
+ GST_keygen = NULL;
+ }
GSC_CLIENTS_done ();
GSC_NEIGHBOURS_done ();
GSC_SESSIONS_done ();
GSC_KX_done ();
GSC_TYPEMAP_done ();
- if (GSC_stats != NULL)
+ if (NULL != GSC_stats)
{
GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO);
GSC_stats = NULL;
@@ -71,6 +89,42 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
+
+/**
+ * Callback for hostkey read/generation
+ *
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
+ */
+static void
+key_generation_cb (void *cls,
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+ const char *emsg)
+{
+ GST_keygen = NULL;
+ if (NULL == pk)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to read hostkey: %s\n"),
+ emsg);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if ((GNUNET_OK != GSC_KX_init (pk)) ||
+ (GNUNET_OK != GSC_NEIGHBOURS_init ()))
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GSC_SESSIONS_init ();
+ GSC_CLIENTS_init (GSC_server);
+ GNUNET_SERVER_resume (GSC_server);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
+ GNUNET_i2s (&GSC_my_identity));
+}
+
+
/**
* Initiate core service.
*
@@ -82,24 +136,36 @@ static void
run (void *cls, struct GNUNET_SERVER_Handle *server,
const struct GNUNET_CONFIGURATION_Handle *c)
{
+ char *keyfile;
+
GSC_cfg = c;
+ GSC_server = server;
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
+ &keyfile))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _
+ ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
NULL);
+ GNUNET_SERVER_suspend (server);
GSC_TYPEMAP_init ();
- if ((GNUNET_OK != GSC_KX_init ()) || (GNUNET_OK != GSC_NEIGHBOURS_init ()))
+ GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
+ GNUNET_free (keyfile);
+ if (NULL == GST_keygen)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Transport service is unable to access hostkey. Exiting.\n"));
GNUNET_SCHEDULER_shutdown ();
- return;
}
- GSC_SESSIONS_init ();
- GSC_CLIENTS_init (server);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
- GNUNET_i2s (&GSC_my_identity));
}
-
/**
* The main function for the transport service.
*
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index f5bea09e5f..755d0c34cf 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -1686,30 +1686,13 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
/**
* Initialize KX subsystem.
*
+ * @param pk private key to use for the peer
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
*/
int
-GSC_KX_init ()
+GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk)
{
- char *keyfile;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
- &keyfile))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
- return GNUNET_SYSERR;
- }
- my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- GNUNET_free (keyfile);
- if (NULL == my_private_key)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Core service could not access hostkey. Exiting.\n"));
- return GNUNET_SYSERR;
- }
+ my_private_key = pk;
GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
&GSC_my_identity.hashPubKey);
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h
index 5ecd2c17f8..fcb561e01c 100644
--- a/src/core/gnunet-service-core_kx.h
+++ b/src/core/gnunet-service-core_kx.h
@@ -121,10 +121,11 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx);
/**
* Initialize KX subsystem.
*
+ * @param pk private key to use for the peer
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
*/
int
-GSC_KX_init (void);
+GSC_KX_init (struct GNUNET_CRYPTO_RsaPrivateKey *pk);
/**
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index ad21692c9a..0f41689183 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -903,8 +903,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri,
_("Lacking key configuration settings.\n"));
return NULL;
}
- my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- if (my_private_key == NULL)
+ if (NULL == (my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not access hostkey file `%s'.\n"), keyfile);
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index b73d26d1e8..710ef31790 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1085,6 +1085,17 @@ void
GNUNET_CRYPTO_random_disable_entropy_gathering (void);
+/**
+ * Check if we are using weak random number generation.
+ *
+ * @return GNUNET_YES if weak number generation is on
+ * (thus will return YES if 'GNUNET_CRYPTO_random_disable_entropy_gathering'
+ * was called previously).
+ */
+int
+GNUNET_CRYPTO_random_is_weak (void);
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
index 73fe8000e6..aaf47aca51 100644
--- a/src/include/gnunet_server_lib.h
+++ b/src/include/gnunet_server_lib.h
@@ -155,6 +155,24 @@ GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access, void *access_cls,
/**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
+
+
+/**
* Stop the listen socket and get ready to shutdown the server
* once only 'monitor' clients are left.
*
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 2ce30c82fc..e40a3de966 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
+ (C) 2001-2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -816,6 +816,12 @@ static long long unsigned int dht_replication_level;
static long long unsigned int max_tunnels;
static long long unsigned int max_msgs_queue;
+
+/**
+ * Hostkey generation context
+ */
+static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
+
/**
* DLL with all the clients, head.
*/
@@ -7684,6 +7690,7 @@ shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
return GNUNET_YES;
}
+
/**
* Task run during shutdown.
*
@@ -7700,6 +7707,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CORE_disconnect (core_handle);
core_handle = NULL;
}
+ if (NULL != keygen)
+ {
+ GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+ keygen = NULL;
+ }
GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
if (dht_handle != NULL)
@@ -7720,6 +7732,76 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
}
+
+/**
+ * Callback for hostkey read/generation
+ *
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
+ */
+static void
+key_generation_cb (void *cls,
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+ const char *emsg)
+{
+ struct MeshPeerInfo *peer;
+ struct MeshPeerPath *p;
+
+ keygen = NULL;
+ if (NULL == pk)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Mesh service could not access hostkey. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ my_private_key = pk;
+ GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
+ GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
+ &my_full_id.hashPubKey);
+ myid = GNUNET_PEER_intern (&my_full_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Mesh for peer [%s] starting\n",
+ GNUNET_i2s(&my_full_id));
+
+// transport_handle = GNUNET_TRANSPORT_connect(c,
+// &my_full_id,
+// NULL,
+// NULL,
+// NULL,
+// NULL);
+
+
+
+ next_tid = 0;
+ next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+
+
+ GNUNET_SERVER_add_handlers (server_handle, client_handlers);
+ nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
+ GNUNET_SERVER_disconnect_notify (server_handle,
+ &handle_local_client_disconnect, NULL);
+
+
+ clients = NULL;
+ clients_tail = NULL;
+ next_client_id = 0;
+
+ announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
+ announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
+
+ /* Create a peer_info for the local peer */
+ peer = peer_info_get (&my_full_id);
+ p = path_new (1);
+ p->peers[0] = myid;
+ GNUNET_PEER_change_rc (myid, 1);
+ peer_info_add_path (peer, p, GNUNET_YES);
+ GNUNET_SERVER_resume (server_handle);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
+}
+
+
/**
* Process mesh requests.
*
@@ -7731,8 +7813,6 @@ static void
run (void *cls, struct GNUNET_SERVER_Handle *server,
const struct GNUNET_CONFIGURATION_Handle *c)
{
- struct MeshPeerInfo *peer;
- struct MeshPeerPath *p;
char *keyfile;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
@@ -7873,76 +7953,28 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
dht_replication_level = 10;
}
-
- my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- GNUNET_free (keyfile);
- if (my_private_key == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Mesh service could not access hostkey. Exiting.\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
- GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
- &my_full_id.hashPubKey);
- myid = GNUNET_PEER_intern (&my_full_id);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Mesh for peer [%s] starting\n",
- GNUNET_i2s(&my_full_id));
-
-// transport_handle = GNUNET_TRANSPORT_connect(c,
-// &my_full_id,
-// NULL,
-// NULL,
-// NULL,
-// NULL);
-
- dht_handle = GNUNET_DHT_connect (c, 64);
- if (dht_handle == NULL)
- {
- GNUNET_break (0);
- }
-
- stats = GNUNET_STATISTICS_create ("mesh", c);
-
-
- next_tid = 0;
- next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
-
tunnels = GNUNET_CONTAINER_multihashmap_create (32);
incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
peers = GNUNET_CONTAINER_multihashmap_create (32);
applications = GNUNET_CONTAINER_multihashmap_create (32);
types = GNUNET_CONTAINER_multihashmap_create (32);
- GNUNET_SERVER_add_handlers (server_handle, client_handlers);
- nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
- GNUNET_SERVER_disconnect_notify (server_handle,
- &handle_local_client_disconnect, NULL);
-
-
- clients = NULL;
- clients_tail = NULL;
- next_client_id = 0;
-
- announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
- announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
-
- /* Create a peer_info for the local peer */
- peer = peer_info_get (&my_full_id);
- p = path_new (1);
- p->peers[0] = myid;
- GNUNET_PEER_change_rc (myid, 1);
- peer_info_add_path (peer, p, GNUNET_YES);
+ dht_handle = GNUNET_DHT_connect (c, 64);
+ if (NULL == dht_handle)
+ {
+ GNUNET_break (0);
+ }
+ stats = GNUNET_STATISTICS_create ("mesh", c);
+ GNUNET_SERVER_suspend (server_handle);
/* Scheduled the task to clean up when shutdown is called */
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
NULL);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "end of run()\n");
+ keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
+ GNUNET_free (keyfile);
}
+
/**
* The main function for the mesh service.
*
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 3031e68532..435f227744 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -304,6 +304,16 @@ static struct GNUNET_PeerIdentity my_identity;
*/
static uint64_t my_proof;
+/**
+ * Handle to this serivce's server.
+ */
+static struct GNUNET_SERVER_Handle *srv;
+
+/**
+ * Hostkey generation context
+ */
+static struct GNUNET_CRYPTO_RsaKeyGenerationContext *keygen;
+
/**
* Initialize a message to clients with the current network
@@ -576,7 +586,7 @@ transmit_ready (void *cls, size_t size, void *buf)
GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0), &transmit_task_cb,
peer_entry);
}
- if ((ntohl (size_estimate_messages[idx].hop_count) == 0) &&
+ if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
(GNUNET_SCHEDULER_NO_TASK != proof_task))
{
GNUNET_STATISTICS_update (stats,
@@ -584,7 +594,7 @@ transmit_ready (void *cls, size_t size, void *buf)
1, GNUNET_NO);
return 0;
}
- if (ntohs (size_estimate_messages[idx].header.size) == 0)
+ if (0 == ntohs (size_estimate_messages[idx].header.size))
{
GNUNET_STATISTICS_update (stats,
"# flood messages not generated (lack of history)",
@@ -661,7 +671,8 @@ update_network_size_estimate ()
* @param ts timestamp to use
*/
static void
-setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
+setup_flood_message (unsigned int slot,
+ struct GNUNET_TIME_Absolute ts)
{
struct GNUNET_NSE_FloodMessage *fm;
uint32_t matching_bits;
@@ -699,7 +710,9 @@ setup_flood_message (unsigned int slot, struct GNUNET_TIME_Absolute ts)
* @return GNUNET_OK (continue to iterate)
*/
static int
-schedule_current_round (void *cls, const struct GNUNET_HashCode * key, void *value)
+schedule_current_round (void *cls,
+ const struct GNUNET_HashCode * key,
+ void *value)
{
struct NSEPeerEntry *peer_entry = value;
struct GNUNET_TIME_Relative delay;
@@ -958,7 +971,7 @@ update_flood_times (void *cls, const struct GNUNET_HashCode * key, void *value)
struct NSEPeerEntry *peer_entry = value;
struct GNUNET_TIME_Relative delay;
- if (peer_entry->th != NULL)
+ if (NULL != peer_entry->th)
return GNUNET_OK; /* already active */
if (peer_entry == exclude)
return GNUNET_OK; /* trigger of the update */
@@ -966,14 +979,14 @@ update_flood_times (void *cls, const struct GNUNET_HashCode * key, void *value)
{
/* still stuck in previous round, no point to update, check that
* we are active here though... */
- if (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task &&
- NULL == peer_entry->th)
+ if ( (GNUNET_SCHEDULER_NO_TASK == peer_entry->transmit_task) &&
+ (NULL == peer_entry->th) )
{
GNUNET_break (0);
}
return GNUNET_OK;
}
- if (peer_entry->transmit_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != peer_entry->transmit_task)
{
GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
@@ -1099,7 +1112,7 @@ handle_p2p_size_estimate (void *cls, const struct GNUNET_PeerIdentity *peer,
GNUNET_SCHEDULER_cancel (peer_entry->transmit_task);
peer_entry->transmit_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (peer_entry->th != NULL)
+ if (NULL != peer_entry->th)
{
GNUNET_CORE_notify_transmit_ready_cancel (peer_entry->th);
peer_entry->th = NULL;
@@ -1228,7 +1241,7 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
GNUNET_SCHEDULER_cancel (pos->transmit_task);
pos->transmit_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (pos->th != NULL)
+ if (NULL != pos->th)
{
GNUNET_CORE_notify_transmit_ready_cancel (pos->th);
pos->th = NULL;
@@ -1247,44 +1260,49 @@ handle_core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- if (flood_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != flood_task)
{
GNUNET_SCHEDULER_cancel (flood_task);
flood_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (proof_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != proof_task)
{
GNUNET_SCHEDULER_cancel (proof_task);
proof_task = GNUNET_SCHEDULER_NO_TASK;
write_proof (); /* remember progress */
}
- if (nc != NULL)
+ if (NULL != keygen)
+ {
+ GNUNET_CRYPTO_rsa_key_create_stop (keygen);
+ keygen = NULL;
+ }
+ if (NULL != nc)
{
GNUNET_SERVER_notification_context_destroy (nc);
nc = NULL;
}
- if (coreAPI != NULL)
+ if (NULL != coreAPI)
{
GNUNET_CORE_disconnect (coreAPI);
coreAPI = NULL;
}
- if (stats != NULL)
+ if (NULL != stats)
{
GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
stats = NULL;
}
- if (peers != NULL)
+ if (NULL != peers)
{
GNUNET_CONTAINER_multihashmap_destroy (peers);
peers = NULL;
}
- if (my_private_key != NULL)
+ if (NULL != my_private_key)
{
GNUNET_CRYPTO_rsa_key_free (my_private_key);
my_private_key = NULL;
}
#if ENABLE_HISTOGRAM
- if (wh != NULL)
+ if (NULL != wh)
{
GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (wh));
wh = NULL;
@@ -1341,19 +1359,17 @@ core_init (void *cls, struct GNUNET_CORE_Handle *server,
/**
- * Handle network size estimate clients.
+ * Callback for hostkey read/generation
*
- * @param cls closure
- * @param server the initialized server
- * @param c configuration to use
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
*/
static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
- const struct GNUNET_CONFIGURATION_Handle *c)
+key_generation_cb (void *cls,
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+ const char *emsg)
{
- char *keyfile;
- char *proof;
-
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
{&handle_start_message, NULL, GNUNET_MESSAGE_TYPE_NSE_START,
sizeof (struct GNUNET_MessageHeader)},
@@ -1364,52 +1380,18 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
sizeof (struct GNUNET_NSE_FloodMessage)},
{NULL, 0, 0}
};
- cfg = c;
-
- if ((GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
- &gnunet_nse_interval)) ||
- (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
- &proof_find_delay)) ||
- (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
- &nse_work_required)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("NSE service is lacking key configuration settings. Exiting.\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Invalid work requirement for NSE service. Exiting.\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
+ char *proof;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY",
- &keyfile))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("NSE service is lacking key configuration settings. Exiting.\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- GNUNET_free (keyfile);
- if (my_private_key == NULL)
+ keygen = NULL;
+ if (NULL == pk)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("NSE service could not access hostkey. Exiting.\n"));
+ _("NSE service could not access hostkey: %s\n"),
+ emsg);
GNUNET_SCHEDULER_shutdown ();
return;
}
+ my_private_key = pk;
GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
&my_identity.hashPubKey);
@@ -1419,11 +1401,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_
("NSE service is lacking key configuration settings. Exiting.\n"));
- if (my_private_key != NULL)
- {
- GNUNET_CRYPTO_rsa_key_free (my_private_key);
- my_private_key = NULL;
- }
+ GNUNET_CRYPTO_rsa_key_free (my_private_key);
+ my_private_key = NULL;
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -1437,8 +1416,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
&find_proof, NULL);
peers = GNUNET_CONTAINER_multihashmap_create (128);
- GNUNET_SERVER_add_handlers (server, handlers);
- nc = GNUNET_SERVER_notification_context_create (server, 1);
+ GNUNET_SERVER_add_handlers (srv, handlers);
+ nc = GNUNET_SERVER_notification_context_create (srv, 1);
/* Connect to core service and register core handlers */
coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */
NULL, /* Closure passed to functions */
@@ -1450,8 +1429,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
NULL, /* Don't want notified about all outbound messages */
GNUNET_NO, /* For header only outbound notification */
core_handlers); /* Register these handlers */
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
- NULL);
+ if (NULL == coreAPI)
+ {
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
#if ENABLE_HISTOGRAM
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM", &proof))
@@ -1460,17 +1442,70 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GNUNET_free (proof);
}
#endif
- if (coreAPI == NULL)
+ stats = GNUNET_STATISTICS_create ("nse", cfg);
+ GNUNET_SERVER_resume (srv);
+}
+
+
+/**
+ * Handle network size estimate clients.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls,
+ struct GNUNET_SERVER_Handle *server,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+ char *keyfile;
+
+ cfg = c;
+ srv = server;
+ if ((GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL",
+ &gnunet_nse_interval)) ||
+ (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY",
+ &proof_find_delay)) ||
+ (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
+ &nse_work_required)))
{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _
+ ("NSE service is lacking key configuration settings. Exiting.\n"));
GNUNET_SCHEDULER_shutdown ();
return;
}
- stats = GNUNET_STATISTICS_create ("nse", cfg);
+ if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Invalid work requirement for NSE service. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY",
+ &keyfile))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _
+ ("NSE service is lacking key configuration settings. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
+ NULL);
+ GNUNET_SERVER_suspend (srv);
+ keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
+ GNUNET_free (keyfile);
}
/**
- * The main function for the statistics service.
+ * The main function for the network size estimation service.
*
* @param argc number of arguments from the command line
* @param argv command line arguments
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index d3637af44c..ddadcddd2c 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -394,10 +394,10 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer,
struct GNUNET_CRYPTO_HashAsciiEncoded enc;
struct PrintContext *pc;
- if (peer == NULL)
+ if (NULL == peer)
{
pic = NULL; /* end of iteration */
- if (err_msg != NULL)
+ if (NULL != err_msg)
{
FPRINTF (stderr,
_("Error in communication with PEERINFO service: %s\n"),
@@ -812,13 +812,14 @@ run (void *cls, char *const *args, const char *cfgfile,
char *fn;
cfg = c;
- if (args[0] != NULL)
+ if (NULL != args[0])
{
- FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]);
+ FPRINTF (stderr,
+ _("Invalid command line argument `%s'\n"),
+ args[0]);
return;
}
- peerinfo = GNUNET_PEERINFO_connect (cfg);
- if (peerinfo == NULL)
+ if (NULL == (peerinfo = GNUNET_PEERINFO_connect (cfg)))
{
FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n"));
return;
@@ -834,7 +835,6 @@ run (void *cls, char *const *args, const char *cfgfile,
"GNUNETD", "HOSTKEYFILE");
return;
}
-
if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn)))
{
FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn);
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 677d0033c9..f9a4c7b9ec 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -62,6 +62,16 @@ struct GNUNET_PeerIdentity GST_my_identity;
struct GNUNET_PEERINFO_Handle *GST_peerinfo;
/**
+ * Hostkey generation context
+ */
+struct GNUNET_CRYPTO_RsaKeyGenerationContext *GST_keygen;
+
+/**
+ * Handle to our service's server.
+ */
+static struct GNUNET_SERVER_Handle *GST_server;
+
+/**
* Our public key.
*/
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded GST_my_public_key;
@@ -271,7 +281,7 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer,
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK:
GST_neighbours_handle_session_ack (message, peer, &address, session, ats,
- ats_count);
+ ats_count);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT:
GST_neighbours_handle_disconnect_message (peer, message);
@@ -539,6 +549,11 @@ neighbours_address_notification (void *cls,
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ if (NULL != GST_keygen)
+ {
+ GNUNET_CRYPTO_rsa_key_create_stop (GST_keygen);
+ GST_keygen = NULL;
+ }
GST_neighbours_stop ();
GST_validation_stop ();
GST_plugins_unload ();
@@ -549,17 +564,17 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GST_blacklist_stop ();
GST_hello_stop ();
- if (GST_peerinfo != NULL)
+ if (NULL != GST_peerinfo)
{
GNUNET_PEERINFO_disconnect (GST_peerinfo);
GST_peerinfo = NULL;
}
- if (GST_stats != NULL)
+ if (NULL != GST_stats)
{
GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
GST_stats = NULL;
}
- if (GST_my_private_key != NULL)
+ if (NULL != GST_my_private_key)
{
GNUNET_CRYPTO_rsa_key_free (GST_my_private_key);
GST_my_private_key = NULL;
@@ -568,41 +583,32 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
- * Initiate transport service.
+ * Callback for hostkey read/generation
*
- * @param cls closure
- * @param server the initialized server
- * @param c configuration to use
+ * @param cls NULL
+ * @param pk the private key
+ * @param emsg error message
*/
static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
- const struct GNUNET_CONFIGURATION_Handle *c)
+key_generation_cb (void *cls,
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk,
+ const char *emsg)
{
- char *keyfile;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp;
- /* setup globals */
- GST_cfg = c;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
- &keyfile))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("Transport service is lacking key configuration settings. Exiting.\n"));
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
- GNUNET_free (keyfile);
- if (GST_my_private_key == NULL)
+
+ GST_keygen = NULL;
+ if (NULL == pk)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Transport service could not access hostkey. Exiting.\n"));
+ _("Transport service could not access hostkey: %s. Exiting.\n"),
+ emsg);
GNUNET_SCHEDULER_shutdown ();
return;
}
- GST_stats = GNUNET_STATISTICS_create ("transport", c);
- GST_peerinfo = GNUNET_PEERINFO_connect (c);
+ GST_my_private_key = pk;
+
+ GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
+ GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key));
memset (&tmp, '\0', sizeof (tmp));
GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
@@ -614,7 +620,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
NULL);
- if (GST_peerinfo == NULL)
+ if (NULL == GST_peerinfo)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not access PEERINFO service. Exiting.\n"));
@@ -625,7 +631,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
/* start subsystems */
GST_hello_start (&process_hello_update, NULL);
GNUNET_assert (NULL != GST_hello_get());
- GST_blacklist_start (server);
+ GST_blacklist_start (GST_server);
GST_ats =
GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL);
GST_plugins_load (&plugin_env_receive_callback,
@@ -636,8 +642,47 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
&neighbours_connect_notification,
&neighbours_disconnect_notification,
&neighbours_address_notification);
- GST_clients_start (server);
+ GST_clients_start (GST_server);
GST_validation_start ();
+ GNUNET_SERVER_resume (GST_server);
+}
+
+
+/**
+ * Initiate transport service.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls, struct GNUNET_SERVER_Handle *server,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+ char *keyfile;
+
+ /* setup globals */
+ GST_cfg = c;
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
+ &keyfile))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _
+ ("Transport service is lacking key configuration settings. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ GST_server = server;
+ GNUNET_SERVER_suspend (server);
+ GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
+ GNUNET_free (keyfile);
+ if (NULL == GST_keygen)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Transport service is unable to access hostkey. Exiting.\n"));
+ GNUNET_SCHEDULER_shutdown ();
+ }
}
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index e6a016c512..6882f919c3 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -139,6 +139,7 @@ struct AddressWrapper
char *addrstring;
};
+
static void
end ()
{
@@ -186,6 +187,7 @@ end ()
}
}
+
static void
end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
@@ -245,6 +247,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
ok = 1;
}
+
static void
wait_end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
@@ -290,6 +293,7 @@ env_receive (void *cls,
static int got_reply;
+
/**
* Take the given address and append it to the set of results sent back to
* the client.
@@ -435,7 +439,8 @@ env_notify_address (void *cls,
}
}
-struct GNUNET_ATS_Information
+
+static struct GNUNET_ATS_Information
env_get_address_type (void *cls,
const struct sockaddr *addr,
size_t addrlen)
@@ -446,19 +451,22 @@ env_get_address_type (void *cls,
return ats;
}
-const struct GNUNET_MessageHeader *
-env_get_our_hello (void)
+
+static const struct GNUNET_MessageHeader *
+env_get_our_hello ()
{
return (const struct GNUNET_MessageHeader *) hello;
}
-void env_session_end (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- struct Session * session)
-{
+static void
+env_session_end (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ struct Session * session)
+{
}
+
static void
setup_plugin_environment ()
{
@@ -482,6 +490,7 @@ handle_helper_message (void *cls, void *client,
return GNUNET_OK;
}
+
/**
* Runs the test.
*
@@ -502,33 +511,31 @@ run (void *cls, char *const *args, const char *cfgfile,
cfg = c;
/* parse configuration */
- if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c,
- "TRANSPORT",
- "NEIGHBOUR_LIMIT",
- &tneigh)) ||
- (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c,
- "GNUNETD", "HOSTKEY",
- &keyfile)))
+ if ( (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c,
+ "TRANSPORT",
+ "NEIGHBOUR_LIMIT",
+ &tneigh)) ||
+ (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c,
+ "GNUNETD", "HOSTKEY",
+ &keyfile)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Transport service is lacking key configuration settings. Exiting.\n"));
-
return;
}
- stats = GNUNET_STATISTICS_create ("transport", cfg);
- if (NULL == stats)
+ if (NULL == (stats = GNUNET_STATISTICS_create ("transport", cfg)))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Could not create statistics. Exiting.\n"));
- end_badly_now ();
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Could not create statistics. Exiting.\n"));
+ end_badly_now ();
+ return;
}
max_connect_per_transport = (uint32_t) tneigh;
my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
GNUNET_free (keyfile);
- if (my_private_key == NULL)
+ if (NULL == my_private_key)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Transport service could not access hostkey. Exiting.\n"));
@@ -638,7 +645,7 @@ run (void *cls, char *const *args, const char *cfgfile,
/**
- * The main function for the transport service.
+ * The main function for the test
*
* @param argc number of arguments from the command line
* @param argv command line arguments
@@ -656,20 +663,19 @@ main (int argc, char *const *argv)
"test_plugin_transport",
"-c",
"test_plugin_transport_data.conf",
- "-L", "WARNING",
NULL
};
GNUNET_log_setup ("test-plugin-transport",
"WARNING",
NULL);
ok = 1; /* set to fail */
- ret = (GNUNET_OK == GNUNET_PROGRAM_run (5,
- argv_prog,
- "test-plugin-transport",
- "testcase",
- options,
- &run,
- (void *) argv)) ? ok : 1;
+ ret = (GNUNET_OK == GNUNET_PROGRAM_run (3,
+ argv_prog,
+ "test-plugin-transport",
+ "testcase",
+ options,
+ &run,
+ (void *) argv)) ? ok : 1;
GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-plugin-transport");
return ret;
}
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index dbf71d78a4..8dce1080cc 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+ (C) 2001, 2002, 2003, 2004, 2005, 2006, 2012 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -34,6 +34,14 @@
#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
+
+/**
+ * GNUNET_YES if we are using a 'weak' (low-entropy) PRNG.
+ */
+static int weak_random;
+
+
+
/* TODO: ndurner, move this to plibc? */
/* The code is derived from glibc, obviously */
#if MINGW
@@ -49,14 +57,18 @@
#undef RAND_MAX
#endif
#define RAND_MAX 0x7fffffff /* Hopefully this is correct */
+
+
static int32_t glibc_weak_rand32_state = 1;
+
void
glibc_weak_srand32 (int32_t s)
{
glibc_weak_rand32_state = s;
}
+
int32_t
glibc_weak_rand32 ()
{
@@ -74,11 +86,12 @@ glibc_weak_rand32 ()
* @return number between 0 and 1.
*/
static double
-weak_random ()
+get_weak_random ()
{
return ((double) RANDOM () / RAND_MAX);
}
+
/**
* Seed a weak random generator. Only GNUNET_CRYPTO_QUALITY_WEAK-mode generator
* can be seeded.
@@ -91,6 +104,7 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed)
SRANDOM (seed);
}
+
/**
* Produce a random value.
*
@@ -134,7 +148,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i)
while (ret >= ul);
return ret % i;
case GNUNET_CRYPTO_QUALITY_WEAK:
- ret = i * weak_random ();
+ ret = i * get_weak_random ();
if (ret >= i)
ret = i - 1;
return ret;
@@ -211,7 +225,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
return ret % max;
case GNUNET_CRYPTO_QUALITY_WEAK:
- ret = max * weak_random ();
+ ret = max * get_weak_random ();
if (ret >= max)
ret = max - 1;
return ret;
@@ -221,6 +235,19 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
return 0;
}
+
+/**
+ * Check if we are using weak random number generation.
+ *
+ * @return GNUNET_YES if weak number generation is on
+ */
+int
+GNUNET_CRYPTO_random_is_weak ()
+{
+ return weak_random;
+}
+
+
/**
* This function should only be called in testcases
* where strong entropy gathering is not desired
@@ -229,6 +256,7 @@ GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
void
GNUNET_CRYPTO_random_disable_entropy_gathering ()
{
+ weak_random = GNUNET_YES;
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
}
@@ -239,6 +267,7 @@ GNUNET_CRYPTO_random_disable_entropy_gathering ()
*/
static struct GNUNET_OS_Process *genproc;
+
/**
* Function called by libgcrypt whenever we are
* blocked gathering entropy.
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index 4afda1f6e2..8843464a2f 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -629,11 +629,17 @@ try_read_key (const char *filename)
(void) GNUNET_DISK_file_close (fd);
return NULL;
}
+ if (0 == fs)
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
+ return NULL;
+ }
if (fs > UINT16_MAX)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _("File `%s' does not contain a valid private key. Deleting it.\n"),
- filename);
+ _("File `%s' does not contain a valid private key (too long, %llu bytes). Deleting it.\n"),
+ filename,
+ (unsigned long long) fs);
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
if (0 != UNLINK (filename))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -648,8 +654,9 @@ try_read_key (const char *filename)
(NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
- _("File `%s' does not contain a valid private key. Deleting it.\n"),
- filename);
+ _("File `%s' does not contain a valid private key (failed decode, %llu bytes). Deleting it.\n"),
+ filename,
+ (unsigned long long) fs);
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd));
if (0 != UNLINK (filename))
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
@@ -664,6 +671,23 @@ try_read_key (const char *filename)
/**
+ * Wait for a short time (we're trying to lock a file or want
+ * to give another process a shot at finishing a disk write, etc.).
+ * Sleeps for 100ms (as that should be long enough for virtually all
+ * modern systems to context switch and allow another process to do
+ * some 'real' work).
+ */
+static void
+short_wait ()
+{
+ struct GNUNET_TIME_Relative timeout;
+
+ timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100);
+ GNUNET_NETWORK_socket_select (NULL, NULL, NULL, timeout);
+}
+
+
+/**
* Create a new private key by reading it from a file. If the
* files does not exist, create a new key and write it to the
* file. Caller must free return value. Note that this function
@@ -723,7 +747,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
sizeof (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded),
GNUNET_YES))
{
- sleep (1);
+ short_wait (1);
if (0 == ++cnt % 10)
{
ec = errno;
@@ -781,7 +805,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
_
("This may be ok if someone is currently generating a hostkey.\n"));
}
- sleep (1);
+ short_wait (1);
continue;
}
if (GNUNET_YES != GNUNET_DISK_file_test (filename))
@@ -817,7 +841,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
_
("This may be ok if someone is currently generating a hostkey.\n"));
}
- sleep (2); /* wait a bit longer! */
+ short_wait (1); /* wait a bit longer! */
continue;
}
break;
@@ -996,6 +1020,7 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename,
{
struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc;
struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+ const char *weak_random;
if (NULL != (pk = try_read_key (filename)))
{
@@ -1023,13 +1048,18 @@ GNUNET_CRYPTO_rsa_key_create_start (const char *filename,
GNUNET_free (gc);
return NULL;
}
+ weak_random = NULL;
+ if (GNUNET_YES ==
+ GNUNET_CRYPTO_random_is_weak ())
+ weak_random = "-w";
gc->gnunet_rsa = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ERR,
NULL,
gc->gnunet_rsa_out,
"gnunet-rsa",
- "gnunet-rsa",
+ "gnunet-rsa",
gc->filename,
+ weak_random,
NULL);
if (NULL == gc->gnunet_rsa)
{
diff --git a/src/util/gnunet-rsa.c b/src/util/gnunet-rsa.c
index 61e1b66dff..e9fbf15dff 100644
--- a/src/util/gnunet-rsa.c
+++ b/src/util/gnunet-rsa.c
@@ -43,6 +43,11 @@ static int print_peer_identity;
*/
static int print_short_identity;
+/**
+ * Use weak random number generator for key generation.
+ */
+static int weak_random;
+
/**
* The private information of an RSA key pair.
@@ -104,6 +109,8 @@ run (void *cls, char *const *args, const char *cfgfile,
fprintf (stderr, _("No hostkey file specified on command line\n"));
return;
}
+ if (0 != weak_random)
+ GNUNET_CRYPTO_random_disable_entropy_gathering ();
pk = GNUNET_CRYPTO_rsa_key_create_from_file (args[0]);
if (NULL == pk)
return;
@@ -159,6 +166,9 @@ main (int argc, char *const *argv)
{ 's', "print-short-identity", NULL,
gettext_noop ("print the short hash of the public key in ASCII format"),
0, &GNUNET_GETOPT_set_one, &print_short_identity },
+ { 'w', "weak-random", NULL,
+ gettext_noop ("use insecure, weak random number generator for key generation (for testing only)"),
+ 0, &GNUNET_GETOPT_set_one, &weak_random },
GNUNET_GETOPT_OPTION_END
};
diff --git a/src/util/server.c b/src/util/server.c
index ff45846776..4622e0779c 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -334,43 +334,6 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
- * Add a listen task with the scheduler for this server.
- *
- * @param server handle to our server for which we are adding the listen
- * socket
- */
-static void
-schedule_listen_task (struct GNUNET_SERVER_Handle *server)
-{
- struct GNUNET_NETWORK_FDSet *r;
- unsigned int i;
-
- if (NULL == server->listen_sockets[0])
- return; /* nothing to do, no listen sockets! */
- if (NULL == server->listen_sockets[1])
- {
- /* simplified method: no fd set needed; this is then much simpler and
- much more efficient */
- server->listen_task =
- GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_SCHEDULER_PRIORITY_HIGH,
- server->listen_sockets[0],
- &process_listen_socket, server);
- return;
- }
- r = GNUNET_NETWORK_fdset_create ();
- i = 0;
- while (NULL != server->listen_sockets[i])
- GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
- server->listen_task =
- GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
- GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
- &process_listen_socket, server);
- GNUNET_NETWORK_fdset_destroy (r);
-}
-
-
-/**
* Scheduler says our listen socket is ready. Process it!
*
* @param cls handle to our server for which we are processing the listen
@@ -389,7 +352,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
/* ignore shutdown, someone else will take care of it! */
- schedule_listen_task (server);
+ GNUNET_SERVER_resume (server);
return;
}
i = 0;
@@ -412,7 +375,7 @@ process_listen_socket (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
i++;
}
/* listen for more! */
- schedule_listen_task (server);
+ GNUNET_SERVER_resume (server);
}
@@ -536,7 +499,7 @@ GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access,
server->access_cls = access_cls;
server->require_found = require_found;
if (NULL != lsocks)
- schedule_listen_task (server);
+ GNUNET_SERVER_resume (server);
return server;
}
@@ -671,6 +634,58 @@ test_monitor_clients (struct GNUNET_SERVER_Handle *server)
/**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != server->listen_task)
+ {
+ GNUNET_SCHEDULER_cancel (server->listen_task);
+ server->listen_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+}
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
+{
+ struct GNUNET_NETWORK_FDSet *r;
+ unsigned int i;
+
+ if (NULL == server->listen_sockets[0])
+ return; /* nothing to do, no listen sockets! */
+ if (NULL == server->listen_sockets[1])
+ {
+ /* simplified method: no fd set needed; this is then much simpler and
+ much more efficient */
+ server->listen_task =
+ GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_SCHEDULER_PRIORITY_HIGH,
+ server->listen_sockets[0],
+ &process_listen_socket, server);
+ return;
+ }
+ r = GNUNET_NETWORK_fdset_create ();
+ i = 0;
+ while (NULL != server->listen_sockets[i])
+ GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
+ server->listen_task =
+ GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+ GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+ &process_listen_socket, server);
+ GNUNET_NETWORK_fdset_destroy (r);
+}
+
+
+/**
* Stop the listen socket and get ready to shutdown the server
* once only 'monitor' clients are left.
*