X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fidentity%2Fgnunet-service-identity.c;h=155c49cc52f9cf9aaf75dc8c6b8d9943340581ba;hb=341c1dd692c62a88eeff34fca155ce2377677d4b;hp=52d0729674e6dd0abe3168c9c5d1778eea7d5ab8;hpb=cf45705470db25831f48452380021d1429973139;p=oweals%2Fgnunet.git diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c index 52d072967..155c49cc5 100644 --- a/src/identity/gnunet-service-identity.c +++ b/src/identity/gnunet-service-identity.c @@ -1,21 +1,19 @@ /* This file is part of GNUnet. - (C) 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2013 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + 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 - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + 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 . */ /** @@ -47,18 +45,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. @@ -87,7 +85,7 @@ static struct GNUNET_STATISTICS_Handle *stats; /** * Notification context, simplifies client broadcasts. */ -static struct GNUNET_SERVER_NotificationContext *nc; +static struct GNUNET_NotificationContext *nc; /** * Directory where we store the identities. @@ -129,21 +127,53 @@ get_ego_filename (struct Ego *ego) return filename; } +/** + * Called whenever a client is disconnected. + * + * @param cls closure + * @param client identification of the client + * @param app_ctx @a client + */ +static void +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + void *app_ctx) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client %p disconnected\n", + client); +} + + +/** + * Add a client to our list of active clients. + * + * @param cls NULL + * @param client client to add + * @param mq message queue for @a client + * @return internal namestore client structure for this client + */ +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) +{ + return client; +} /** * Task run during shutdown. * * @param cls unused - * @param tc unused */ static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls) { struct Ego *e; if (NULL != nc) { - GNUNET_SERVER_notification_context_destroy (nc); + GNUNET_notification_context_destroy (nc); nc = NULL; } if (NULL != stats) @@ -161,6 +191,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, e); GNUNET_free (e->pk); + GNUNET_free (e->identifier); GNUNET_free (e); } } @@ -174,29 +205,29 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param emsg error message to include (or NULL for none) */ static void -send_result_code (struct GNUNET_SERVER_Client *client, +send_result_code (struct GNUNET_SERVICE_Client *client, uint32_t result_code, const char *emsg) { - struct GNUNET_IDENTITY_ResultCodeMessage *rcm; + struct ResultCodeMessage *rcm; + struct GNUNET_MQ_Envelope *env; size_t elen; if (NULL == emsg) elen = 0; else elen = strlen (emsg) + 1; - rcm = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) + elen); - rcm->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE); - rcm->header.size = htons (sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) + elen); + env = GNUNET_MQ_msg_extra (rcm, + elen, + GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE); rcm->result_code = htonl (result_code); if (0 < elen) - memcpy (&rcm[1], emsg, elen); + GNUNET_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); + "Sending result %d (%s) to client\n", + (int) result_code, + emsg); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); } @@ -206,21 +237,22 @@ send_result_code (struct GNUNET_SERVER_Client *client, * @param ego ego to create message for * @return corresponding update message */ -static struct GNUNET_IDENTITY_UpdateMessage * +static struct GNUNET_MQ_Envelope * create_update_message (struct Ego *ego) { - struct GNUNET_IDENTITY_UpdateMessage *um; + struct UpdateMessage *um; + struct GNUNET_MQ_Envelope *env; size_t name_len; - + name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1); - 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) + name_len); + env = GNUNET_MQ_msg_extra (um, + name_len, + GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); um->name_len = htons (name_len); um->end_of_list = htons (GNUNET_NO); um->private_key = *ego->pk; - memcpy (&um[1], ego->identifier, name_len); - return um; + GNUNET_memcpy (&um[1], ego->identifier, name_len); + return env; } @@ -231,28 +263,29 @@ create_update_message (struct Ego *ego) * @param servicename name of the service to provide in the message * @return corresponding set default message */ -static struct GNUNET_IDENTITY_SetDefaultMessage * +static struct GNUNET_MQ_Envelope * create_set_default_message (struct Ego *ego, - const char *servicename) + const char *servicename) { - struct GNUNET_IDENTITY_SetDefaultMessage *sdm; + struct SetDefaultMessage *sdm; + struct GNUNET_MQ_Envelope *env; size_t name_len; name_len = (NULL == servicename) ? 0 : (strlen (servicename) + 1); - 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) + name_len); + env = GNUNET_MQ_msg_extra (sdm, + name_len, + GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT); sdm->name_len = htons (name_len); sdm->reserved = htons (0); sdm->private_key = *ego->pk; - memcpy (&sdm[1], servicename, name_len); - return sdm; + GNUNET_memcpy (&sdm[1], servicename, name_len); + return env; } /** * 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. * @@ -261,188 +294,225 @@ create_set_default_message (struct Ego *ego, * @param message the message received */ static void -handle_start_message (void *cls, struct GNUNET_SERVER_Client *client, +handle_start_message (void *cls, const struct GNUNET_MessageHeader *message) { - struct GNUNET_IDENTITY_UpdateMessage *um; - struct GNUNET_IDENTITY_UpdateMessage ume; + struct UpdateMessage *ume; + struct GNUNET_SERVICE_Client *client = cls; + struct GNUNET_MQ_Envelope *env; struct Ego *ego; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received START message from client\n"); - GNUNET_SERVER_notification_context_add (nc, client); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received START message from client\n"); + GNUNET_SERVICE_client_mark_monitor (client); + GNUNET_SERVICE_client_disable_continue_warning (client); + GNUNET_notification_context_add (nc, + GNUNET_SERVICE_client_get_mq(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_NO); - GNUNET_free (um); + env = create_update_message (ego); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(client), env); } - 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); + env = GNUNET_MQ_msg_extra (ume, + 0, + GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); + ume->end_of_list = htons (GNUNET_YES); + ume->name_len = htons (0); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(client), env); + GNUNET_SERVICE_client_continue (client); } - /** - * Handler for GET_DEFAULT message from client, returns - * default identity for some service. + * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT message * - * @param cls unused - * @param client who sent the message - * @param message the message received + * @param cls client sending the message + * @param msg message of type `struct GetDefaultMessage` + * @return #GNUNET_OK if @a msg is well-formed */ -static void -handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_get_default_message (void *cls, + const struct GetDefaultMessage *msg) { - const struct GNUNET_IDENTITY_GetDefaultMessage *gdm; - struct GNUNET_IDENTITY_SetDefaultMessage *sdm; uint16_t size; uint16_t name_len; - struct Ego *ego; const char *name; - char *identifier; - size = ntohs (message->size); - if (size <= sizeof (struct GNUNET_IDENTITY_GetDefaultMessage)) + size = ntohs (msg->header.size); + if (size <= sizeof (struct GetDefaultMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - gdm = (const struct GNUNET_IDENTITY_GetDefaultMessage *) message; - name = (const char *) &gdm[1]; - name_len = ntohs (gdm->name_len); - if ( (name_len + sizeof (struct GNUNET_IDENTITY_GetDefaultMessage) != size) || - (0 != ntohs (gdm->reserved)) || + name = (const char *) &msg[1]; + name_len = ntohs (msg->name_len); + if ( (name_len + sizeof (struct GetDefaultMessage) != size) || + (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]) ) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received GET_DEFAULT for service `%s' from client\n", - name); + return GNUNET_OK; +} + + +/** + * Handler for GET_DEFAULT message from client, returns + * default identity for some service. + * + * @param cls unused + * @param client who sent the message + * @param message the message received + */ +static void +handle_get_default_message (void *cls, + const struct GetDefaultMessage *gdm) +{ + struct GNUNET_MQ_Envelope *env; + struct GNUNET_SERVICE_Client *client = cls; + struct Ego *ego; + char *name; + char *identifier; + + + name = GNUNET_strdup ((const char *) &gdm[1]); + GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], name); + 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, - "DEFAULT_IDENTIFIER", - &identifier)) + name, + "DEFAULT_IDENTIFIER", + &identifier)) { send_result_code (client, 1, gettext_noop ("no default known")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); + GNUNET_free (name); return; } for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, - identifier)) + identifier)) { - sdm = create_set_default_message (ego, - name); - GNUNET_SERVER_notification_context_broadcast (nc, &sdm->header, GNUNET_NO); - GNUNET_free (sdm); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + env = create_set_default_message (ego, + name); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); + GNUNET_SERVICE_client_continue (client); GNUNET_free (identifier); + GNUNET_free (name); return; } } 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); + "Failed to find ego `%s'\n", + name); + GNUNET_free (name); + send_result_code (client, 1, + gettext_noop ("default configured, but ego unknown (internal error)")); + GNUNET_SERVICE_client_continue (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) { - return memcmp (pk1, pk2, sizeof (struct GNUNET_CRYPTO_EccPrivateKey)); + return memcmp (pk1, pk2, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); } - /** - * Handler for SET_DEFAULT message from client, updates - * default identity for some service. + * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT message * - * @param cls unused - * @param client who sent the message - * @param message the message received + * @param cls client sending the message + * @param msg message of type `struct SetDefaultMessage` + * @return #GNUNET_OK if @a msg is well-formed */ -static void -handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_set_default_message (void *cls, + const struct SetDefaultMessage *msg) { - const struct GNUNET_IDENTITY_SetDefaultMessage *sdm; uint16_t size; uint16_t name_len; - struct Ego *ego; const char *str; - size = ntohs (message->size); - if (size <= sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) + size = ntohs (msg->header.size); + if (size <= sizeof (struct SetDefaultMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) message; - name_len = ntohs (sdm->name_len); - GNUNET_break (0 == ntohs (sdm->reserved)); - if (name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage) != size) + name_len = ntohs (msg->name_len); + GNUNET_break (0 == ntohs (msg->reserved)); + if (name_len + sizeof (struct SetDefaultMessage) != size) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - str = (const char *) &sdm[1]; + str = (const char *) &msg[1]; if ('\0' != str[name_len - 1]) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received SET_DEFAULT for service `%s' from client\n", - str); + return GNUNET_OK; +} + +/** + * Handler for SET_DEFAULT message from client, updates + * default identity for some service. + * + * @param cls unused + * @param client who sent the message + * @param message the message received + */ +static void +handle_set_default_message (void *cls, + const struct SetDefaultMessage *sdm) +{ + struct Ego *ego; + struct GNUNET_SERVICE_Client *client = cls; + char *str; + + str = GNUNET_strdup ((const char *) &sdm[1]); + GNUNET_STRINGS_utf8_tolower ((const char *) &sdm[1], str); + + 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, - &sdm->private_key)) + &sdm->private_key)) { GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, - str, - "DEFAULT_IDENTIFIER", - ego->identifier); - 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); + str, + "DEFAULT_IDENTIFIER", + ego->identifier); + 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); send_result_code (client, 0, NULL); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); + GNUNET_free (str); return; } - } + } send_result_code (client, 1, _("Unknown ego specified for service (internal error)")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_free (str); + GNUNET_SERVICE_client_continue (client); } @@ -454,96 +524,122 @@ handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client, static void notify_listeners (struct Ego *ego) { - struct GNUNET_IDENTITY_UpdateMessage *um; + struct UpdateMessage *um; + size_t name_len; - um = create_update_message (ego); - GNUNET_SERVER_notification_context_broadcast (nc, &um->header, GNUNET_NO); + name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1); + um = GNUNET_malloc (sizeof (struct UpdateMessage) + name_len); + um->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); + um->header.size = htons (sizeof (struct UpdateMessage) + name_len); + um->name_len = htons (name_len); + um->end_of_list = htons (GNUNET_NO); + um->private_key = *ego->pk; + GNUNET_memcpy (&um[1], ego->identifier, name_len); + GNUNET_notification_context_broadcast (nc, + &um->header, + GNUNET_NO); GNUNET_free (um); } - /** - * Handler for CREATE message from client, creates - * new identity. + * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_CREATE message * - * @param cls unused - * @param client who sent the message - * @param message the message received + * @param cls client sending the message + * @param msg message of type `struct CreateRequestMessage` + * @return #GNUNET_OK if @a msg is well-formed */ -static void -handle_create_message (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_create_message (void *cls, + const struct CreateRequestMessage *msg) { - const struct GNUNET_IDENTITY_CreateRequestMessage *crm; + uint16_t size; uint16_t name_len; - struct Ego *ego; const char *str; - char *fn; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received CREATE message from client\n"); - size = ntohs (message->size); - if (size <= sizeof (struct GNUNET_IDENTITY_CreateRequestMessage)) + size = ntohs (msg->header.size); + if (size <= sizeof (struct CreateRequestMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - crm = (const struct GNUNET_IDENTITY_CreateRequestMessage *) message; - name_len = ntohs (crm->name_len); - GNUNET_break (0 == ntohs (crm->reserved)); - if (name_len + sizeof (struct GNUNET_IDENTITY_CreateRequestMessage) != size) + name_len = ntohs (msg->name_len); + GNUNET_break (0 == ntohs (msg->reserved)); + if (name_len + sizeof (struct CreateRequestMessage) != size) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - str = (const char *) &crm[1]; + str = (const char *) &msg[1]; if ('\0' != str[name_len - 1]) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + +/** + * Handler for CREATE message from client, creates + * new identity. + * + * @param cls unused + * @param client who sent the message + * @param message the message received + */ +static void +handle_create_message (void *cls, + const struct CreateRequestMessage *crm) +{ + struct GNUNET_SERVICE_Client *client = cls; + struct Ego *ego; + char *str; + char *fn; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received CREATE message from client\n"); + str = GNUNET_strdup ((const char *) &crm[1]); + GNUNET_STRINGS_utf8_tolower ((const char *) &crm[1], str); for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, - str)) + str)) { send_result_code (client, 1, gettext_noop ("identifier already in use for another ego")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); + GNUNET_free (str); return; } } ego = GNUNET_new (struct Ego); - ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); + 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, - ego); + ego_tail, + ego); send_result_code (client, 0, NULL); fn = get_ego_filename (ego); (void) GNUNET_DISK_directory_create_for_file (fn); - if (sizeof (struct GNUNET_CRYPTO_EccPrivateKey) != + if (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) != GNUNET_DISK_fn_write (fn, - &crm->private_key, - sizeof (struct GNUNET_CRYPTO_EccPrivateKey), - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE)) + &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); + "write", fn); GNUNET_free (fn); - notify_listeners (ego); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_free (str); + notify_listeners (ego); + GNUNET_SERVICE_client_continue (client); } /** * Closure for 'handle_ego_rename'. */ -struct RenameContext +struct RenameContext { /** * Old name. @@ -556,7 +652,6 @@ struct RenameContext const char *new_name; }; - /** * An ego was renamed; rename it in all subsystems where it is * currently set as the default. @@ -566,84 +661,109 @@ struct RenameContext */ static void handle_ego_rename (void *cls, - const char *section) + const char *section) { struct RenameContext *rc = cls; char *id; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, - section, - "DEFAULT_IDENTIFIER", - &id)) + section, + "DEFAULT_IDENTIFIER", + &id)) 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); + section, + "DEFAULT_IDENTIFIER", + rc->new_name); + GNUNET_free (id); } - /** - * Handler for RENAME message from client, creates - * new identity. + * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_RENAME message * - * @param cls unused - * @param client who sent the message - * @param message the message received + * @param cls client sending the message + * @param msg message of type `struct RenameMessage` + * @return #GNUNET_OK if @a msg is well-formed */ -static void -handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_rename_message (void *cls, + const struct RenameMessage *msg) { - const struct GNUNET_IDENTITY_RenameMessage *rm; uint16_t size; uint16_t old_name_len; uint16_t new_name_len; - struct Ego *ego; const char *old_name; const char *new_name; - struct RenameContext rename_ctx; - char *fn_old; - char *fn_new; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received RENAME message from client\n"); - size = ntohs (message->size); - if (size <= sizeof (struct GNUNET_IDENTITY_RenameMessage)) + size = ntohs (msg->header.size); + if (size <= sizeof (struct RenameMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - rm = (const struct GNUNET_IDENTITY_RenameMessage *) message; - old_name_len = ntohs (rm->old_name_len); - new_name_len = ntohs (rm->new_name_len); - old_name = (const char *) &rm[1]; + old_name_len = ntohs (msg->old_name_len); + new_name_len = ntohs (msg->new_name_len); + old_name = (const char *) &msg[1]; new_name = &old_name[old_name_len]; - if ( (old_name_len + new_name_len + sizeof (struct GNUNET_IDENTITY_RenameMessage) != size) || + if ( (old_name_len + new_name_len + sizeof (struct RenameMessage) != size) || ('\0' != old_name[old_name_len - 1]) || ('\0' != new_name[new_name_len - 1]) ) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handler for RENAME message from client, creates + * new identity. + * + * @param cls unused + * @param client who sent the message + * @param message the message received + */ +static void +handle_rename_message (void *cls, + const struct RenameMessage *rm) +{ + uint16_t old_name_len; + struct Ego *ego; + char *old_name; + char *new_name; + struct RenameContext rename_ctx; + struct GNUNET_SERVICE_Client *client = cls; + char *fn_old; + char *fn_new; + const char *old_name_tmp; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received RENAME message from client\n"); + old_name_len = ntohs (rm->old_name_len); + old_name_tmp = (const char *) &rm[1]; + old_name = GNUNET_strdup (old_name_tmp); + GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name); + new_name = GNUNET_strdup (&old_name_tmp[old_name_len]); + GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name); + /* check if new name is already in use */ for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, - new_name)) + new_name)) { send_result_code (client, 1, gettext_noop ("target name already exists")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); + GNUNET_free (old_name); + GNUNET_free (new_name); return; } } @@ -652,37 +772,41 @@ handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, - old_name)) + old_name)) { fn_old = get_ego_filename (ego); GNUNET_free (ego->identifier); rename_ctx.old_name = old_name; rename_ctx.new_name = new_name; GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, - &handle_ego_rename, - &rename_ctx); - 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); + &handle_ego_rename, + &rename_ctx); + 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_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rename", fn_old); GNUNET_free (fn_old); GNUNET_free (fn_new); + GNUNET_free (old_name); + GNUNET_free (new_name); notify_listeners (ego); send_result_code (client, 0, NULL); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); return; } } /* failed to locate old name */ send_result_code (client, 1, gettext_noop ("no matching ego found")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_free (old_name); + GNUNET_free (new_name); + GNUNET_SERVICE_client_continue (client); } @@ -695,103 +819,121 @@ handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client, */ static void handle_ego_delete (void *cls, - const char *section) + const char *section) { const char *identifier = cls; char *id; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, - section, - "DEFAULT_IDENTIFIER", - &id)) + section, + "DEFAULT_IDENTIFIER", + &id)) 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); + section, + "DEFAULT_IDENTIFIER", + NULL); + GNUNET_free (id); } - /** - * Handler for DELETE message from client, creates - * new identity. + * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_DELETE message * - * @param cls unused - * @param client who sent the message - * @param message the message received + * @param cls client sending the message + * @param msg message of type `struct DeleteMessage` + * @return #GNUNET_OK if @a msg is well-formed */ -static void -handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_delete_message (void *cls, + const struct DeleteMessage *msg) { - const struct GNUNET_IDENTITY_DeleteMessage *dm; uint16_t size; uint16_t name_len; - struct Ego *ego; const char *name; - char *fn; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received DELETE message from client\n"); - size = ntohs (message->size); - if (size <= sizeof (struct GNUNET_IDENTITY_DeleteMessage)) + size = ntohs (msg->header.size); + if (size <= sizeof (struct DeleteMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - dm = (const struct GNUNET_IDENTITY_DeleteMessage *) message; - name = (const char *) &dm[1]; - name_len = ntohs (dm->name_len); - if ( (name_len + sizeof (struct GNUNET_IDENTITY_DeleteMessage) != size) || - (0 != ntohs (dm->reserved)) || + name = (const char *) &msg[1]; + name_len = ntohs (msg->name_len); + if ( (name_len + sizeof (struct DeleteMessage) != size) || + (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1]) ) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handler for DELETE message from client, creates + * new identity. + * + * @param cls unused + * @param client who sent the message + * @param message the message received + */ +static void +handle_delete_message (void *cls, + const struct DeleteMessage *dm) +{ + struct Ego *ego; + char *name; + char *fn; + struct GNUNET_SERVICE_Client *client = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received DELETE message from client\n"); + name = GNUNET_strdup ((const char *) &dm[1]); + GNUNET_STRINGS_utf8_tolower ((const char *) &dm[1], name); + for (ego = ego_head; NULL != ego; ego = ego->next) { if (0 == strcmp (ego->identifier, - name)) + name)) { GNUNET_CONTAINER_DLL_remove (ego_head, - ego_tail, - ego); + ego_tail, + ego); GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, - &handle_ego_delete, - ego->identifier); - 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); + &handle_ego_delete, + ego->identifier); + 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); fn = get_ego_filename (ego); if (0 != UNLINK (fn)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); GNUNET_free (fn); GNUNET_free (ego->identifier); ego->identifier = NULL; notify_listeners (ego); GNUNET_free (ego->pk); GNUNET_free (ego); + GNUNET_free (name); send_result_code (client, 0, NULL); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVICE_client_continue (client); return; } } send_result_code (client, 1, gettext_noop ("no matching ego found")); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_free (name); + GNUNET_SERVICE_client_continue (client); } @@ -807,7 +949,7 @@ handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client, */ static int process_ego_file (void *cls, - const char *filename) + const char *filename) { struct Ego *ego; const char *fn; @@ -819,22 +961,22 @@ 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; - } + { + 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); + "Loaded ego `%s'\n", + fn + 1); ego->identifier = GNUNET_strdup (fn + 1); GNUNET_CONTAINER_DLL_insert (ego_head, - ego_tail, - ego); + ego_tail, + ego); return GNUNET_OK; } @@ -847,31 +989,16 @@ process_ego_file (void *cls, * @param c configuration to use */ static void -run (void *cls, - struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { - static const struct GNUNET_SERVER_MessageHandler handlers[] = { - {&handle_start_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_START, sizeof (struct GNUNET_MessageHeader)}, - {&handle_get_default_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, 0}, - {&handle_set_default_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, 0}, - {&handle_create_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, 0}, - {&handle_rename_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, 0}, - {&handle_delete_message, NULL, - GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, 0}, - {NULL, NULL, 0, 0} - }; - cfg = c; + nc = GNUNET_notification_context_create (1); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", - "EGODIR", - &ego_directory)) + "EGODIR", + &ego_directory)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR"); GNUNET_SCHEDULER_shutdown (); @@ -879,62 +1006,81 @@ run (void *cls, } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "identity", - "SUBSYSTEM_CFG", - &subsystem_cfg_file)) + "SUBSYSTEM_CFG", + &subsystem_cfg_file)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Loading subsystem configuration `%s'\n", - subsystem_cfg_file); + "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_CONFIGURATION_parse (subsystem_cfg, - subsystem_cfg_file)) ) + GNUNET_DISK_file_test (subsystem_cfg_file)) && + (GNUNET_OK != + GNUNET_CONFIGURATION_parse (subsystem_cfg, + subsystem_cfg_file)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse subsystem identity configuration file `%s'\n"), - subsystem_cfg_file); + _("Failed to parse subsystem identity configuration file `%s'\n"), + subsystem_cfg_file); GNUNET_SCHEDULER_shutdown (); return; } 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); + _("Failed to create directory `%s' for storing egos\n"), + ego_directory); } GNUNET_DISK_directory_scan (ego_directory, - &process_ego_file, - NULL); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, - NULL); + &process_ego_file, + NULL); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); } /** - * The main function for the network size estimation service. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * Define "main" method using service macro. */ -int -main (int argc, char *const *argv) -{ - return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "identity", - GNUNET_SERVICE_OPTION_NONE, - &run, NULL)) ? 0 : 1; -} +GNUNET_SERVICE_MAIN +("identity", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_fixed_size (start_message, + GNUNET_MESSAGE_TYPE_IDENTITY_START, + struct GNUNET_MessageHeader, + NULL), + GNUNET_MQ_hd_var_size (get_default_message, + GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, + struct GetDefaultMessage, + NULL), + GNUNET_MQ_hd_var_size (set_default_message, + GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, + struct SetDefaultMessage, + NULL), + GNUNET_MQ_hd_var_size (create_message, + GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, + struct CreateRequestMessage, + NULL), + GNUNET_MQ_hd_var_size (rename_message, + GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, + struct RenameMessage, + NULL), + GNUNET_MQ_hd_var_size (delete_message, + GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, + struct DeleteMessage, + NULL), + GNUNET_MQ_handler_end()); + /* end of gnunet-service-identity.c */