X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fidentity%2Fgnunet-service-identity.c;h=7d635c2912df655f95649c5980b2f265633ff6ef;hb=cea95af17bb3bfaf65224d0ecd2db2308e333764;hp=4de7746b06343734b8cce1f5b56978d3a8572758;hpb=987795c6c7d4a0f04f989688341d93d684039a62;p=oweals%2Fgnunet.git diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c index 4de7746b0..7d635c291 100644 --- a/src/identity/gnunet-service-identity.c +++ b/src/identity/gnunet-service-identity.c @@ -25,6 +25,10 @@ * * The purpose of this service is to manage private keys that * represent the various egos/pseudonyms/identities of a GNUnet user. + * + * Todo: + * - auto-initialze default egos; maybe trigger default + * initializations (such as gnunet-gns-import.sh?) */ #include "platform.h" #include "gnunet_util_lib.h" @@ -43,18 +47,18 @@ struct Ego /** * We keep egos in a DLL. - */ + */ struct Ego *next; /** * We keep egos in a DLL. - */ + */ struct Ego *prev; /** * Private key of the ego. */ - struct GNUNET_CRYPTO_EccPrivateKey *pk; + struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; /** * String identifier for the ego. @@ -156,7 +160,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) while (NULL != (e = ego_head)) { GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, e); - GNUNET_CRYPTO_ecc_key_free (e->pk); + GNUNET_free (e->pk); + GNUNET_free (e->identifier); GNUNET_free (e); } } @@ -185,8 +190,13 @@ send_result_code (struct GNUNET_SERVER_Client *client, rcm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE); rcm->header.size = htons (sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) + elen); rcm->result_code = htonl (result_code); - memcpy (&rcm[1], emsg, elen); - GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, GNUNET_YES); + if (0 < elen) + memcpy (&rcm[1], emsg, elen); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending result %d (%s) to client\n", + (int) result_code, + emsg); + GNUNET_SERVER_notification_context_unicast (nc, client, &rcm->header, GNUNET_NO); GNUNET_free (rcm); } @@ -201,23 +211,16 @@ static struct GNUNET_IDENTITY_UpdateMessage * create_update_message (struct Ego *ego) { struct GNUNET_IDENTITY_UpdateMessage *um; - char *str; - uint16_t pk_len; size_t name_len; - struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded *enc; name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1); - enc = GNUNET_CRYPTO_ecc_encode_key (ego->pk); - pk_len = ntohs (enc->size); - um = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_UpdateMessage) + pk_len + name_len); + um = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_UpdateMessage) + name_len); um->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); - um->header.size = htons (sizeof (struct GNUNET_IDENTITY_UpdateMessage) + pk_len + name_len); + um->header.size = htons (sizeof (struct GNUNET_IDENTITY_UpdateMessage) + name_len); um->name_len = htons (name_len); - um->pk_len = htons (pk_len); - str = (char *) &um[1]; - memcpy (str, enc, pk_len); - memcpy (&str[pk_len], ego->identifier, name_len); - GNUNET_free (enc); + um->end_of_list = htons (GNUNET_NO); + um->private_key = *ego->pk; + memcpy (&um[1], ego->identifier, name_len); return um; } @@ -234,30 +237,23 @@ create_set_default_message (struct Ego *ego, const char *servicename) { struct GNUNET_IDENTITY_SetDefaultMessage *sdm; - char *str; - uint16_t pk_len; size_t name_len; - struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded *enc; name_len = (NULL == servicename) ? 0 : (strlen (servicename) + 1); - enc = GNUNET_CRYPTO_ecc_encode_key (ego->pk); - pk_len = ntohs (enc->size); - sdm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + pk_len + name_len); + sdm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + name_len); sdm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT); - sdm->header.size = htons (sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + pk_len + name_len); + sdm->header.size = htons (sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) + name_len); sdm->name_len = htons (name_len); - sdm->pk_len = htons (pk_len); - str = (char *) &sdm[1]; - memcpy (str, enc, pk_len); - memcpy (&str[pk_len], servicename, name_len); - GNUNET_free (enc); + sdm->reserved = htons (0); + sdm->private_key = *ego->pk; + memcpy (&sdm[1], servicename, name_len); return sdm; } /** * Handler for START message from client, sends information - * about all identities to the client immediately and + * about all identities to the client immediately and * adds the client to the notification context for future * updates. * @@ -270,17 +266,24 @@ handle_start_message (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct GNUNET_IDENTITY_UpdateMessage *um; + struct GNUNET_IDENTITY_UpdateMessage ume; struct Ego *ego; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received START message from client\n"); GNUNET_SERVER_notification_context_add (nc, client); for (ego = ego_head; NULL != ego; ego = ego->next) { um = create_update_message (ego); - GNUNET_SERVER_notification_context_unicast (nc, client, &um->header, GNUNET_YES); + GNUNET_SERVER_notification_context_unicast (nc, client, &um->header, GNUNET_NO); GNUNET_free (um); } + memset (&ume, 0, sizeof (ume)); + ume.header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); + ume.header.size = htons (sizeof (struct GNUNET_IDENTITY_UpdateMessage)); + ume.end_of_list = htons (GNUNET_YES); + ume.name_len = htons (0); + GNUNET_SERVER_notification_context_unicast (nc, client, &ume.header, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -305,8 +308,6 @@ handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, const char *name; char *identifier; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received GET_DEFAULT message from client\n"); size = ntohs (message->size); if (size <= sizeof (struct GNUNET_IDENTITY_GetDefaultMessage)) { @@ -325,6 +326,9 @@ handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received GET_DEFAULT for service `%s' from client\n", + name); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, name, @@ -332,7 +336,7 @@ handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, &identifier)) { send_result_code (client, 1, gettext_noop ("no default known")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } for (ego = ego_head; NULL != ego; ego = ego->next) @@ -342,13 +346,19 @@ handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, { sdm = create_set_default_message (ego, name); - GNUNET_SERVER_notification_context_broadcast (nc, &sdm->header, GNUNET_YES); + GNUNET_SERVER_notification_context_unicast (nc, client, + &sdm->header, GNUNET_NO); GNUNET_free (sdm); GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_free (identifier); return; } } - send_result_code (client, 1, + GNUNET_free (identifier); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Failed to find ego `%s'\n", + name); + send_result_code (client, 1, gettext_noop ("default configured, but ego unknown (internal error)")); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -356,21 +366,16 @@ handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, /** * Compare the given two private keys for equality. - * + * * @param pk1 one private key * @param pk2 another private key * @return 0 if the keys are equal */ static int -key_cmp (const struct GNUNET_CRYPTO_EccPrivateKey *pk1, - const struct GNUNET_CRYPTO_EccPrivateKey *pk2) +key_cmp (const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk1, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *pk2) { - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded p1; - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded p2; - - GNUNET_CRYPTO_ecc_key_get_public (pk1, &p1); - GNUNET_CRYPTO_ecc_key_get_public (pk2, &p2); - return memcmp (&p1, &p2, sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded)); + return memcmp (pk1, pk2, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); } @@ -389,13 +394,9 @@ handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_IDENTITY_SetDefaultMessage *sdm; uint16_t size; uint16_t name_len; - uint16_t pk_len; struct Ego *ego; const char *str; - struct GNUNET_CRYPTO_EccPrivateKey *pk; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received SET_DEFAULT message from client\n"); size = ntohs (message->size); if (size <= sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) { @@ -405,32 +406,33 @@ handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client, } sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) message; name_len = ntohs (sdm->name_len); - pk_len = ntohs (sdm->pk_len); - str = (const char *) &sdm[1]; - if ( (name_len + pk_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) != size) || - (NULL == (pk = GNUNET_CRYPTO_ecc_decode_key (str, pk_len, GNUNET_YES))) ) + GNUNET_break (0 == ntohs (sdm->reserved)); + if (name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) != size) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - str = &str[pk_len]; + str = (const char *) &sdm[1]; if ('\0' != str[name_len - 1]) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received SET_DEFAULT for service `%s' from client\n", + str); for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == key_cmp (ego->pk, - pk)) + &sdm->private_key)) { GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, str, "DEFAULT_IDENTIFIER", ego->identifier); - if (GNUNET_OK != + if (GNUNET_OK != GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -438,13 +440,11 @@ handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client, subsystem_cfg_file); send_result_code (client, 0, NULL); GNUNET_SERVER_receive_done (client, GNUNET_OK); - GNUNET_CRYPTO_ecc_key_free (pk); return; } - } + } send_result_code (client, 1, _("Unknown ego specified for service (internal error)")); GNUNET_SERVER_receive_done (client, GNUNET_OK); - GNUNET_CRYPTO_ecc_key_free (pk); } @@ -459,7 +459,7 @@ notify_listeners (struct Ego *ego) struct GNUNET_IDENTITY_UpdateMessage *um; um = create_update_message (ego); - GNUNET_SERVER_notification_context_broadcast (nc, &um->header, GNUNET_YES); + GNUNET_SERVER_notification_context_broadcast (nc, &um->header, GNUNET_NO); GNUNET_free (um); } @@ -479,14 +479,11 @@ handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_IDENTITY_CreateRequestMessage *crm; uint16_t size; uint16_t name_len; - uint16_t pk_len; struct Ego *ego; - const char *pks; const char *str; - struct GNUNET_CRYPTO_EccPrivateKey *pk; char *fn; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREATE message from client\n"); size = ntohs (message->size); if (size <= sizeof (struct GNUNET_IDENTITY_CreateRequestMessage)) @@ -497,16 +494,14 @@ handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, } crm = (const struct GNUNET_IDENTITY_CreateRequestMessage *) message; name_len = ntohs (crm->name_len); - pk_len = ntohs (crm->pk_len); - pks = (const char *) &crm[1]; - if ( (name_len + pk_len + sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) != size) || - (NULL == (pk = GNUNET_CRYPTO_ecc_decode_key (pks, pk_len, GNUNET_YES))) ) + GNUNET_break (0 == ntohs (crm->reserved)); + if (name_len + sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) != size) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - str = &pks[pk_len]; + str = (const char *) &crm[1]; if ('\0' != str[name_len - 1]) { GNUNET_break (0); @@ -520,12 +515,12 @@ handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, { send_result_code (client, 1, gettext_noop ("identifier already in use for another ego")); GNUNET_SERVER_receive_done (client, GNUNET_OK); - GNUNET_CRYPTO_ecc_key_free (pk); return; } } ego = GNUNET_new (struct Ego); - ego->pk = pk; + ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); + *ego->pk = crm->private_key; ego->identifier = GNUNET_strdup (str); GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, @@ -533,14 +528,16 @@ handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, send_result_code (client, 0, NULL); fn = get_ego_filename (ego); (void) GNUNET_DISK_directory_create_for_file (fn); - if (pk_len != - GNUNET_DISK_fn_write (fn, pks, pk_len, + if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) != + GNUNET_DISK_fn_write (fn, + &crm->private_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); GNUNET_free (fn); - notify_listeners (ego); + notify_listeners (ego); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -548,7 +545,7 @@ handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, /** * Closure for 'handle_ego_rename'. */ -struct RenameContext +struct RenameContext { /** * Old name. @@ -584,14 +581,14 @@ handle_ego_rename (void *cls, return; if (0 != strcmp (id, rc->old_name)) { - GNUNET_free (id); + GNUNET_free (id); return; } GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, section, "DEFAULT_IDENTIFIER", rc->new_name); - GNUNET_free (id); + GNUNET_free (id); } @@ -618,7 +615,7 @@ handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, char *fn_old; char *fn_new; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received RENAME message from client\n"); size = ntohs (message->size); if (size <= sizeof (struct GNUNET_IDENTITY_RenameMessage)) @@ -648,7 +645,7 @@ handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, new_name)) { send_result_code (client, 1, gettext_noop ("target name already exists")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } } @@ -666,14 +663,14 @@ handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, &handle_ego_rename, &rename_ctx); - if (GNUNET_OK != + if (GNUNET_OK != GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to write subsystem default identifier map to `%s'.\n"), subsystem_cfg_file); ego->identifier = GNUNET_strdup (new_name); - fn_new = get_ego_filename (ego); + fn_new = get_ego_filename (ego); if (0 != RENAME (fn_old, fn_new)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rename", fn_old); GNUNET_free (fn_old); @@ -713,14 +710,14 @@ handle_ego_delete (void *cls, return; if (0 != strcmp (id, identifier)) { - GNUNET_free (id); + GNUNET_free (id); return; } GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, section, "DEFAULT_IDENTIFIER", NULL); - GNUNET_free (id); + GNUNET_free (id); } @@ -743,7 +740,7 @@ handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, const char *name; char *fn; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received DELETE message from client\n"); size = ntohs (message->size); if (size <= sizeof (struct GNUNET_IDENTITY_DeleteMessage)) @@ -774,7 +771,7 @@ handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, &handle_ego_delete, ego->identifier); - if (GNUNET_OK != + if (GNUNET_OK != GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -787,7 +784,7 @@ handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_free (ego->identifier); ego->identifier = NULL; notify_listeners (ego); - GNUNET_CRYPTO_ecc_key_free (ego->pk); + GNUNET_free (ego->pk); GNUNET_free (ego); send_result_code (client, 0, NULL); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -806,9 +803,9 @@ handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, * * @param cls NULL * @param filename name of the file to parse - * @return GNUNET_OK to continue to iterate, - * GNUNET_NO to stop iteration with no error, - * GNUNET_SYSERR to abort iteration with error! + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to stop iteration with no error, + * #GNUNET_SYSERR to abort iteration with error! */ static int process_ego_file (void *cls, @@ -824,17 +821,19 @@ process_ego_file (void *cls, return GNUNET_OK; } ego = GNUNET_new (struct Ego); - ego->pk = GNUNET_CRYPTO_ecc_key_create_from_file (filename); + ego->pk = GNUNET_CRYPTO_ecdsa_key_create_from_file (filename); if (NULL == ego->pk) - { - GNUNET_free (ego); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Failed to parse ego information in `%s'\n"), - filename); - return GNUNET_OK; - } - - ego->identifier = GNUNET_strdup (fn); + { + GNUNET_free (ego); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to parse ego information in `%s'\n"), + filename); + return GNUNET_OK; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Loaded ego `%s'\n", + fn + 1); + ego->identifier = GNUNET_strdup (fn + 1); GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, ego); @@ -850,7 +849,7 @@ process_ego_file (void *cls, * @param c configuration to use */ static void -run (void *cls, +run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { @@ -889,10 +888,13 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Loading subsystem configuration `%s'\n", + subsystem_cfg_file); subsystem_cfg = GNUNET_CONFIGURATION_create (); if ( (GNUNET_YES == GNUNET_DISK_file_test (subsystem_cfg_file)) && - (GNUNET_OK != + (GNUNET_OK != GNUNET_CONFIGURATION_parse (subsystem_cfg, subsystem_cfg_file)) ) { @@ -905,6 +907,13 @@ run (void *cls, stats = GNUNET_STATISTICS_create ("identity", cfg); GNUNET_SERVER_add_handlers (server, handlers); nc = GNUNET_SERVER_notification_context_create (server, 1); + if (GNUNET_OK != + GNUNET_DISK_directory_create (ego_directory)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to create directory `%s' for storing egos\n"), + ego_directory); + } GNUNET_DISK_directory_scan (ego_directory, &process_ego_file, NULL); @@ -924,7 +933,7 @@ int main (int argc, char *const *argv) { return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "identity", + GNUNET_SERVICE_run (argc, argv, "identity", GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1; }