diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/credential/Makefile.am | 113 | ||||
-rw-r--r-- | src/credential/credential.conf.in | 5 | ||||
-rw-r--r-- | src/credential/credential.h | 91 | ||||
-rw-r--r-- | src/credential/credential_api.c | 410 | ||||
-rw-r--r-- | src/credential/gnunet-credential.c | 382 | ||||
-rw-r--r-- | src/credential/gnunet-service-credential.c | 425 | ||||
-rw-r--r-- | src/credential/plugin_gnsrecord_credential.c | 257 | ||||
-rwxr-xr-x | src/credential/test_credential_lookup.sh | 40 | ||||
-rw-r--r-- | src/include/gnunet_credential_service.h | 60 | ||||
-rw-r--r-- | src/include/gnunet_gnsrecord_lib.h | 7 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 9 |
13 files changed, 1794 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac index d839f8b4e6..1a24513929 100644 --- a/configure.ac +++ b/configure.ac @@ -1581,6 +1581,8 @@ src/gnsrecord/Makefile src/hello/Makefile src/identity/Makefile src/identity/identity.conf +src/credential/Makefile +src/credential/credential.conf src/include/Makefile src/integration-tests/Makefile src/json/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 98ca70ae32..2877cab0b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,6 +109,7 @@ SUBDIRS = \ revocation \ vpn \ gns \ + credential \ $(CONVERSATION_DIR) \ fs \ exit \ diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am new file mode 100644 index 0000000000..6469895e37 --- /dev/null +++ b/src/credential/Makefile.am @@ -0,0 +1,113 @@ +# This Makefile.am is in the public domain +AM_CPPFLAGS = -I$(top_srcdir)/src/include + +EXTRA_DIST = \ + test_credential_defaults.conf \ + test_credential_lookup.conf +# test_gns_nick_shorten.conf \ +#### test_gns_proxy.conf \ +# test_gns_simple_lookup.conf \ +# gns-helper-service-w32.conf \ +# w32nsp.def \ +# gnunet-gns-proxy-setup-ca \ +# zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ +# zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ +# zonefiles/test_zonekey \ +# $(check_SCRIPTS) + + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 +endif + +pkgcfgdir = $(pkgdatadir)/config.d/ + +libexecdir= $(pkglibdir)/libexec/ + +plugindir = $(libdir)/gnunet + +pkgcfg_DATA = \ + credential.conf + + +# /usr/lib - compiles a layer which can be used to be communicagte with the service +lib_LTLIBRARIES = \ + libgnunetcredential.la + +# /usr/lib/gnunet/libexec - Business logic . Separate process +libexec_PROGRAMS = \ + gnunet-service-credential + +bin_PROGRAMS = \ + gnunet-credential + +plugin_LTLIBRARIES = \ + libgnunet_plugin_gnsrecord_credential.la + + +#if HAVE_MHD +#if HAVE_JSON +#plugin_LTLIBRARIES += libgnunet_plugin_rest_gns.la +#endif +#endif + + +gnunet_credential_SOURCES = \ + gnunet-credential.c +gnunet_credential_LDADD = \ + libgnunetcredential.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + $(GN_LIBINTL) + + +libgnunet_plugin_gnsrecord_credential_la_SOURCES = \ + plugin_gnsrecord_credential.c +libgnunet_plugin_gnsrecord_credential_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) +libgnunet_plugin_gnsrecord_credential_la_LDFLAGS = \ + $(GN_PLUGIN_LDFLAGS) + + + +gnunet_service_credential_SOURCES = \ + gnunet-service-credential.c +gnunet_service_credential_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(GN_LIBINTL) + + +libgnunetcredential_la_SOURCES = \ + credential_api.c credential.h +libgnunetcredential_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la $(XLIB) +libgnunetcredential_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) + + +#libgnunet_plugin_rest_gns_la_SOURCES = \ +# plugin_rest_gns.c +#libgnunet_plugin_rest_gns_la_LIBADD = \ +# libgnunetgns.la \ +# $(top_builddir)/src/rest/libgnunetrest.la \ +# $(top_builddir)/src/identity/libgnunetidentity.la \ +# $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ +# $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \ +# $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ +# $(LTLIBINTL) -ljansson -lmicrohttpd +#libgnunet_plugin_rest_gns_la_LDFLAGS = \ +# $(GN_PLUGIN_LDFLAGS) + + +#check_SCRIPTS = \ + #test_gns_lookup.sh + +if ENABLE_TEST_RUN +if HAVE_SQLITE + AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; + TESTS = $(check_SCRIPTS) +endif +endif diff --git a/src/credential/credential.conf.in b/src/credential/credential.conf.in new file mode 100644 index 0000000000..71f3066ca9 --- /dev/null +++ b/src/credential/credential.conf.in @@ -0,0 +1,5 @@ +[credential] +BINARY = gnunet-service-credential +UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-credential.sock +USER_SERVICE = YES +OPTIONS = -L DEBUG
\ No newline at end of file diff --git a/src/credential/credential.h b/src/credential/credential.h new file mode 100644 index 0000000000..597c34a3d7 --- /dev/null +++ b/src/credential/credential.h @@ -0,0 +1,91 @@ +/* + This file is part of GNUnet + Copyright (C) 2012-2013 GNUnet e.V. + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ +/** + * @file credential/credential.h + * @brief IPC messages between CREDENTIAL API and CREDENTIAL service + * @author Adnan Husain + */ +#ifndef CREDENTIAL_H +#define CREDENTIAL_H + +#include "gnunet_credential_service.h" + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Message from client to Credential service to lookup credentials. + */ +struct LookupMessage +{ + /** + * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP + */ + struct GNUNET_MessageHeader header; + + /** + * Subject public key + */ + struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; + + /** + * Trust anchor + */ + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + /** + * Unique identifier for this request (for key collisions). + */ + uint32_t id GNUNET_PACKED; + + /* Followed by the zero-terminated credential to look up */ + +}; + + +/** + * Message from CREDENTIAL service to client: new results. + */ +struct LookupResultMessage +{ + /** + * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT + */ + struct GNUNET_MessageHeader header; + + /** + * Unique identifier for this request (for key collisions). + */ + uint32_t id GNUNET_PACKED; + + + /** + * The number of credentials in the response + */ + uint32_t cd_count GNUNET_PACKED; + + /* followed by cd_count GNUNET_CREDENTIAL_RecordData structs*/ + +}; + + +GNUNET_NETWORK_STRUCT_END + +#endif + diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c new file mode 100644 index 0000000000..1efe2d0892 --- /dev/null +++ b/src/credential/credential_api.c @@ -0,0 +1,410 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016 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 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file credential/credential_api.c + * @brief library to access the CREDENTIAL service + * @author Adnan Husain + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_arm_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_protocols.h" +#include "credential.h" +#include "gnunet_credential_service.h" +#include "gnunet_identity_service.h" + + +#define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__) + +/** + * Handle to a lookup request + */ +struct GNUNET_CREDENTIAL_LookupRequest +{ + + /** + * DLL + */ + struct GNUNET_CREDENTIAL_LookupRequest *next; + + /** + * DLL + */ + struct GNUNET_CREDENTIAL_LookupRequest *prev; + + /** + * handle to credential service + */ + struct GNUNET_CREDENTIAL_Handle *credential_handle; + + /** + * processor to call on lookup result + */ + GNUNET_CREDENTIAL_LookupResultProcessor lookup_proc; + + /** + * @e lookup_proc closure + */ + void *proc_cls; + + /** + * Envelope with the message for this queue entry. + */ + struct GNUNET_MQ_Envelope *env; + + /** + * request id + */ + uint32_t r_id; + +}; + + +/** + * Connection to the CREDENTIAL service. + */ +struct GNUNET_CREDENTIAL_Handle +{ + + /** + * Configuration to use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Connection to service (if available). + */ + struct GNUNET_MQ_Handle *mq; + + /** + * Head of linked list of active lookup requests. + */ + struct GNUNET_CREDENTIAL_LookupRequest *lookup_head; + + /** + * Tail of linked list of active lookup requests. + */ + struct GNUNET_CREDENTIAL_LookupRequest *lookup_tail; + + /** + * Reconnect task + */ + struct GNUNET_SCHEDULER_Task *reconnect_task; + + /** + * How long do we wait until we try to reconnect? + */ + struct GNUNET_TIME_Relative reconnect_backoff; + + /** + * Request Id generator. Incremented by one for each request. + */ + uint32_t r_id_gen; + +}; + + +/** + * Reconnect to CREDENTIAL service. + * + * @param handle the handle to the CREDENTIAL service + */ +static void +reconnect (struct GNUNET_CREDENTIAL_Handle *handle); + + +/** + * Reconnect to CREDENTIAL + * + * @param cls the handle + */ +static void +reconnect_task (void *cls) +{ + struct GNUNET_CREDENTIAL_Handle *handle = cls; + + handle->reconnect_task = NULL; + reconnect (handle); +} + + +/** + * Disconnect from service and then reconnect. + * + * @param handle our handle + */ +static void +force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle) +{ + GNUNET_MQ_destroy (handle->mq); + handle->mq = NULL; + handle->reconnect_backoff + = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); + handle->reconnect_task + = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, + &reconnect_task, + handle); +} + + +/** + * Generic error handler, called with the appropriate error code and + * the same closure specified at the creation of the message queue. + * Not every message queue implementation supports an error handler. + * + * @param cls closure with the `struct GNUNET_CREDENTIAL_Handle *` + * @param error error code + */ +static void +mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_CREDENTIAL_Handle *handle = cls; + + force_reconnect (handle); +} + + +/** + * Check validity of message received from the CREDENTIAL service + * + * @param cls the `struct GNUNET_CREDENTIAL_Handle *` + * @param loookup_msg the incoming message + */ +static int +check_result (void *cls, + const struct LookupResultMessage *lookup_msg) +{ + //TODO + return GNUNET_OK; +} + + +/** + * Handler for messages received from the CREDENTIAL service + * + * @param cls the `struct GNUNET_CREDENTIAL_Handle *` + * @param loookup_msg the incoming message + */ +static void +handle_result (void *cls, + const struct LookupResultMessage *lookup_msg) +{ + struct GNUNET_CREDENTIAL_Handle *handle = cls; + uint32_t cd_count = ntohl (lookup_msg->cd_count); + struct GNUNET_CREDENTIAL_RecordData cd[cd_count]; + uint32_t r_id = ntohl (lookup_msg->id); + struct GNUNET_CREDENTIAL_LookupRequest *lr; + GNUNET_CREDENTIAL_LookupResultProcessor proc; + void *proc_cls; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received lookup reply from CREDENTIAL service (%u credentials)\n", + (unsigned int) cd_count); + for (lr = handle->lookup_head; NULL != lr; lr = lr->next) + if (lr->r_id == r_id) + break; + if (NULL == lr) + return; + proc = lr->lookup_proc; + proc_cls = lr->proc_cls; + GNUNET_CONTAINER_DLL_remove (handle->lookup_head, + handle->lookup_tail, + lr); + GNUNET_free (lr); + /** + GNUNET_assert (GNUNET_OK == + GNUNET_CREDENTIAL_records_deserialize (mlen, + (const char*) &lookup_msg[1], + rd_count, + rd)); + */ + proc (proc_cls, + NULL, + cd_count, + cd); // TODO +} + + +/** + * Reconnect to CREDENTIAL service. + * + * @param handle the handle to the CREDENTIAL service + */ +static void +reconnect (struct GNUNET_CREDENTIAL_Handle *handle) +{ + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_var_size (result, + GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT, + struct LookupResultMessage, + NULL), + GNUNET_MQ_handler_end () + }; + struct GNUNET_CREDENTIAL_LookupRequest *lh; + + GNUNET_assert (NULL == handle->mq); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Trying to connect to CREDENTIAL\n"); + handle->mq = GNUNET_CLIENT_connecT (handle->cfg, + "credential", + handlers, + &mq_error_handler, + handle); + if (NULL == handle->mq) + return; + for (lh = handle->lookup_head; NULL != lh; lh = lh->next) + GNUNET_MQ_send_copy (handle->mq, + lh->env); +} + + +/** + * Initialize the connection with the CREDENTIAL service. + * + * @param cfg configuration to use + * @return handle to the CREDENTIAL service, or NULL on error + */ +struct GNUNET_CREDENTIAL_Handle * +GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_CREDENTIAL_Handle *handle; + + handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle); + handle->cfg = cfg; + reconnect (handle); + if (NULL == handle->mq) + { + GNUNET_free (handle); + return NULL; + } + return handle; +} + + +/** + * Shutdown connection with the CREDENTIAL service. + * + * @param handle handle of the CREDENTIAL connection to stop + */ +void +GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle) +{ + if (NULL != handle->mq) + { + GNUNET_MQ_destroy (handle->mq); + handle->mq = NULL; + } + if (NULL != handle->reconnect_task) + { + GNUNET_SCHEDULER_cancel (handle->reconnect_task); + handle->reconnect_task = NULL; + } + GNUNET_assert (NULL == handle->lookup_head); + GNUNET_free (handle); +} + + +/** + * Cancel pending lookup request + * + * @param lr the lookup request to cancel + */ +void +GNUNET_CREDENTIAL_lookup_cancel (struct GNUNET_CREDENTIAL_LookupRequest *lr) +{ + struct GNUNET_CREDENTIAL_Handle *handle = lr->credential_handle; + + GNUNET_CONTAINER_DLL_remove (handle->lookup_head, + handle->lookup_tail, + lr); + GNUNET_MQ_discard (lr->env); + GNUNET_free (lr); +} + + +/** + * Perform an asynchronous lookup operation for a credential. + * + * @param handle handle to the Credential service + * @param credential the credential to look up + * @param subject Ego to check the credential for + * @param proc function to call on result + * @param proc_cls closure for processor + * @return handle to the queued request + */ +struct GNUNET_CREDENTIAL_LookupRequest* +GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle, + const char *credential, + const struct GNUNET_IDENTITY_Ego *subject, + const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, + uint32_t credential_flags, + uint32_t max_delegation_depth, + GNUNET_CREDENTIAL_LookupResultProcessor proc, + void *proc_cls) +{ + /* IPC to shorten credential names, return shorten_handle */ + struct LookupMessage *lookup_msg; + struct GNUNET_CREDENTIAL_LookupRequest *lr; + size_t nlen; + + if (NULL == credential) + { + GNUNET_break (0); + return NULL; + } + //DEBUG LOG + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Trying to lookup `%s' in CREDENTIAL\n", + credential); + nlen = strlen (credential) + 1; + if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*lr)) + { + GNUNET_break (0); + return NULL; + } + lr = GNUNET_new (struct GNUNET_CREDENTIAL_LookupRequest); + lr->credential_handle = handle; + lr->lookup_proc = proc; + lr->proc_cls = proc_cls; + lr->r_id = handle->r_id_gen++; + lr->env = GNUNET_MQ_msg_extra (lookup_msg, + nlen, + GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP); + lookup_msg->id = htonl (lr->r_id); + lookup_msg->subject_key = *subject_key; + lookup_msg->issuer_key = *issuer_key; + GNUNET_memcpy (&lookup_msg[1], + credential, + nlen); + GNUNET_CONTAINER_DLL_insert (handle->lookup_head, + handle->lookup_tail, + lr); + if (NULL != handle->mq) + GNUNET_MQ_send_copy (handle->mq, + lr->env); + return lr; +} + + +/* end of credential_api.c */ diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c new file mode 100644 index 0000000000..363ed03fce --- /dev/null +++ b/src/credential/gnunet-credential.c @@ -0,0 +1,382 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2013 GNUnet e.V. + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file gnunet-credential.c + * @brief command line tool to access command line Credential service + * @author Adnan Husain + */ +#include "platform.h" +#include <gnunet_util_lib.h> +#include <gnunet_identity_service.h> +#include <gnunet_credential_service.h> + +/** + * Configuration we are using. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Handle to Credential service. + */ +static struct GNUNET_CREDENTIAL_Handle *credential; + +/** + * Desired timeout for the lookup (default is no timeout). + */ +static struct GNUNET_TIME_Relative timeout; + +/** + * Credential to lookup. (-u option) + */ +static char *lookup_credential; + +/** + * Handle to lookup request + */ +static struct GNUNET_CREDENTIAL_LookupRequest *lookup_request; + +/** + * Lookup an ego with the identity service. + */ +static struct GNUNET_IDENTITY_EgoLookup *el; + +/** + * Handle for identity service. + */ +static struct GNUNET_IDENTITY_Handle *identity; + +/** + * Active operation on identity service. + */ +static struct GNUNET_IDENTITY_Operation *id_op; + +/** + * Task scheduled to handle timeout. + */ +static struct GNUNET_SCHEDULER_Task *tt; + +/** + * Subject pubkey string + */ +static char *subject_key; + +/** + * Subject pubkey string + */ +static char *issuer_key; + +/* + * Credential flags + */ +static int credential_flags; + +/* + * Maximum delegation depth + */ +static int max_delegation_depth; + + + +/** + * Identity of the zone to use for the lookup (-z option) + */ +static char *zone_ego_name; + + +/** + * Task run on shutdown. Cleans up everything. + * + * @param cls unused + */ +static void +do_shutdown (void *cls) +{ + if (NULL != el) + { + GNUNET_IDENTITY_ego_lookup_cancel (el); + el = NULL; + } + if (NULL != id_op) + { + GNUNET_IDENTITY_cancel (id_op); + id_op = NULL; + } + if (NULL != lookup_request) + { + GNUNET_CREDENTIAL_lookup_cancel (lookup_request); + lookup_request = NULL; + } + if (NULL != identity) + { + GNUNET_IDENTITY_disconnect (identity); + identity = NULL; + } + if (NULL != credential) + { + GNUNET_CREDENTIAL_disconnect (credential); + credential = NULL; + } + if (NULL != tt) + { + GNUNET_SCHEDULER_cancel (tt); + tt = NULL; + } +} + + +/** + * Task run on timeout. Triggers shutdown. + * + * @param cls unused + */ +static void +do_timeout (void *cls) +{ + tt = NULL; + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Function called with the result of a Credential lookup. + * + * @param cls the 'const char *' name that was resolved + * @param cd_count number of records returned + * @param cd array of @a cd_count records with the results + */ +static void +handle_lookup_result (void *cls, + struct GNUNET_IDENTITY_Ego *issuer, + uint16_t issuer_len, + const struct GNUNET_CREDENTIAL_RecordData *data) +{ + + + lookup_request = NULL; + if (0 == issuer_len) + printf ("No results.\n"); + else + printf ("%u\n", + issuer_len); + + + GNUNET_SCHEDULER_shutdown (); +} + + + + +/** + * Perform the actual resolution, with the subject pkey and + * the issuer public key + * + * @param pkey public key to use for the zone, can be NULL + * @param shorten_key private key used for shortening, can be NULL + */ +static void +lookup_credentials (struct GNUNET_IDENTITY_Ego *ego) +{ + + struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey; + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey; + + if (NULL != subject_key && NULL != issuer_key && NULL != lookup_credential) + { + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, + strlen (subject_key), + &subject_pkey)) + { + fprintf (stderr, + _("Subject public key `%s' is not well-formed\n"), + subject_key); + GNUNET_SCHEDULER_shutdown (); + return; + } + + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, + strlen (issuer_key), + &issuer_pkey)) + { + fprintf (stderr, + _("Authority public key `%s' is not well-formed\n"), + issuer_key); + GNUNET_SCHEDULER_shutdown (); + return; + } + + lookup_request = GNUNET_CREDENTIAL_lookup(credential, + lookup_credential, + ego, + &subject_pkey, + &issuer_pkey, + credential_flags, + max_delegation_depth, + &handle_lookup_result, + NULL); + return; + } + else + { + fprintf (stderr, + _("Please specify name to lookup, subject key and issuer key!\n")); + GNUNET_SCHEDULER_shutdown (); + return; + } +} + + +/** + * Method called to with the ego we are to use for the lookup, + * when the ego is the one for the default master zone. + * + * @param cls closure (NULL, unused) + * @param ego ego handle, NULL if not found + * @param ctx context for application to store data for this ego + * (during the lifetime of this process, initially NULL) + * @param name name assigned by the user for this ego, + * NULL if the user just deleted the ego and it + * must thus no longer be used + */ +static void +identity_master_cb (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *name) +{ + + id_op = NULL; + if (NULL == ego) + { + fprintf (stderr, + _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); + GNUNET_SCHEDULER_shutdown (); + return; + } + + lookup_credentials(ego); + + +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + + cfg = c; + credential = GNUNET_CREDENTIAL_connect (cfg); + identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL); + + + + + if (NULL == credential) + { + fprintf (stderr, + _("Failed to connect to CREDENTIAL\n")); + return; + } + if (NULL == identity) + { + fprintf (stderr, + _("Failed to connect to IDENTITY\n")); + return; + } + tt = GNUNET_SCHEDULER_add_delayed (timeout, + &do_timeout, NULL); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); + + + + GNUNET_break (NULL == id_op); + id_op = GNUNET_IDENTITY_get (identity, + "gns-master",//# TODO: Create credential-master + &identity_master_cb, + cls); + GNUNET_assert (NULL != id_op); + + + + +} + + +/** + * The main function for gnunet-gns. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'u', "lookup", "CREDENTIAL", + gettext_noop ("Lookup a record for the given credential"), 1, + &GNUNET_GETOPT_set_string, &lookup_credential}, + /** { 'T', "timeout", "DELAY", + gettext_noop ("Specify timeout for the lookup"), 1, + &GNUNET_GETOPT_set_relative_time, &timeout }, + {'t', "type", "TYPE", + gettext_noop ("Specify the type of the record to lookup"), 1, + &GNUNET_GETOPT_set_string, &lookup_type},**/ + {'z', "zone", "NAME", + gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, + &GNUNET_GETOPT_set_string, &zone_ego_name}, + {'s', "subject", "PKEY", + gettext_noop ("Specify the public key of the subject to lookup the credential for"), 1, + &GNUNET_GETOPT_set_string, &subject_key}, + {'i', "issuer", "PKEY", + gettext_noop ("Specify the public key of the authority to verify the credential against"), 1, + &GNUNET_GETOPT_set_string, &issuer_key}, + GNUNET_GETOPT_OPTION_END + }; + int ret; + + timeout = GNUNET_TIME_UNIT_FOREVER_REL; + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + GNUNET_log_setup ("gnunet-credential", "WARNING", NULL); + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-credential", + _("GNUnet credential resolver tool"), + options, + &run, NULL)) ? 0 : 1; + GNUNET_free ((void*) argv); + return ret; +} + +/* end of gnunet-credential.c */ diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c new file mode 100644 index 0000000000..de05926375 --- /dev/null +++ b/src/credential/gnunet-service-credential.c @@ -0,0 +1,425 @@ +/* + This file is part of GNUnet. + Copyright (C) 2011-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 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file gns/gnunet-service-credential.c + * @brief GNU Credential Service (main service) + * @author Adnan Husain + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_credential_service.h" +#include "gnunet_statistics_service.h" +#include "credential.h" +#include "gnunet_protocols.h" + +// For Looking up GNS request +#include <gnunet_dnsparser_lib.h> +#include <gnunet_identity_service.h> +#include <gnunet_gnsrecord_lib.h> +#include <gnunet_namestore_service.h> +#include <gnunet_gns_service.h> +#include "gnunet_gns_service.h" + + + + +#define GNUNET_CREDENTIAL_MAX_LENGTH 255 + +/** + * DLL for record + */ +struct CredentialRecordEntry +{ + /** + * DLL + */ + struct CredentialRecordEntry *next; + + /** + * DLL + */ + struct CredentialRecordEntry *prev; + + + /** + * Payload + */ + struct GNUNET_CREDENTIAL_RecordData record_data; +}; + +/** + * Handle to a lookup operation from api + */ +struct ClientLookupHandle +{ + + /** + * We keep these in a DLL. + */ + struct ClientLookupHandle *next; + + /** + * We keep these in a DLL. + */ + struct ClientLookupHandle *prev; + + /** + * Handle to the requesting client + */ + struct GNUNET_SERVICE_Client *client; + + /** + * Handle to GNS lookup + */ + struct GNUNET_GNS_LookupRequest *lookup_request; + + /** + * Authority public key + */ + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + /** + * Credential Chain + */ + struct CredentialRecordEntry *cred_chain_head; + + /** + * Credential Chain + */ + struct CredentialRecordEntry *cred_chain_tail; + + /** + * request id + */ + uint32_t request_id; + +}; + + +/** + * Head of the DLL. + */ +static struct ClientLookupHandle *clh_head; + +/** + * Tail of the DLL. + */ +static struct ClientLookupHandle *clh_tail; + +/** + * Handle to the statistics service + */ +static struct GNUNET_STATISTICS_Handle *statistics; + + + +/** + * Handle to GNS service. + */ +static struct GNUNET_GNS_Handle *gns; + +/** + * Task run during shutdown. + * + * @param cls unused + * @param tc unused + */ +static void +shutdown_task (void *cls) +{ + struct ClientLookupHandle *clh; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Shutting down!\n"); + while (NULL != (clh = clh_head)) + { + //CREDENTIAL_resolver_lookup_cancel (clh->lookup); + GNUNET_CONTAINER_DLL_remove (clh_head, + clh_tail, + clh); + GNUNET_free (clh); + } + + + if (NULL != statistics) + { + GNUNET_STATISTICS_destroy (statistics, + GNUNET_NO); + statistics = NULL; + } + +} + +/** + * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP message + * + * @param cls client sending the message + * @param l_msg message of type `struct LookupMessage` + * @return #GNUNET_OK if @a l_msg is well-formed + */ +static int +check_lookup (void *cls, + const struct LookupMessage *l_msg) +{ + size_t msg_size; + const char* cred; + + msg_size = ntohs (l_msg->header.size); + if (msg_size < sizeof (struct LookupMessage)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + cred = (const char *) &l_msg[1]; + if ( ('\0' != cred[l_msg->header.size - sizeof (struct LookupMessage) - 1]) || + (strlen (cred) > GNUNET_CREDENTIAL_MAX_LENGTH) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Reply to client with the result from our lookup. + * + * @param cls the closure (our client lookup handle) + * @param rd_count the number of records in @a rd + * @param rd the record data + */ +static void +send_lookup_response (void* cls, + uint32_t rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + struct ClientLookupHandle *clh = cls; + size_t len; + int i; + int cred_record_count; + struct GNUNET_MQ_Envelope *env; + struct LookupResultMessage *rmsg; + const struct GNUNET_CREDENTIAL_RecordData *crd; + struct CredentialRecordEntry *cr_entry; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending LOOKUP_RESULT message with %u results\n", + (unsigned int) rd_count); + + cred_record_count = 0; + for (i=0; i < rd_count; i++) + { + if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) + continue; + cred_record_count++; + crd = rd[i].data; + /** + * TODO: Check for: + * - First time we come here subject must be subject prvided by client + * - After that is has to be the prev issuer + * - Terminate condition: issuer is clh->authority_key + * + * In any case: + * Append crd to result list of RecordData + */ + cr_entry = GNUNET_new (struct CredentialRecordEntry); + cr_entry->record_data = *crd; + GNUNET_CONTAINER_DLL_insert_tail (clh->cred_chain_head, + clh->cred_chain_tail, + cr_entry); + + } + + /** + * Get serialized record data size + */ + len = cred_record_count * sizeof (struct GNUNET_CREDENTIAL_RecordData); + + /** + * Prepare a lookup result response message for the client + */ + env = GNUNET_MQ_msg_extra (rmsg, + len, + GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT); + //Assign id so that client can find associated request + rmsg->id = clh->request_id; + rmsg->cd_count = htonl (cred_record_count); + + /** + * Get serialized record data + * Append at the end of rmsg + */ + i = 0; + struct GNUNET_CREDENTIAL_RecordData *tmp_record = (struct GNUNET_CREDENTIAL_RecordData*) &rmsg[1]; + for (cr_entry = clh->cred_chain_head; NULL != cr_entry; cr_entry = cr_entry->next) + { + memcpy (tmp_record, + &cr_entry->record_data, + sizeof (struct GNUNET_CREDENTIAL_RecordData)); + tmp_record++; + } + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->client), + env); + + GNUNET_CONTAINER_DLL_remove (clh_head, clh_tail, clh); + + /** + * TODO: + * - Free DLL + * - Refactor into cleanup_handle() function for this + */ + GNUNET_free (clh); + + GNUNET_STATISTICS_update (statistics, + "Completed lookups", 1, + GNUNET_NO); + GNUNET_STATISTICS_update (statistics, + "Records resolved", + rd_count, + GNUNET_NO); +} + +/** + * Handle lookup requests from client + * + * @param cls the closure + * @param client the client + * @param message the message + */ +static void +handle_lookup (void *cls, + const struct LookupMessage *l_msg) +{ + char credential[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; + struct ClientLookupHandle *clh; + struct GNUNET_SERVICE_Client *client = cls; + char *credentialptr = credential; + const char *utf_in; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received LOOKUP message\n"); + + utf_in = (const char *) &l_msg[1]; + GNUNET_STRINGS_utf8_tolower (utf_in, credentialptr); + clh = GNUNET_new (struct ClientLookupHandle); + GNUNET_CONTAINER_DLL_insert (clh_head, clh_tail, clh); + clh->client = client; + clh->request_id = l_msg->id; + clh->issuer_key = l_msg->issuer_key; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending LOOKUP_RESULT message with >%u results\n", + 0); + + if (NULL == credential) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No credential provided\n"); + send_lookup_response (clh, 0, NULL); + return; + } + clh->lookup_request = GNUNET_GNS_lookup (gns, + credential, + &l_msg->subject_key, //subject_pkey, + GNUNET_GNSRECORD_TYPE_CREDENTIAL, + GNUNET_GNS_LO_DEFAULT, //TODO configurable? credential.conf + NULL, //shorten_key, always NULL + &send_lookup_response, + clh); +} + + +/** + * One of our clients disconnected, clean up after it. + * + * @param cls NULL + * @param client the client that disconnected + */ +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 this client + */ +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client %p connected\n", + client); + return client; +} + +/** + * Process Credential requests. + * + * @param cls closure + * @param server the initialized server + * @param c configuration to use + */ +static void +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *handle) +{ + + gns = GNUNET_GNS_connect (c); + if (NULL == gns) + { + fprintf (stderr, + _("Failed to connect to GNS\n")); + } + + statistics = GNUNET_STATISTICS_create ("credential", c); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); +} + + +/** + * Define "main" method using service macro + */ +GNUNET_SERVICE_MAIN +("credential", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_var_size (lookup, + GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP, + struct LookupMessage, + NULL), + GNUNET_MQ_handler_end()); + +/* end of gnunet-service-credential.c */ diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c new file mode 100644 index 0000000000..6ae3b8980c --- /dev/null +++ b/src/credential/plugin_gnsrecord_credential.c @@ -0,0 +1,257 @@ +/* + This file is part of GNUnet + 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 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/** + * @file credential/plugin_gnsrecord_credential.c + * @brief gnsrecord plugin to provide the API for CREDENTIAL records + * @author Adnan Husain + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_gnsrecord_lib.h" +#include "gnunet_credential_service.h" +#include "gnunet_gnsrecord_plugin.h" + + +/** + * Convert the 'value' of a record to a string. + * + * @param cls closure, unused + * @param type type of the record + * @param data value in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the value + */ +static char * +credential_value_to_string (void *cls, + uint32_t type, + const void *data, + size_t data_size) +{ + + const char *cdata; + + switch (type) + { + case GNUNET_GNSRECORD_TYPE_CREDENTIAL: + { + struct GNUNET_CREDENTIAL_RecordData cred; + char *cred_str; + char *subject_pkey; + char *issuer_pkey; + uint32_t cf; // Credential flags + uint32_t mdd; // Max delegation depth + if (data_size < sizeof (struct GNUNET_CREDENTIAL_RecordData)) + return NULL; /* malformed */ + memcpy (&cred, + data, + sizeof (cred)); + cdata = data; + subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key); + issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key); + cf = ntohl (cred.credential_flags); + mdd = ntohl (cred.max_delegation_depth); + + GNUNET_asprintf (&cred_str, + "%s %s %u %u %s", + subject_pkey, + issuer_pkey, + (unsigned int) cf, + (unsigned int) mdd, + &cdata[sizeof (cred)]); + GNUNET_free (subject_pkey); + GNUNET_free (issuer_pkey); + + + + return cred_str; + } + default: + return NULL; + } +} + + +/** + * Convert human-readable version of a 'value' of a record to the binary + * representation. + * + * @param cls closure, unused + * @param type type of the record + * @param s human-readable string + * @param data set to value in binary encoding (will be allocated) + * @param data_size set to number of bytes in @a data + * @return #GNUNET_OK on success + */ +static int +credential_string_to_value (void *cls, + uint32_t type, + const char *s, + void **data, + size_t *data_size) +{ + if (NULL == s) + return GNUNET_SYSERR; + switch (type) + { + case GNUNET_GNSRECORD_TYPE_CREDENTIAL: + { + struct GNUNET_CREDENTIAL_RecordData *cred; + unsigned int cf; // credential flags + unsigned int mdd; // max delegation depth + + size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; + if (enclen % 5 > 0) + enclen += 5 - enclen % 5; + enclen /= 5; /* 260/5 = 52 */ + char subject_pkey[enclen + 1]; + char issuer_pkey[enclen + 1]; + char name[253 + 1]; + + if (5 != SSCANF (s, + "%52s %52s %u %u %253s", + subject_pkey, + issuer_pkey, + &cf, + &mdd, + name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Unable to parse CRED record string `%s'\n"), + s); + return GNUNET_SYSERR; + } + *data_size = sizeof (struct GNUNET_CREDENTIAL_RecordData) + strlen (name) + 1; + *data = cred = GNUNET_malloc (*data_size); + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, + strlen (subject_pkey), + &cred->subject_key); + GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, + strlen (issuer_pkey), + &cred->issuer_key); + cred->credential_flags = htonl (cf); + cred->max_delegation_depth = htonl (mdd); + GNUNET_memcpy (&cred[1], + name, + strlen (name)); + + + *data = GNUNET_strdup (s); + *data_size = strlen (s); + return GNUNET_OK; + } + default: + return GNUNET_SYSERR; + } +} + + +/** + * Mapping of record type numbers to human-readable + * record type names. + */ +static struct { + const char *name; + uint32_t number; +} name_map[] = { + { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL }, + { NULL, UINT32_MAX } +}; + + +/** + * Convert a type name (i.e. "AAAA") to the corresponding number. + * + * @param cls closure, unused + * @param gns_typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +static uint32_t +credential_typename_to_number (void *cls, + const char *gns_typename) +{ + unsigned int i; + + i=0; + while ( (name_map[i].name != NULL) && + (0 != strcasecmp (gns_typename, name_map[i].name)) ) + i++; + return name_map[i].number; +} + + +/** + * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") + * + * @param cls closure, unused + * @param type number of a type to convert + * @return corresponding typestring, NULL on error + */ +static const char * +credential_number_to_typename (void *cls, + uint32_t type) +{ + unsigned int i; + + i=0; + while ( (name_map[i].name != NULL) && + (type != name_map[i].number) ) + i++; + return name_map[i].name; +} + + +/** + * Entry point for the plugin. + * + * @param cls NULL + * @return the exported block API + */ +void * +libgnunet_plugin_gnsrecord_credential_init (void *cls) +{ + struct GNUNET_GNSRECORD_PluginFunctions *api; + + api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions); + api->value_to_string = &credential_value_to_string; + api->string_to_value = &credential_string_to_value; + api->typename_to_number = &credential_typename_to_number; + api->number_to_typename = &credential_number_to_typename; + return api; +} + + +/** + * Exit point from the plugin. + * + * @param cls the return value from #libgnunet_plugin_block_test_init + * @return NULL + */ +void * +libgnunet_plugin_gnsrecord_credential_done (void *cls) +{ + struct GNUNET_GNSRECORD_PluginFunctions *api = cls; + + GNUNET_free (api); + return NULL; +} + +/* end of plugin_gnsrecord_credential.c */ diff --git a/src/credential/test_credential_lookup.sh b/src/credential/test_credential_lookup.sh new file mode 100755 index 0000000000..216c281d7a --- /dev/null +++ b/src/credential/test_credential_lookup.sh @@ -0,0 +1,40 @@ +#!/bin/bash +trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT + +LOCATION=$(which gnunet-config) +if [ -z $LOCATION ] +then + LOCATION="gnunet-config" +fi +$LOCATION --version 1> /dev/null +if test $? != 0 +then + echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" + exit 77 +fi + +rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` +which timeout &> /dev/null && DO_TIMEOUT="timeout 30" +TEST_CREDENTIAL="keySub keyIss credName" +gnunet-arm -s -c test_credential_lookup.conf +gnunet-identity -C testsubject -c test_credential_lookup.conf + +#TODO1 Plugin serialization functions see REVERSE in gns/plugin_gnsrecord_gns.c +gnunet-namestore -p -z testsubject -a -n newcred -t CRED -V $TEST_CREDENTIAL -e never -c test_credential_lookup.conf + +#TODO2 Add -z swich like in gnunet-gns +RES_IP=`$DO_TIMEOUT gnunet-credential -z testsubject -s testsubject -u credName -c test_credential_lookup.conf` +gnunet-namestore -z testsubject -d -n newcred -t CRED -e never -c test_credential_lookup.conf +gnunet-identity -D testsubject -c test_credential_lookup.conf +gnunet-arm -e -c test_credential_lookup.conf + +#TODO3 proper test +exit 0 + +#if [ "$RES_IP" == "$TEST_CRED" ] +#then +# exit 0 +#else +# echo "FAIL: Failed to resolve to proper IP, got $RES_IP." +# exit 1 +#fi diff --git a/src/include/gnunet_credential_service.h b/src/include/gnunet_credential_service.h index 99d4161698..55deb786e1 100644 --- a/src/include/gnunet_credential_service.h +++ b/src/include/gnunet_credential_service.h @@ -34,6 +34,7 @@ #include "gnunet_util_lib.h" #include "gnunet_gns_service.h" +#include "gnunet_identity_service.h" #ifdef __cplusplus extern "C" @@ -54,6 +55,44 @@ struct GNUNET_CREDENTIAL_Handle; */ struct GNUNET_CREDENTIAL_LookupRequest; +/* +* Enum used for checking whether the issuer has the authority to issue credentials or is just a subject +*/ +enum GNUNET_CREDENTIAL_CredentialFlags { + + //Subject had credentials before, but have been revoked now + GNUNET_CREDENTIAL_FLAG_REVOKED=0, + + //Subject flag indicates that the subject is a holder of this credential and may present it as such + GNUNET_CREDENTIAL_FLAG_SUBJECT=1, + + //Issuer flag is used to signify that the subject is allowed to issue this credential and delegate issuance + GNUNET_CREDENTIAL_FLAG_ISSUER=2 + +}; + +GNUNET_NETWORK_STRUCT_BEGIN +/* +* Data stored in the credential record +*/ +struct GNUNET_CREDENTIAL_RecordData { + + /* + * Key of the + */ + struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; + + struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; + + + uint32_t credential_flags GNUNET_PACKED; + + uint32_t max_delegation_depth GNUNET_PACKED; +}; + +GNUNET_NETWORK_STRUCT_END + + /** * Initialize the connection with the Credential service. @@ -61,7 +100,7 @@ struct GNUNET_CREDENTIAL_LookupRequest; * @param cfg configuration to use * @return handle to the Credential service, or NULL on error */ -struct GNUNET_Credential_Handle * +struct GNUNET_CREDENTIAL_Handle * GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); @@ -85,7 +124,7 @@ GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle); typedef void (*GNUNET_CREDENTIAL_LookupResultProcessor) (void *cls, struct GNUNET_IDENTITY_Ego *issuer, uint16_t issuer_len, - const struct GNUNET_CREDENTIAL_Value *value); + const struct GNUNET_CREDENTIAL_RecordData *data); /** @@ -102,7 +141,11 @@ struct GNUNET_CREDENTIAL_LookupRequest * GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle, const char *credential, const struct GNUNET_IDENTITY_Ego *subject, - GNUNET_CREDENTIAL_LookupResultProcessor proc, + const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, + uint32_t credential_flags, + uint32_t max_delegation_depth, + GNUNET_CREDENTIAL_LookupResultProcessor proc, void *proc_cls); @@ -113,18 +156,18 @@ GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle, * @param issuer the identity that issues the credential * @param subject the subject of the credential * @param credential the name of the credential - * @param value the value of the credential + * @param data the data of the credential * @return handle to the queued request */ -struct GNUNET_CREDENTIAL_IssueRequest * +/**struct GNUNET_CREDENTIAL_IssueRequest * GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle, struct GNUNET_IDENTITY_Ego *issuer, struct GNUNET_IDENTITY_Ego *subject, const char *credential, - struct GNUNET_CREDENTIAL_Value *value, + struct GNUNET_CREDENTIAL_Data *data, GNUNET_CREDENTIAL_IssueResultProcessor proc, void *proc_cls); - +*/ /** * Remove a credential * @@ -134,6 +177,7 @@ GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle, * @param credential the name of the credential * @return handle to the queued request */ + /** struct GNUNET_CREDENTIAL_IssueRequest * GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle, struct GNUNET_IDENTITY_Ego *issuer, @@ -141,7 +185,7 @@ GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle, const char *credential, GNUNET_CREDENTIAL_IssueResultProcessor proc, void *proc_cls); - +*/ /** diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index 985ae1f7ab..7e0a1a9e96 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h @@ -109,10 +109,17 @@ extern "C" #define GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA 65546 /** + * Record type for credential + */ +#define GNUNET_GNSRECORD_TYPE_CREDENTIAL 65547 + +/** * Record type for reverse lookups */ #define GNUNET_GNSRECORD_TYPE_REVERSE 65548 + + /** * Flags that can be set for a record. */ diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index db479d2350..3e16350c16 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -2607,6 +2607,15 @@ extern "C" #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT 964 + +/************************************************** + * + * CREDENTIAL MESSAGE TYPES + */ +#define GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP 971 + +#define GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT 972 + /******************************************************************************/ |