gnunet

Main GNUnet Logic
Log | Files | Refs | Submodules | README | LICENSE

commit cd0ff18525770f9f3578c90a2dc6938911c910df
parent 5126e9d42b24a0a6cf26de79b65bcd23790dee9b
Author: Phil <phil.buschmann@tum.de>
Date:   Thu,  7 Dec 2017 11:31:52 +0000

Merge branch 'identity_oidc' of git-int.aisec.fraunhofer.de:sas/gnunet-mirror into identity_oidc

Diffstat:
Mpo/POTFILES.in | 2+-
Msrc/identity-attribute/Makefile.am | 4++--
Msrc/identity-attribute/identity_attribute.c | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/identity-attribute/plugin_identity_attribute_gnuid.c | 4++--
Msrc/identity-provider/Makefile.am | 3++-
Msrc/identity-provider/gnunet-idp.c | 40+++++++++++++++++++++++++++++++++-------
Msrc/identity-provider/jwt.c | 30+++++++++++++++++++-----------
Msrc/identity-provider/plugin_rest_identity_provider.c | 316+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/include/gnunet_identity_attribute_lib.h | 46++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 447 insertions(+), 174 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in @@ -197,7 +197,7 @@ src/hostlist/gnunet-daemon-hostlist.c src/hostlist/gnunet-daemon-hostlist_client.c src/hostlist/gnunet-daemon-hostlist_server.c src/identity-attribute/identity_attribute.c -src/identity-attribute/plugin_identity_attribute_type_gnuid.c +src/identity-attribute/plugin_identity_attribute_gnuid.c src/identity-provider/gnunet-idp.c src/identity-provider/gnunet-service-identity-provider.c src/identity-provider/identity_provider_api.c diff --git a/src/identity-attribute/Makefile.am b/src/identity-attribute/Makefile.am @@ -20,7 +20,7 @@ lib_LTLIBRARIES = \ libgnunetidentityattribute.la libgnunetidentityattribute_la_SOURCES = \ - identity_attribute.c + identity_attribute.c libgnunetidentityattribute_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) @@ -38,7 +38,7 @@ libgnunet_plugin_identity_attribute_gnuid_la_SOURCES = \ libgnunet_plugin_identity_attribute_gnuid_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(LTLIBINTL) -libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \ +libgnunet_plugin_identity_attribute_gnuid_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) diff --git a/src/identity-attribute/identity_attribute.c b/src/identity-attribute/identity_attribute.c @@ -26,6 +26,182 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "identity_attribute.h" +#include "gnunet_identity_attribute_plugin.h" + +/** + * Handle for a plugin + */ +struct Plugin +{ + /** + * Name of the plugin + */ + char *library_name; + + /** + * Plugin API + */ + struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api; +}; + +/** + * Plugins + */ +static struct Plugin **attr_plugins; + +/** + * Number of plugins + */ +static unsigned int num_plugins; + +/** + * Init canary + */ +static int initialized; + +/** + * Add a plugin + */ +static void +add_plugin (void* cls, + const char *library_name, + void *lib_ret) +{ + struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = lib_ret; + struct Plugin *plugin; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Loading attribute plugin `%s'\n", + library_name); + plugin = GNUNET_new (struct Plugin); + plugin->api = api; + plugin->library_name = GNUNET_strdup (library_name); + GNUNET_array_append (attr_plugins, num_plugins, plugin); +} + +/** + * Load plugins + */ +static void +init() +{ + if (GNUNET_YES == initialized) + return; + initialized = GNUNET_YES; + GNUNET_PLUGIN_load_all ("libgnunet_plugin_identity_attribute_", NULL, + &add_plugin, NULL); +} + +/** + * Convert a type name to the corresponding number + * + * @param typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename) +{ + unsigned int i; + struct Plugin *plugin; + uint32_t ret; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = attr_plugins[i]; + if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls, + typename))) + return ret; + } + return UINT32_MAX; +} + +/** + * Convert a type number to the corresponding type string + * + * @param type number of a type + * @return corresponding typestring, NULL on error + */ +const char* +GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type) +{ + unsigned int i; + struct Plugin *plugin; + const char *ret; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = attr_plugins[i]; + if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls, + type))) + return ret; + } + return NULL; +} + +/** + * Convert human-readable version of a 'claim' of an attribute to the binary + * representation + * + * @param type type of the claim + * @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 + */ +int +GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type, + const char *s, + void **data, + size_t *data_size) +{ + unsigned int i; + struct Plugin *plugin; + + init (); + for (i = 0; i < num_plugins; i++) + { + plugin = attr_plugins[i]; + if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls, + type, + s, + data, + data_size)) + return GNUNET_OK; + } + return GNUNET_SYSERR; +} + +/** + * Convert the 'claim' of an attribute to a string + * + * @param type the type of attribute + * @param data claim in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the claim + */ +char * +GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type, + const void* data, + size_t data_size) +{ + unsigned int i; + struct Plugin *plugin; + char *ret; + + init(); + for (i = 0; i < num_plugins; i++) + { + plugin = attr_plugins[i]; + if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls, + type, + data, + data_size))) + return ret; + } + return NULL; +} /** * Create a new attribute. diff --git a/src/identity-attribute/plugin_identity_attribute_gnuid.c b/src/identity-attribute/plugin_identity_attribute_gnuid.c @@ -153,7 +153,7 @@ gnuid_number_to_typename (void *cls, * @return the exported block API */ void * -libgnunet_plugin_attribute_type_gnuid_init (void *cls) +libgnunet_plugin_identity_attribute_gnuid_init (void *cls) { struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api; @@ -173,7 +173,7 @@ libgnunet_plugin_attribute_type_gnuid_init (void *cls) * @return NULL */ void * -libgnunet_plugin_attribute_type_gnuid_done (void *cls) +libgnunet_plugin_identity_attribute_gnuid_done (void *cls) { struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = cls; diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am @@ -87,7 +87,8 @@ libgnunetidentityprovider_la_LDFLAGS = \ -version-info 0:0:0 libgnunet_plugin_rest_identity_provider_la_SOURCES = \ - plugin_rest_identity_provider.c + plugin_rest_identity_provider.c \ + jwt.c libgnunet_plugin_rest_identity_provider_la_LIBADD = \ $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetidentityprovider.la \ diff --git a/src/identity-provider/gnunet-idp.c b/src/identity-provider/gnunet-idp.c @@ -67,6 +67,11 @@ static char* issue_attrs; static char* consume_ticket; /** + * Attribute type + */ +static char* type_str; + +/** * Ticket to revoke */ static char* revoke_ticket; @@ -168,6 +173,7 @@ process_attrs (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) { + char *value_str; if (NULL == identity) { GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); @@ -178,8 +184,11 @@ process_attrs (void *cls, ret = 1; return; } + value_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (attr->type, + attr->data, + attr->data_size); GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - "%s: %s\n", attr->name, (char*)attr->data); + "%s: %s\n", attr->name, value_str); } @@ -207,7 +216,10 @@ process_rvk (void *cls, int success, const char* msg) static void iter_finished (void *cls) { - struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; + struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim; + char *data; + size_t data_size; + int type; attr_iterator = NULL; if (list) @@ -244,13 +256,22 @@ iter_finished (void *cls) NULL); return; } - attr = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name, - GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING, - attr_value, - strlen (attr_value) + 1); + if (NULL == type_str) + type = GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING; + else + type = GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (type_str); + + GNUNET_assert (GNUNET_SYSERR != GNUNET_IDENTITY_ATTRIBUTE_string_to_value (type, + attr_value, + (void**)&data, + &data_size)); + claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name, + type, + data, + data_size); idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle, pkey, - attr, + claim, &store_attr_cont, NULL); @@ -404,6 +425,11 @@ main(int argc, char *const argv[]) NULL, gettext_noop ("Revoke a ticket"), &revoke_ticket), + GNUNET_GETOPT_option_string ('t', + "type", + NULL, + gettext_noop ("Type of attribute"), + &type_str), GNUNET_GETOPT_OPTION_END }; GNUNET_PROGRAM_run (argc, argv, "ct", diff --git a/src/identity-provider/jwt.c b/src/identity-provider/jwt.c @@ -26,7 +26,7 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_signatures.h" -#include "identity_attribute.h" +#include "gnunet_identity_attribute_lib.h" #include <jansson.h> @@ -55,18 +55,20 @@ create_jwt_header(void) } /** - * Create a JWT from a ticket and attributes + * Create a JWT from attributes * - * @param ticket the ticket + * @param sub_key the public of the subject * @param attrs the attribute list + * @param priv_key the key used to sign the JWT * @return a new base64-encoded JWT string. */ char* -jwt_create (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, - const struct GNUNET_IDENTITY_PROVIDER_AttributeList *attrs, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key) +jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, + const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key) { - struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le; + struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; + struct GNUNET_CRYPTO_EcdsaPublicKey iss_key; struct GNUNET_CRYPTO_EcdsaSignature signature; struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; char* audience; @@ -79,12 +81,14 @@ jwt_create (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, char* body_base64; char* signature_target; char* signature_base64; + char* attr_val_str; json_t* body; + GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &iss_key); /* TODO maybe we should use a local identity here */ - issuer = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, + issuer = GNUNET_STRINGS_data_to_string_alloc (&iss_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - audience = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, + audience = GNUNET_STRINGS_data_to_string_alloc (sub_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); header = create_jwt_header (); body = json_object (); @@ -103,9 +107,13 @@ jwt_create (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, * calls the Attribute plugins to create a * json representation for its value */ + attr_val_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (le->claim->type, + le->claim->data, + le->claim->data_size); json_object_set_new (body, - le->attribute->name, - json_string (le->attribute->data)); + le->claim->name, + json_string (attr_val_str)); + GNUNET_free (attr_val_str); } body_str = json_dumps (body, JSON_INDENT(0)); json_decref (body); diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c @@ -1027,156 +1027,172 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, */ static void authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) + const char* url, + void *cls) { - //TODO clean up method - - -// The Authorization Server MUST validate all the OAuth 2.0 parameters according to the OAuth 2.0 specification. -// The Authorization Server MUST verify that all the REQUIRED parameters are present and their usage conforms to this specification. -// If the sub (subject) Claim is requested with a specific value for the ID Token, the Authorization Server MUST only send a positive response if the End-User identified by that sub value has an active session with the Authorization Server or has been Authenticated as a result of the request. The Authorization Server MUST NOT reply with an ID Token or Access Token for a different user, even if they have an active session with the Authorization Server. Such a request can be made either using an id_token_hint parameter or by requesting a specific Claim Value as described in Section 5.5.1, if the claims parameter is supported by the implementation. - - - - struct MHD_Response *resp; - struct RequestHandle *handle = cls; - - /* - * response_type 0 - * client_id 1 - * scope 2 - * redirect_uri 3 - * state 4 - * nonce 5 - * display 6 - * prompt 7 - * max_age 8 - * ui_locales 9 - * response_mode 10 - * id_token_hint 11 - * login_hint 12 - * acr_values 13 - */ - char* array[] = { "response_type", "client_id", "scope", "redirect_uri", - "state", "nonce", "display", "prompt", "max_age", "ui_locales", - "response_mode", "id_token_hint","login_hint", "acr_values" }; - int array_size=14; - int bool_array[array_size]; - - struct GNUNET_HashCode cache_key; - - //iterates over each parameter and store used values in array array[] - int iterator; - for( iterator = 0; iterator<array_size; iterator++){ - GNUNET_CRYPTO_hash (array[iterator], strlen (array[iterator]), &cache_key); - char* cache=GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, &cache_key); - bool_array[iterator]=0; - if(cache!=0){ - size_t size=strlen(cache)+1; - array[iterator]=(char*)malloc(size*sizeof(char)); - strncpy(array[iterator],cache,size); - bool_array[iterator]=1; - } - } - - //MUST validate all the OAuth 2.0 parameters & that all the REQUIRED parameters are present and their usage conforms to this specification - - //required values: response_type, client_id, scope, redirect_uri - if(!bool_array[0] || !bool_array[1] || !bool_array[2] || !bool_array[3]){ - handle->emsg=GNUNET_strdup("invalid_request"); - handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - //response_type = code - if(strcmp(array[0],"code")!=0){ - handle->emsg=GNUNET_strdup("invalid_response_type"); - handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - //scope contains openid - if(strstr(array[2],"openid")==NULL){ - handle->emsg=GNUNET_strdup("invalid_scope"); - handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - //TODO check other values and use them accordingly - - - char* redirect_url_to_login; - -// if(){ -// -// }else{ -// -// } - if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, - "identity-rest-plugin", - "address", - &redirect_url_to_login)){ - - char* build_array[] = { "response_type", "client_id", "scope", "redirect_uri", - "state", "nonce", "display", "prompt", "max_age", "ui_locales", - "response_mode", "id_token_hint","login_hint", "acr_values" }; - - size_t redirect_parameter_size= strlen("?"); - for(iterator=0;iterator<array_size;iterator++){ - if(bool_array[iterator]){ - redirect_parameter_size += strlen(array[iterator]); - redirect_parameter_size += strlen(build_array[iterator]); - if(iterator==array_size-1) - { - redirect_parameter_size += strlen("="); - }else{ - redirect_parameter_size += strlen("=&"); - } - } - } - - char redirect_parameter[redirect_parameter_size+1]; - redirect_parameter_size = 0; - redirect_parameter[redirect_parameter_size]='?'; - for(iterator=0;iterator<array_size;iterator++){ - if(bool_array[iterator]){ - //If not last parameter - if(iterator!=array_size-1) - { - char cache[strlen(array[iterator])+strlen(build_array[iterator])+2+1]; - snprintf(cache,sizeof(cache),"%s=%s&", build_array[iterator], array[iterator]); - strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+2 ); - }else{ - char cache[strlen(array[iterator])+strlen(build_array[iterator])+1+1]; - snprintf(cache,sizeof(cache),"%s=%s", build_array[iterator], array[iterator]); - strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+1 ); - } - } - } - char redirect_component[strlen(redirect_url_to_login)+strlen(redirect_parameter)+1]; - snprintf(redirect_component, sizeof(redirect_component), "%s%s", redirect_url_to_login, redirect_parameter); - resp = GNUNET_REST_create_response (""); - MHD_add_response_header (resp, "Location", redirect_component); - }else{ - handle->emsg=GNUNET_strdup("No server on localhost:8000"); - handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; -// resp = GNUNET_REST_create_response (""); -// MHD_add_response_header (resp, "Location", array[3]); - } - - handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); - cleanup_handle (handle); - for(iterator=0; iterator<array_size; iterator++){ - if(bool_array[iterator]){ - free(array[iterator]); - } - } - return; + //TODO clean up method + + + // The Authorization Server MUST validate all the OAuth 2.0 parameters according to the OAuth 2.0 specification. + // The Authorization Server MUST verify that all the REQUIRED parameters are present and their usage conforms to this specification. + // If the sub (subject) Claim is requested with a specific value for the ID Token, the Authorization Server MUST only send a positive response if the End-User identified by that sub value has an active session with the Authorization Server or has been Authenticated as a result of the request. The Authorization Server MUST NOT reply with an ID Token or Access Token for a different user, even if they have an active session with the Authorization Server. Such a request can be made either using an id_token_hint parameter or by requesting a specific Claim Value as described in Section 5.5.1, if the claims parameter is supported by the implementation. + + + + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + /* + * response_type 0 + * client_id 1 + * scope 2 + * redirect_uri 3 + * state 4 + * nonce 5 + * display 6 + * prompt 7 + * max_age 8 + * ui_locales 9 + * response_mode 10 + * id_token_hint 11 + * login_hint 12 + * acr_values 13 + */ + char* array[] = { "response_type", "client_id", "scope", "redirect_uri", + "state", "nonce", "display", "prompt", "max_age", "ui_locales", + "response_mode", "id_token_hint","login_hint", "acr_values" }; + int array_size=14; + int bool_array[array_size]; + + struct GNUNET_HashCode cache_key; + + //iterates over each parameter and store used values in array array[] + int iterator; + for( iterator = 0; iterator<array_size; iterator++){ + GNUNET_CRYPTO_hash (array[iterator], strlen (array[iterator]), &cache_key); + char* cache=GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, &cache_key); + bool_array[iterator]=0; + if(cache!=0){ + size_t size=strlen(cache)+1; + array[iterator]=(char*)malloc(size*sizeof(char)); + strncpy(array[iterator],cache,size); + bool_array[iterator]=1; + } + } + + /* MUST validate all the OAuth 2.0 parameters & that all the + * REQUIRED parameters are present and their usage conforms to this specification + */ + GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (array[iterator]), &cache_key); + if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, + &key)) + { + handle->emsg=GNUNET_strdup("invalid_request"); + handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, + &key); + + //required values: response_type, client_id, scope, redirect_uri + if(!bool_array[0] || !bool_array[1] || !bool_array[2] || !bool_array[3]){ + handle->emsg=GNUNET_strdup("invalid_request"); + handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + //response_type = code + if(strcmp(array[0],"code")!=0){ + handle->emsg=GNUNET_strdup("invalid_response_type"); + handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + //scope contains openid + if(strstr(array[2],"openid")==NULL){ + handle->emsg=GNUNET_strdup("invalid_scope"); + handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + //TODO check other values and use them accordingly + + + char* redirect_url_to_login; + + // if(){ + // + // }else{ + // + // } + if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, + "identity-rest-plugin", + "address", + &redirect_url_to_login)){ + + char* build_array[] = { "response_type", "client_id", "scope", "redirect_uri", + "state", "nonce", "display", "prompt", "max_age", "ui_locales", + "response_mode", "id_token_hint","login_hint", "acr_values" }; + GNUNET_asprintf (new_redirect, "%s=%s&...", + OIDC_REDIRECT_URI_KEY, redirect_uri, + OIDC_CLIENT_ID_KEY, client_id, + ...); + size_t redirect_parameter_size= strlen("?"); + for(iterator=0;iterator<array_size;iterator++){ + if(bool_array[iterator]){ + redirect_parameter_size += strlen(array[iterator]); + redirect_parameter_size += strlen(build_array[iterator]); + if(iterator==array_size-1) + { + redirect_parameter_size += strlen("="); + }else{ + redirect_parameter_size += strlen("=&"); + } + } + } + + char redirect_parameter[redirect_parameter_size+1]; + redirect_parameter_size = 0; + redirect_parameter[redirect_parameter_size]='?'; + for(iterator=0;iterator<array_size;iterator++){ + if(bool_array[iterator]){ + //If not last parameter + if(iterator!=array_size-1) + { + char cache[strlen(array[iterator])+strlen(build_array[iterator])+2+1]; + snprintf(cache,sizeof(cache),"%s=%s&", build_array[iterator], array[iterator]); + strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+2 ); + }else{ + char cache[strlen(array[iterator])+strlen(build_array[iterator])+1+1]; + snprintf(cache,sizeof(cache),"%s=%s", build_array[iterator], array[iterator]); + strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+1 ); + } + } + } + char redirect_component[strlen(redirect_url_to_login)+strlen(redirect_parameter)+1]; + snprintf(redirect_component, sizeof(redirect_component), "%s%s", redirect_url_to_login, redirect_parameter); + resp = GNUNET_REST_create_response (""); + MHD_add_response_header (resp, "Location", redirect_component); + }else{ + handle->emsg=GNUNET_strdup("No server on localhost:8000"); + handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + // resp = GNUNET_REST_create_response (""); + // MHD_add_response_header (resp, "Location", array[3]); + } + + handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); + cleanup_handle (handle); + for(iterator=0; iterator<array_size; iterator++){ + if(bool_array[iterator]){ + free(array[iterator]); + } + } + return; } /** @@ -1192,8 +1208,8 @@ init_cont (struct RequestHandle *handle) {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, + {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, diff --git a/src/include/gnunet_identity_attribute_lib.h b/src/include/gnunet_identity_attribute_lib.h @@ -213,6 +213,52 @@ GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data, struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList* GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); +/** + * Convert a type name to the corresponding number + * + * @param typename name to convert + * @return corresponding number, UINT32_MAX on error + */ +uint32_t +GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename); + +/** + * Convert human-readable version of a 'claim' of an attribute to the binary + * representation + * + * @param type type of the claim + * @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 + */ +int +GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type, + const char *s, + void **data, + size_t *data_size); + +/** + * Convert the 'claim' of an attribute to a string + * + * @param type the type of attribute + * @param data claim in binary encoding + * @param data_size number of bytes in @a data + * @return NULL on error, otherwise human-readable representation of the claim + */ +char * +GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type, + const void* data, + size_t data_size); + +/** + * Convert a type number to the corresponding type string + * + * @param type number of a type + * @return corresponding typestring, NULL on error + */ +const char* +GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type); #if 0 /* keep Emacsens' auto-indent happy */