*/
struct GNUNET_GNS_LookupRequest *gns_lookup;
+ /**
+ * Handle to Ego lookup, during #SOCKS5_RESOLVING phase.
+ */
+ struct GNUNET_IDENTITY_EgoLookup *el;
+
/**
* Client socket read task
*/
*/
char *domain;
+ /**
+ * the tld
+ */
+ const char *tld;
+
/**
* DNS Legacy Host Name as given by GNS, NULL if not given.
*/
if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain))
{
offset += sprintf (new_cookie_hdr + offset,
- " domain=%s;",
- s5r->domain);
+ " domain=%s.%s;",
+ s5r->domain,
+ s5r->tld);
continue;
}
}
else if (0 == strcmp (cookie_domain, s5r->leho))
{
offset += sprintf (new_cookie_hdr + offset,
- " domain=%s;",
- s5r->domain);
+ " domain=%s.%s;",
+ s5r->domain,
+ s5r->tld);
continue;
}
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
strlen (leho_host)))
{
GNUNET_asprintf (&new_location,
- "%s%s%s",
+ "%s%s.%s%s",
(HTTPS_PORT != s5r->port)
? "http://"
: "https://",
s5r->domain,
+ s5r->tld,
hdr_val + strlen (leho_host));
hdr_val = new_location;
}
int fd;
const struct sockaddr *addr;
socklen_t len;
+ char *domain;
switch (s5r->port)
{
case HTTPS_PORT:
- hd = lookup_ssl_httpd (s5r->domain);
+ GNUNET_asprintf (&domain,
+ "%s.%s",
+ s5r->domain,
+ s5r->tld);
+ hd = lookup_ssl_httpd (domain);
if (NULL == hd)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Failed to start HTTPS server for `%s'\n"),
s5r->domain);
cleanup_s5r (s5r);
+ GNUNET_free (domain);
return;
}
break;
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_("Failed to pass client to MHD\n"));
cleanup_s5r (s5r);
+ GNUNET_free (domain);
return;
}
s5r->hd = hd;
s5r->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_HANDSHAKE_TIMEOUT,
&timeout_s5r_handshake,
s5r);
+ GNUNET_free (domain);
}
}
+/**
+ * Method called to with the ego we are to use for the lookup,
+ * when the ego is determined by a name.
+ *
+ * @param cls closure (NULL, unused)
+ * @param ego ego handle, NULL if not found
+ */
+static void
+identity_zone_cb (void *cls,
+ const struct GNUNET_IDENTITY_Ego *ego)
+{
+ struct Socks5Request *s5r = cls;
+ struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
+
+ s5r->el = NULL;
+ if (NULL == ego)
+ {
+ signal_socks_failure (s5r,
+ SOCKS5_STATUS_GENERAL_FAILURE);
+ return;
+
+ }
+ GNUNET_IDENTITY_ego_get_public_key (ego,
+ &pkey);
+ s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
+ s5r->domain,
+ &pkey,
+ GNUNET_DNSPARSER_TYPE_A,
+ GNUNET_NO /* only cached */,
+ &handle_gns_result,
+ s5r);
+
+
+}
+
+/**
+ * Obtain TLD from @a name
+ *
+ * @param name a name
+ * @return the part of @a name after the last ".",
+ * or @a name if @a name does not contain a "."
+ */
+static const char *
+get_tld (const char *name)
+{
+ const char *tld;
+
+ tld = strrchr (name,
+ (unsigned char) '.');
+ if (NULL == tld)
+ tld = name;
+ else
+ tld++; /* skip the '.' */
+ return tld;
+}
+
+/**
+ * Eat the TLD of the given @a name.
+ *
+ * @param name a name
+ */
+static void
+eat_tld (char *name)
+{
+ char *tld;
+
+ GNUNET_assert (0 < strlen (name));
+ tld = strrchr (name,
+ (unsigned char) '.');
+ if (NULL == tld)
+ strcpy (name,
+ GNUNET_GNS_MASTERZONE_STR);
+ else
+ *tld = '\0';
+}
+
/**
* Read data from incoming Socks5 connection
*
ssize_t rlen;
size_t alen;
const struct GNUNET_SCHEDULER_TaskContext *tc;
+ char *zonestr;
+ char *dot_tld;
+ struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
s5r->rtask = NULL;
tc = GNUNET_SCHEDULER_get_task_context ();
ntohs (*port));
s5r->state = SOCKS5_RESOLVING;
s5r->port = ntohs (*port);
- s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
- s5r->domain,
- &local_gns_zone,
- GNUNET_DNSPARSER_TYPE_A,
- GNUNET_NO /* only cached */,
- &handle_gns_result,
- s5r);
+ /* TLD is zkey */
+ s5r->tld = get_tld (s5r->domain);
+ if (GNUNET_OK ==
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (s5r->tld,
+ strlen (s5r->tld),
+ &pkey))
+ {
+ eat_tld (s5r->domain);
+ s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
+ s5r->domain,
+ &pkey,
+ GNUNET_DNSPARSER_TYPE_A,
+ GNUNET_NO /* only cached */,
+ &handle_gns_result,
+ s5r);
+
+ break;
+ }
+ /* TLD is mapped in our config */
+ GNUNET_asprintf (&dot_tld,
+ ".%s",
+ s5r->tld);
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "gns",
+ dot_tld,
+ &zonestr))
+ {
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr,
+ strlen (zonestr),
+ &pkey))
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "gns",
+ dot_tld,
+ _("Expected a base32-encoded public zone key\n"));
+ GNUNET_free (zonestr);
+ GNUNET_free (dot_tld);
+ signal_socks_failure (s5r,
+ SOCKS5_STATUS_GENERAL_FAILURE);
+ return;
+
+ }
+ GNUNET_free (zonestr);
+ GNUNET_free (dot_tld);
+ eat_tld (s5r->domain);
+ s5r->gns_lookup = GNUNET_GNS_lookup (gns_handle,
+ s5r->domain,
+ &pkey,
+ GNUNET_DNSPARSER_TYPE_A,
+ GNUNET_NO /* only cached */,
+ &handle_gns_result,
+ s5r);
+ break;
+ }
+
+ /* TLD matches against ego */
+ eat_tld (s5r->domain);
+
+ s5r->el = GNUNET_IDENTITY_ego_lookup (cfg,
+ s5r->tld,
+ &identity_zone_cb,
+ s5r);
break;
}
default:
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_ulong ('p',
- "port",
- NULL,
- gettext_noop ("listen on specified port (default: 7777)"),
- &port),
+ "port",
+ NULL,
+ gettext_noop ("listen on specified port (default: 7777)"),
+ &port),
GNUNET_GETOPT_option_string ('a',
"authority",
size_t size;
char *buf;
char *scope;
- char *lookup_query;
handle->lookup_request = NULL;
if (1 != rd_count)
for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ","))
{
- GNUNET_asprintf (&lookup_query,
- "%s.gnu",
- scope);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Looking up %s\n", lookup_query);
+ "Looking up %s\n", scope);
parallel_lookup = GNUNET_new (struct ParallelLookup);
parallel_lookup->handle = handle;
parallel_lookup->label = GNUNET_strdup (scope);
parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
parallel_lookup->lookup_request
= GNUNET_GNS_lookup (gns_handle,
- lookup_query,
+ scope,
&handle->ticket.identity,
GNUNET_GNSRECORD_TYPE_ID_ATTR,
GNUNET_GNS_LO_DEFAULT,
GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head,
handle->parallel_lookups_tail,
parallel_lookup);
- GNUNET_free (lookup_query);
+ GNUNET_free (scope);
}
GNUNET_free (scopes);
GNUNET_free (buf);
{
struct ConsumeTicketHandle *ch;
struct IdpClient *idp = cls;
- char* lookup_query;
char* rnd_label;
ch = GNUNET_new (struct ConsumeTicketHandle);
ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]);
rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd,
sizeof (uint64_t));
- GNUNET_asprintf (&lookup_query,
- "%s.gnu",
- rnd_label);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Looking for ABE key under %s\n", lookup_query);
+ "Looking for ABE key under %s\n", rnd_label);
ch->lookup_start_time = GNUNET_TIME_absolute_get ();
ch->lookup_request
= GNUNET_GNS_lookup (gns_handle,
- lookup_query,
+ rnd_label,
&ch->ticket.identity,
GNUNET_GNSRECORD_TYPE_ABE_KEY,
GNUNET_GNS_LO_DEFAULT,
&process_consume_abe_key,
ch);
GNUNET_free (rnd_label);
- GNUNET_free (lookup_query);
GNUNET_SERVICE_client_continue (idp->client);
}
[identity-rest-plugin]
#ADDRESS = https://identity.gnu:8000#/login
-ADDRESS = https://identity.gnu/ui/#/login
+ADDRESS = https://reclaim.id/ui/#/login
PSW = secret
EXPIRATION_TIME = 3600
*/
char *url;
+ /**
+ * The tld for redirect
+ */
+ char *tld;
+
/**
* Error response message
*/
GNUNET_IDENTITY_PROVIDER_disconnect (handle->idp);
if (NULL != handle->url)
GNUNET_free (handle->url);
+ if (NULL != handle->tld)
+ GNUNET_free (handle->tld);
if (NULL != handle->emsg)
GNUNET_free (handle->emsg);
if (NULL != handle->edesc)
char *code_base64_final_string;
char *redirect_path;
char *tmp;
+ char *tmp_prefix;
+ char *prefix;
ticket_str = GNUNET_STRINGS_data_to_string_alloc (&handle->ticket,
sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
//TODO change if more attributes are needed (see max_age)
redirect_path = strtok (tmp, "/");
redirect_path = strtok (NULL, "/");
redirect_path = strtok (NULL, "/");
- GNUNET_asprintf (&redirect_uri, "https://%s.gnu/%s?%s=%s&state=%s",
- label,
+ tmp_prefix = GNUNET_strdup (handle->oidc->redirect_uri);
+ prefix = strrchr (tmp_prefix,
+ (unsigned char) '.');
+ *prefix = '\0';
+ GNUNET_asprintf (&redirect_uri, "%s.%s/%s?%s=%s&state=%s",
+ tmp_prefix,
+ handle->tld,
redirect_path,
handle->oidc->response_type,
code_base64_final_string, handle->oidc->state);
handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
GNUNET_free (tmp);
+ GNUNET_free (tmp_prefix);
GNUNET_free (redirect_uri);
GNUNET_free (ticket_str);
GNUNET_free (code_json_string);
struct RequestHandle *handle = cls;
struct GNUNET_HashCode cache_key;
- char *expected_redirect_uri;
char *expected_scope;
char delimiter[]=" ";
int number_of_ignored_parameter, iterator;
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
- handle->oidc->redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
- &cache_key);
+ handle->oidc->redirect_uri = GNUNET_strdup (GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
+ &cache_key));
- GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", handle->oidc->client_id);
- // verify the redirect uri matches https://<client_id>.zkey[/xyz]
- if( 0 != strncmp( expected_redirect_uri, handle->oidc->redirect_uri, strlen(expected_redirect_uri)) )
- {
- handle->oidc->redirect_uri = NULL;
- handle->emsg=GNUNET_strdup("invalid_request");
- handle->edesc=GNUNET_strdup("Invalid redirect_uri");
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- GNUNET_free(expected_redirect_uri);
- return;
- }
- handle->oidc->redirect_uri = GNUNET_strdup(handle->oidc->redirect_uri);
-
- GNUNET_free(expected_redirect_uri);
// REQUIRED value: response_type
GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (OIDC_RESPONSE_TYPE_KEY),
&cache_key);
{
struct RequestHandle *handle = cls;
struct GNUNET_HashCode cache_key;
+ struct EgoEntry *tmp_ego;
+ struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
cookie_identity_interpretation(handle);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
- handle->oidc->client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
- &cache_key);
- handle->oidc->client_id = GNUNET_strdup (handle->oidc->client_id);
+ handle->oidc->client_id = GNUNET_strdup (GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
+ &cache_key));
if ( GNUNET_OK
!= GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id,
handle->ego_entry = handle->ego_head;
handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego);
handle->oidc->is_client_trusted = GNUNET_NO;
+
+ //First check if client_id is one of our egos; TODO: handle other TLD cases: Delegation, from config
+ for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
+ {
+ priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
+ GNUNET_CRYPTO_ecdsa_key_get_public (priv_key,
+ &pkey);
+ if ( 0 == memcmp (&pkey, &handle->oidc->client_pkey,
+ sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) )
+ {
+ handle->tld = GNUNET_strdup (tmp_ego->identifier);
+ handle->oidc->is_client_trusted = GNUNET_YES;
+ handle->ego_entry = handle->ego_tail;
+ }
+ }
+
// Checks if client_id is valid:
handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
- // check redirect_uri
- GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id);
- // verify the redirect uri matches https://<client_id>.zkey[/xyz]
- if( 0 != strncmp( expected_redirect_uri, redirect_uri, strlen(expected_redirect_uri)) )
- {
- GNUNET_free_non_null(user_psw);
- handle->emsg=GNUNET_strdup("invalid_request");
- handle->edesc=GNUNET_strdup("Invalid redirect_uri");
- handle->response_code = MHD_HTTP_BAD_REQUEST;
- GNUNET_SCHEDULER_add_now (&do_error, handle);
- GNUNET_free(expected_redirect_uri);
- return;
- }
- GNUNET_free(expected_redirect_uri);
GNUNET_CRYPTO_hash (code, strlen (code), &cache_key);
int i = 1;
if ( GNUNET_SYSERR