--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2012-2015 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**
+ * @author Martin Schanzenbach
+ * @file src/reclaim/gnunet-service-reclaim.c
+ * @brief reclaim Service
+ *
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_protocols.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_gns_service.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_namestore_service.h"
+#include "zklaim_api.h"
+#include "zklaim/zklaim.h"
+
+/**
+ * Namestore handle
+ */
+static struct GNUNET_NAMESTORE_Handle *ns_handle;
+
+/**
+ * GNS handle
+ */
+static struct GNUNET_GNS_Handle *gns_handle;
+
+/**
+ * Handle to the statistics service.
+ */
+static struct GNUNET_STATISTICS_Handle *stats;
+
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * An idp client
+ */
+struct ZkClient
+{
+
+ /**
+ * The client
+ */
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue for transmission to @e client
+ */
+ struct GNUNET_MQ_Handle *mq;
+
+ /**
+ * Head of DLL of context create ops
+ */
+ struct CreateContextHandle *create_op_head;
+
+ /**
+ * Tail of DLL of attribute store ops
+ */
+ struct CreateContextHandle *create_op_tail;
+
+};
+
+struct CreateContextHandle
+{
+ /**
+ * DLL
+ */
+ struct CreateContextHandle *next;
+
+ /**
+ * DLL
+ */
+ struct CreateContextHandle *prev;
+
+ /**
+ * Client connection
+ */
+ struct ZkClient *client;
+
+ /**
+ * Issuer private key
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey private_key;
+
+ /**
+ * Issuer public key
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
+
+ /**
+ * QueueEntry
+ */
+ struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+ /**
+ * The context name
+ */
+ char *name;
+
+ /**
+ * The attributes to support
+ */
+ char *attrs;
+
+};
+
+/**
+ * Cleanup task
+ */
+static void
+cleanup()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Cleaning up\n");
+
+ if (NULL != stats)
+ {
+ GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
+ stats = NULL;
+ }
+ if (NULL != gns_handle)
+ GNUNET_GNS_disconnect (gns_handle);
+ if (NULL != ns_handle)
+ GNUNET_NAMESTORE_disconnect (ns_handle);
+}
+
+/**
+ * Shutdown task
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Shutting down...\n");
+ cleanup();
+}
+
+
+
+/**
+ * Cleanup attribute store handle
+ *
+ * @param handle handle to clean up
+ */
+static void
+cleanup_create_handle (struct CreateContextHandle *handle)
+{
+ if (NULL != handle->ns_qe)
+ GNUNET_NAMESTORE_cancel (handle->ns_qe);
+ if (NULL != handle->name)
+ GNUNET_free (handle->name);
+ GNUNET_free (handle);
+}
+
+static void
+send_result (int32_t status,
+ struct CreateContextHandle *cch)
+{
+ struct GNUNET_MQ_Envelope *env;
+ struct ResultCodeMessage *r_msg;
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending RESULT_CODE message\n");
+ env = GNUNET_MQ_msg (r_msg,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_RESULT_CODE);
+ r_msg->result_code = htonl (status);
+ GNUNET_MQ_send (cch->client->mq,
+ env);
+ cleanup_create_handle (cch);
+
+}
+
+static void
+context_store_cont (void *cls,
+ int32_t success,
+ const char *emsg)
+{
+ struct CreateContextHandle *cch = cls;
+
+ cch->ns_qe = NULL;
+ GNUNET_CONTAINER_DLL_remove (cch->client->create_op_head,
+ cch->client->create_op_tail,
+ cch);
+
+ if (GNUNET_SYSERR == success)
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to create context %s\n",
+ emsg);
+
+ send_result (success, cch);
+}
+
+
+
+static int
+check_create_context_message(void *cls,
+ const struct CreateRequestMessage *crm)
+{
+ uint16_t size;
+
+ size = ntohs (crm->header.size);
+ if (size <= sizeof (struct CreateRequestMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+static void
+handle_create_context_message (void *cls,
+ const struct CreateRequestMessage *crm)
+{
+ struct CreateContextHandle *cch;
+ struct ZkClient *zkc = cls;
+ size_t data_len;
+ char *tmp;
+ char *pos;
+ unsigned char *data;
+ int num_attrs;
+ int num_pl;
+ int i;
+ zklaim_ctx *ctx;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received CREATE_REQUEST message\n");
+
+ data_len = ntohs (crm->name_len);
+
+ cch = GNUNET_new (struct CreateContextHandle);
+ cch->name = GNUNET_strndup ((char*)&crm[1], data_len-1);
+ data_len = ntohs(crm->attrs_len);
+ cch->attrs = GNUNET_strndup (((char*)&crm[1]) + strlen (cch->name) + 1,
+ data_len-1);
+ cch->private_key = crm->private_key;
+ GNUNET_CRYPTO_ecdsa_key_get_public (&crm->private_key,
+ &cch->public_key);
+
+ GNUNET_SERVICE_client_continue (zkc->client);
+ cch->client = zkc;
+ GNUNET_CONTAINER_DLL_insert (zkc->create_op_head,
+ zkc->create_op_tail,
+ cch);
+
+ tmp = GNUNET_strdup (cch->attrs);
+ pos = strtok(tmp, ",");
+ num_attrs = 0;
+ if (NULL == pos)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "No attributes given.\n");
+ send_result(GNUNET_SYSERR, cch);
+ GNUNET_free (tmp);
+ return;
+ }
+ while (NULL != pos)
+ {
+ num_attrs++;
+ pos = strtok(NULL, ",");
+ }
+ GNUNET_free (tmp);
+ num_pl = num_attrs / 5;
+ zklaim_payload pl[num_pl];
+ ctx = zklaim_context_new ();
+ for (i = 0; i < num_pl; i++)
+ zklaim_add_pl (ctx, pl[i]);
+ zklaim_hash_ctx (ctx);
+ if (0 != zklaim_trusted_setup (ctx))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Trusted Setup failed.\n");
+ send_result(GNUNET_SYSERR, cch);
+ zklaim_ctx_free (ctx);
+ return;
+ }
+ if (0 != zklaim_ctx_serialize (ctx, &data))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Context serialization failed.\n");
+ send_result(GNUNET_SYSERR, cch);
+ zklaim_ctx_free (ctx);
+ return;
+ }
+ zklaim_ctx_free (ctx);
+ // store ctx,attrs as GNS record
+}
+
+
+
+/**
+ * Main function that will be run
+ *
+ * @param cls closure
+ * @param c the configuration used
+ * @param server the service handle
+ */
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *server)
+{
+ cfg = c;
+
+ stats = GNUNET_STATISTICS_create ("zklaim", cfg);
+
+ //Connect to services
+ ns_handle = GNUNET_NAMESTORE_connect (cfg);
+ if (NULL == ns_handle)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to namestore");
+ }
+
+ gns_handle = GNUNET_GNS_connect (cfg);
+ if (NULL == gns_handle)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
+ }
+ GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
+}
+
+
+/**
+ * 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)
+{
+ struct ZkClient *zkc = app_ctx;
+ struct CreateContextHandle *cch;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p disconnected\n",
+ client);
+
+ while (NULL != (cch = zkc->create_op_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (zkc->create_op_head,
+ zkc->create_op_tail,
+ cch);
+ cleanup_create_handle (cch);
+ }
+ GNUNET_free (zkc);
+}
+
+
+
+/**
+ * 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)
+{
+ struct ZkClient *zkc;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p connected\n",
+ client);
+ zkc = GNUNET_new (struct ZkClient);
+ zkc->client = client;
+ zkc->mq = mq;
+ return zkc;
+}
+
+
+
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("zklaim",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (create_context_message,
+ GNUNET_MESSAGE_TYPE_ZKLAIM_CREATE,
+ struct CreateRequestMessage,
+ NULL),
+ GNUNET_MQ_handler_end());
+/* end of gnunet-service-zklaim.c */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2012-2015 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**
+ * @author Martin Schanzenbach
+ * @file src/zklaim/gnunet-zklaim.c
+ * @brief ZKlaim CLI
+ *
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_namestore_service.h"
+#include "gnunet_zklaim_service.h"
+#include "gnunet_identity_service.h"
+#include "gnunet_signatures.h"
+
+/**
+ * state
+ */
+static int init;
+
+/**
+ * return value
+ */
+static int ret;
+
+/**
+ * Create new ZKlaim issuer context flag
+ */
+static int create;
+
+/**
+ * Name of new context
+ */
+static char* context_name;
+
+/**
+ * Attribute names for issuer context data
+ */
+static char* issue_attrs;
+
+/**
+ * Ego name
+ */
+static char* ego_name;
+
+/**
+ * ZKLAIM handle
+ */
+static struct GNUNET_ZKLAIM_Handle *zklaim_handle;
+
+/**
+ * ZKLAIM Operation
+ */
+static struct GNUNET_ZKLAIM_Operation *zklaim_op;
+
+/**
+ * IDENTITY handle
+ */
+static struct GNUNET_IDENTITY_Handle *identity_handle;
+
+/**
+ * ego private key
+ */
+static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
+
+/**
+ * Timeout task
+ */
+static struct GNUNET_SCHEDULER_Task *timeout;
+
+/**
+ * Cleanup task
+ */
+static struct GNUNET_SCHEDULER_Task *cleanup_task;
+
+static void
+do_cleanup(void *cls)
+{
+ cleanup_task = NULL;
+ if (NULL != timeout)
+ GNUNET_SCHEDULER_cancel (timeout);
+ if (NULL != zklaim_op)
+ GNUNET_ZKLAIM_cancel (zklaim_op);
+ if (NULL != zklaim_handle)
+ GNUNET_ZKLAIM_disconnect (zklaim_handle);
+ if (NULL != identity_handle)
+ GNUNET_IDENTITY_disconnect (identity_handle);
+}
+
+static void
+timeout_task (void *cls)
+{
+ timeout = NULL;
+ ret = 1;
+ fprintf (stderr,
+ "Timeout\n");
+ if (NULL == cleanup_task)
+ cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
+static void
+context_create_cb (void *cls,
+ int32_t success,
+ const char* emsg)
+{
+ return;
+}
+
+static void
+handle_arguments ()
+{
+ timeout = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10),
+ &timeout_task,
+ NULL);
+ if (create)
+ {
+ zklaim_op = GNUNET_ZKLAIM_context_create (zklaim_handle,
+ pkey,
+ context_name,
+ issue_attrs,
+ &context_create_cb,
+ NULL);
+ return;
+ }
+ cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
+static void
+ego_cb (void *cls,
+ struct GNUNET_IDENTITY_Ego *ego,
+ void **ctx,
+ const char *name)
+{
+ if (NULL == name) {
+ if (GNUNET_YES == init) {
+ init = GNUNET_NO;
+ handle_arguments();
+ }
+ return;
+ }
+ if (0 != strcmp (name, ego_name))
+ return;
+ pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
+}
+
+
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+ ret = 0;
+ if (NULL == ego_name)
+ {
+ ret = 1;
+ fprintf (stderr,
+ _("Ego is required\n"));
+ return;
+ }
+
+ if ( (create) && (NULL == context_name) )
+ {
+ ret = 1;
+ fprintf (stderr,
+ _("Context name missing!\n"));
+ return;
+ }
+ if ( (create) && (NULL == issue_attrs) )
+ {
+ ret = 1;
+ fprintf (stderr,
+ _("Context attributes missing!\n"));
+ return;
+ }
+
+ zklaim_handle = GNUNET_ZKLAIM_connect (c);
+ //Get Ego
+ identity_handle = GNUNET_IDENTITY_connect (c,
+ &ego_cb,
+ NULL);
+
+
+}
+
+
+int
+main(int argc, char *const argv[])
+{
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+
+ GNUNET_GETOPT_option_string ('n',
+ "name",
+ NULL,
+ gettext_noop ("Context name"),
+ &context_name),
+
+ GNUNET_GETOPT_option_string ('A',
+ "attributes",
+ NULL,
+ gettext_noop ("Context attributes (comma separated)"),
+ &issue_attrs),
+ GNUNET_GETOPT_option_string ('e',
+ "ego",
+ NULL,
+ gettext_noop ("Ego"),
+ &ego_name),
+ GNUNET_GETOPT_option_flag ('C',
+ "create",
+ gettext_noop ("Create new issuer context"),
+ &create),
+ GNUNET_GETOPT_OPTION_END
+ };
+ if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "ct",
+ "ct", options,
+ &run, NULL))
+ return 1;
+ else
+ return ret;
+}