GNUnet  0.10.x
Data Structures | Macros | Functions | Variables
plugin_rest_openid_connect.c File Reference
#include "platform.h"
#include <inttypes.h>
#include <jansson.h>
#include "gnunet_gns_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_identity_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_reclaim_attribute_lib.h"
#include "gnunet_reclaim_service.h"
#include "gnunet_rest_lib.h"
#include "gnunet_rest_plugin.h"
#include "gnunet_signatures.h"
#include "microhttpd.h"
#include "oidc_helper.h"
Include dependency graph for plugin_rest_openid_connect.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 
struct  OIDC_Variables
 OIDC needed variables. More...
 
struct  EgoEntry
 The ego list. More...
 
struct  RequestHandle
 The request handle. More...
 

Macros

#define GNUNET_REST_API_NS_OIDC   "/openid"
 REST root namespace. More...
 
#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"
 Authorize endpoint. More...
 
#define GNUNET_REST_API_NS_TOKEN   "/openid/token"
 Token endpoint. More...
 
#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"
 UserInfo endpoint. More...
 
#define GNUNET_REST_API_NS_LOGIN   "/openid/login"
 Login namespace. More...
 
#define ID_REST_STATE_INIT   0
 State while collecting all egos. More...
 
#define ID_REST_STATE_POST_INIT   1
 Done collecting egos. More...
 
#define OIDC_GRANT_TYPE_KEY   "grant_type"
 OIDC grant_type key. More...
 
#define OIDC_GRANT_TYPE_VALUE   "authorization_code"
 OIDC grant_type key. More...
 
#define OIDC_CODE_KEY   "code"
 OIDC code key. More...
 
#define OIDC_RESPONSE_TYPE_KEY   "response_type"
 OIDC response_type key. More...
 
#define OIDC_CLIENT_ID_KEY   "client_id"
 OIDC client_id key. More...
 
#define OIDC_SCOPE_KEY   "scope"
 OIDC scope key. More...
 
#define OIDC_REDIRECT_URI_KEY   "redirect_uri"
 OIDC redirect_uri key. More...
 
#define OIDC_STATE_KEY   "state"
 OIDC state key. More...
 
#define OIDC_NONCE_KEY   "nonce"
 OIDC nonce key. More...
 
#define OIDC_COOKIE_EXPIRATION   3
 OIDC cookie expiration (in seconds) More...
 
#define OIDC_COOKIE_HEADER_KEY   "cookie"
 OIDC cookie header key. More...
 
#define OIDC_AUTHORIZATION_HEADER_KEY   "authorization"
 OIDC cookie header information key. More...
 
#define OIDC_COOKIE_HEADER_INFORMATION_KEY   "Identity="
 OIDC cookie header information key. More...
 
#define OIDC_COOKIE_HEADER_ACCESS_DENIED   "Identity=Denied"
 OIDC cookie header if user cancelled. More...
 
#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE   "code"
 OIDC expected response_type while authorizing. More...
 
#define OIDC_EXPECTED_AUTHORIZATION_SCOPE   "openid"
 OIDC expected scope part while authorizing. More...
 
#define OIDC_ERROR_KEY_INVALID_CLIENT   "invalid_client"
 OIDC error key for invalid client. More...
 
#define OIDC_ERROR_KEY_INVALID_SCOPE   "invalid_scope"
 OIDC error key for invalid scopes. More...
 
#define OIDC_ERROR_KEY_INVALID_REQUEST   "invalid_request"
 OIDC error key for invalid requests. More...
 
#define OIDC_ERROR_KEY_INVALID_TOKEN   "invalid_token"
 OIDC error key for invalid tokens. More...
 
#define OIDC_ERROR_KEY_INVALID_COOKIE   "invalid_cookie"
 OIDC error key for invalid cookies. More...
 
#define OIDC_ERROR_KEY_SERVER_ERROR   "server_error"
 OIDC error key for generic server errors. More...
 
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE   "unsupported_grant_type"
 OIDC error key for unsupported grants. More...
 
#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE   "unsupported_response_type"
 OIDC error key for unsupported response types. More...
 
#define OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT   "unauthorized_client"
 OIDC error key for unauthorized clients. More...
 
#define OIDC_ERROR_KEY_ACCESS_DENIED   "access_denied"
 OIDC error key for denied access. More...
 

Functions

static void cleanup_handle (struct RequestHandle *handle)
 Cleanup lookup handle. More...
 
static void cleanup_handle_delayed (void *cls)
 
static void do_error (void *cls)
 Task run on error, sends error message. More...
 
static void do_userinfo_error (void *cls)
 Task run on error in userinfo endpoint, sends error header. More...
 
static void do_redirect_error (void *cls)
 Task run on error, sends error message and redirects. More...
 
static void do_timeout (void *cls)
 Task run on timeout, sends error message. More...
 
static void return_userinfo_response (void *cls)
 Return attributes for claim. More...
 
static void options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Respond to OPTIONS request. More...
 
static void cookie_identity_interpretation (struct RequestHandle *handle)
 Interprets cookie header and pass its identity keystring to handle. More...
 
static void login_redirect (void *cls)
 Redirects to login page stored in configuration file. More...
 
static void oidc_iteration_error (void *cls)
 Does internal server error when iteration failed. More...
 
static void oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
 Issues ticket and redirects to relying party with the authorization code as parameter. More...
 
static void oidc_collect_finished_cb (void *cls)
 
static void oidc_attr_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
 Collects all attributes for an ego if in scope parameter. More...
 
static void code_redirect (void *cls)
 Checks time and cookie and redirects accordingly. More...
 
static void build_redirect (void *cls)
 
static void lookup_redirect_uri_result (void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 
static void client_redirect (void *cls)
 Initiate redirect back to client. More...
 
static char * get_url_parameter_copy (const struct RequestHandle *handle, const char *key)
 
static void build_authz_response (void *cls)
 Iteration over all results finished, build final response. More...
 
static void tld_iter (void *cls, const char *section, const char *option, const char *value)
 Iterate over tlds in config. More...
 
static void authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Responds to authorization GET and url-encoded POST request. More...
 
static void login_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Combines an identity with a login time and responds OK to login request. More...
 
static int check_authorization (struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
 
const struct EgoEntryfind_ego (struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
 
static void persist_access_token (const struct RequestHandle *handle, const char *access_token, const struct GNUNET_RECLAIM_Ticket *ticket)
 
static void token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Responds to token url-encoded POST request. More...
 
static void consume_ticket (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
 Collects claims and stores them in handle. More...
 
static void userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Responds to userinfo GET and url-encoded POST request. More...
 
static void init_cont (struct RequestHandle *handle)
 Handle rest request. More...
 
static void list_ego (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
 If listing is enabled, prints information about the egos. More...
 
static void rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
 
void * libgnunet_plugin_rest_openid_connect_init (void *cls)
 Entry point for the plugin. More...
 
void * libgnunet_plugin_rest_openid_connect_done (void *cls)
 Exit point from the plugin. More...
 

Variables

static char * OIDC_ignored_parameter_array []
 OIDC ignored parameter array. More...
 
struct GNUNET_CONTAINER_MultiHashMapOIDC_cookie_jar_map
 OIDC Hash map that keeps track of issued cookies. More...
 
struct GNUNET_CONTAINER_MultiHashMapOIDC_access_token_map
 Hash map that links the issued access token to the corresponding ticket and ego. More...
 
const struct GNUNET_CONFIGURATION_Handlecfg
 The configuration handle. More...
 
static char * allow_methods
 HTTP methods allows for this plugin. More...
 

Macro Definition Documentation

◆ GNUNET_REST_API_NS_OIDC

#define GNUNET_REST_API_NS_OIDC   "/openid"

REST root namespace.

Definition at line 45 of file plugin_rest_openid_connect.c.

Referenced by init_cont(), and libgnunet_plugin_rest_openid_connect_init().

◆ GNUNET_REST_API_NS_AUTHORIZE

#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"

Authorize endpoint.

Definition at line 50 of file plugin_rest_openid_connect.c.

Referenced by init_cont().

◆ GNUNET_REST_API_NS_TOKEN

#define GNUNET_REST_API_NS_TOKEN   "/openid/token"

Token endpoint.

Definition at line 55 of file plugin_rest_openid_connect.c.

Referenced by init_cont().

◆ GNUNET_REST_API_NS_USERINFO

#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"

UserInfo endpoint.

Definition at line 60 of file plugin_rest_openid_connect.c.

Referenced by init_cont().

◆ GNUNET_REST_API_NS_LOGIN

#define GNUNET_REST_API_NS_LOGIN   "/openid/login"

Login namespace.

Definition at line 65 of file plugin_rest_openid_connect.c.

Referenced by init_cont().

◆ ID_REST_STATE_INIT

#define ID_REST_STATE_INIT   0

State while collecting all egos.

Definition at line 70 of file plugin_rest_openid_connect.c.

Referenced by list_ego(), and rest_identity_process_request().

◆ ID_REST_STATE_POST_INIT

#define ID_REST_STATE_POST_INIT   1

Done collecting egos.

Definition at line 75 of file plugin_rest_openid_connect.c.

Referenced by list_ego().

◆ OIDC_GRANT_TYPE_KEY

#define OIDC_GRANT_TYPE_KEY   "grant_type"

OIDC grant_type key.

Definition at line 80 of file plugin_rest_openid_connect.c.

Referenced by token_endpoint().

◆ OIDC_GRANT_TYPE_VALUE

#define OIDC_GRANT_TYPE_VALUE   "authorization_code"

OIDC grant_type key.

Definition at line 85 of file plugin_rest_openid_connect.c.

Referenced by token_endpoint().

◆ OIDC_CODE_KEY

#define OIDC_CODE_KEY   "code"

OIDC code key.

Definition at line 90 of file plugin_rest_openid_connect.c.

Referenced by token_endpoint().

◆ OIDC_RESPONSE_TYPE_KEY

#define OIDC_RESPONSE_TYPE_KEY   "response_type"

OIDC response_type key.

Definition at line 95 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and login_redirect().

◆ OIDC_CLIENT_ID_KEY

#define OIDC_CLIENT_ID_KEY   "client_id"

OIDC client_id key.

Definition at line 100 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint(), and login_redirect().

◆ OIDC_SCOPE_KEY

#define OIDC_SCOPE_KEY   "scope"

OIDC scope key.

Definition at line 105 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and login_redirect().

◆ OIDC_REDIRECT_URI_KEY

#define OIDC_REDIRECT_URI_KEY   "redirect_uri"

OIDC redirect_uri key.

Definition at line 110 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and login_redirect().

◆ OIDC_STATE_KEY

#define OIDC_STATE_KEY   "state"

OIDC state key.

Definition at line 115 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint(), and login_redirect().

◆ OIDC_NONCE_KEY

#define OIDC_NONCE_KEY   "nonce"

OIDC nonce key.

Definition at line 120 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and login_redirect().

◆ OIDC_COOKIE_EXPIRATION

#define OIDC_COOKIE_EXPIRATION   3

OIDC cookie expiration (in seconds)

Definition at line 125 of file plugin_rest_openid_connect.c.

Referenced by login_cont().

◆ OIDC_COOKIE_HEADER_KEY

#define OIDC_COOKIE_HEADER_KEY   "cookie"

OIDC cookie header key.

Definition at line 130 of file plugin_rest_openid_connect.c.

Referenced by cookie_identity_interpretation().

◆ OIDC_AUTHORIZATION_HEADER_KEY

#define OIDC_AUTHORIZATION_HEADER_KEY   "authorization"

OIDC cookie header information key.

Definition at line 135 of file plugin_rest_openid_connect.c.

Referenced by check_authorization(), and userinfo_endpoint().

◆ OIDC_COOKIE_HEADER_INFORMATION_KEY

#define OIDC_COOKIE_HEADER_INFORMATION_KEY   "Identity="

OIDC cookie header information key.

Definition at line 140 of file plugin_rest_openid_connect.c.

Referenced by cookie_identity_interpretation().

◆ OIDC_COOKIE_HEADER_ACCESS_DENIED

#define OIDC_COOKIE_HEADER_ACCESS_DENIED   "Identity=Denied"

OIDC cookie header if user cancelled.

Definition at line 145 of file plugin_rest_openid_connect.c.

Referenced by cookie_identity_interpretation().

◆ OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE

#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE   "code"

OIDC expected response_type while authorizing.

Definition at line 150 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response().

◆ OIDC_EXPECTED_AUTHORIZATION_SCOPE

#define OIDC_EXPECTED_AUTHORIZATION_SCOPE   "openid"

OIDC expected scope part while authorizing.

Definition at line 155 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response().

◆ OIDC_ERROR_KEY_INVALID_CLIENT

#define OIDC_ERROR_KEY_INVALID_CLIENT   "invalid_client"

OIDC error key for invalid client.

Definition at line 160 of file plugin_rest_openid_connect.c.

Referenced by check_authorization().

◆ OIDC_ERROR_KEY_INVALID_SCOPE

#define OIDC_ERROR_KEY_INVALID_SCOPE   "invalid_scope"

OIDC error key for invalid scopes.

Definition at line 165 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and oidc_collect_finished_cb().

◆ OIDC_ERROR_KEY_INVALID_REQUEST

#define OIDC_ERROR_KEY_INVALID_REQUEST   "invalid_request"

OIDC error key for invalid requests.

Definition at line 170 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint(), build_authz_response(), and token_endpoint().

◆ OIDC_ERROR_KEY_INVALID_TOKEN

#define OIDC_ERROR_KEY_INVALID_TOKEN   "invalid_token"

OIDC error key for invalid tokens.

Definition at line 175 of file plugin_rest_openid_connect.c.

Referenced by userinfo_endpoint().

◆ OIDC_ERROR_KEY_INVALID_COOKIE

#define OIDC_ERROR_KEY_INVALID_COOKIE   "invalid_cookie"

OIDC error key for invalid cookies.

Definition at line 180 of file plugin_rest_openid_connect.c.

Referenced by code_redirect().

◆ OIDC_ERROR_KEY_SERVER_ERROR

#define OIDC_ERROR_KEY_SERVER_ERROR   "server_error"

◆ OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE

#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE   "unsupported_grant_type"

OIDC error key for unsupported grants.

Definition at line 190 of file plugin_rest_openid_connect.c.

Referenced by token_endpoint().

◆ OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE

#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE   "unsupported_response_type"

OIDC error key for unsupported response types.

Definition at line 195 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response().

◆ OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT

#define OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT   "unauthorized_client"

OIDC error key for unauthorized clients.

Definition at line 200 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint().

◆ OIDC_ERROR_KEY_ACCESS_DENIED

#define OIDC_ERROR_KEY_ACCESS_DENIED   "access_denied"

OIDC error key for denied access.

Definition at line 205 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response().

Function Documentation

◆ cleanup_handle()

static void cleanup_handle ( struct RequestHandle handle)
static

Cleanup lookup handle.

Parameters
handleHandle to clean up

Definition at line 494 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_it, RequestHandle::attr_list, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::claim, OIDC_Variables::client_id, RequestHandle::edesc, RequestHandle::ego_head, RequestHandle::emsg, RequestHandle::gns_handle, RequestHandle::gns_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_free_non_null, GNUNET_GNS_disconnect(), GNUNET_GNS_lookup_cancel(), GNUNET_IDENTITY_disconnect(), GNUNET_log, GNUNET_NAMESTORE_disconnect(), GNUNET_RECLAIM_disconnect(), GNUNET_RECLAIM_get_attributes_stop(), GNUNET_RECLAIM_ticket_iteration_stop(), GNUNET_SCHEDULER_cancel(), EgoEntry::identifier, RequestHandle::identity_handle, RequestHandle::idp, EgoEntry::keystring, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_head, OIDC_Variables::login_identity, RequestHandle::namestore_handle, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::next, EgoEntry::next, OIDC_Variables::nonce, RequestHandle::oidc, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, OIDC_Variables::redirect_uri, OIDC_Variables::response, OIDC_Variables::response_type, OIDC_Variables::scope, OIDC_Variables::state, RequestHandle::ticket_it, RequestHandle::timeout_task, RequestHandle::tld, and RequestHandle::url.

Referenced by cleanup_handle_delayed(), options_cont(), and return_userinfo_response().

495 {
496  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
497  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
498  struct EgoEntry *ego_entry;
499  struct EgoEntry *ego_tmp;
500  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
501  if (NULL != handle->timeout_task)
503  if (NULL != handle->identity_handle)
505  if (NULL != handle->attr_it)
507  if (NULL != handle->ticket_it)
509  if (NULL != handle->idp)
510  GNUNET_RECLAIM_disconnect (handle->idp);
511  GNUNET_free_non_null (handle->url);
512  GNUNET_free_non_null (handle->tld);
515  GNUNET_free_non_null (handle->emsg);
516  GNUNET_free_non_null (handle->edesc);
517  if (NULL != handle->gns_op)
519  if (NULL != handle->gns_handle)
521 
522  if (NULL != handle->namestore_handle)
524  if (NULL != handle->oidc)
525  {
528  GNUNET_free_non_null (handle->oidc->nonce);
531  GNUNET_free_non_null (handle->oidc->scope);
532  GNUNET_free_non_null (handle->oidc->state);
533  json_decref (handle->oidc->response);
534  GNUNET_free (handle->oidc);
535  }
536  if (NULL != handle->attr_list)
537  {
538  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
539  {
540  claim_tmp = claim_entry;
541  claim_entry = claim_entry->next;
542  GNUNET_free (claim_tmp->claim);
543  GNUNET_free (claim_tmp);
544  }
545  GNUNET_free (handle->attr_list);
546  }
547  for (ego_entry = handle->ego_head; NULL != ego_entry;)
548  {
549  ego_tmp = ego_entry;
550  ego_entry = ego_entry->next;
551  GNUNET_free (ego_tmp->identifier);
552  GNUNET_free (ego_tmp->keystring);
553  GNUNET_free (ego_tmp);
554  }
555  GNUNET_free (handle);
556 }
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * claim
The attribute claim.
char * redirect_uri
The OIDC redirect uri.
char * scope
The list of oidc scopes.
char * nonce
The OIDC nonce.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
void GNUNET_RECLAIM_disconnect(struct GNUNET_RECLAIM_Handle *h)
Disconnect from identity provider service.
Definition: reclaim_api.c:819
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1207
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The ego list.
char * response_type
The OIDC response type.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:285
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
char * tld
The tld for redirect.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:838
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
char * state
The OIDC state.
char * identifier
Ego Identifier.
char * redirect_prefix
The redirect prefix.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
struct EgoEntry * ego_head
Ego list.
void GNUNET_RECLAIM_get_attributes_stop(struct GNUNET_RECLAIM_AttributeIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1020
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
char * redirect_suffix
The redirect suffix.
#define GNUNET_log(kind,...)
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:309
json_t * response
The response JSON.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * next
DLL.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NAMESTORE_Handle * namestore_handle
Handle to NAMESTORE.
char * login_identity
The identity chosen by the user to login.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
char * url
The url.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_handle_delayed()

static void cleanup_handle_delayed ( void *  cls)
static

Definition at line 559 of file plugin_rest_openid_connect.c.

References cleanup_handle().

Referenced by build_redirect(), do_error(), do_redirect_error(), do_userinfo_error(), login_cont(), login_redirect(), oidc_ticket_issue_cb(), and token_endpoint().

560 {
561  cleanup_handle (cls);
562 }
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_error()

static void do_error ( void *  cls)
static

Task run on error, sends error message.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 571 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), handle, RequestHandle::oidc, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::response_code, and OIDC_Variables::state.

Referenced by authorize_endpoint(), build_authz_response(), do_timeout(), init_cont(), login_redirect(), oidc_iteration_error(), and token_endpoint().

572 {
573  struct RequestHandle *handle = cls;
574  struct MHD_Response *resp;
575  char *json_error;
576 
577  GNUNET_asprintf (&json_error,
578  "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
579  handle->emsg,
580  (NULL != handle->edesc) ? handle->edesc : "",
581  (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
582  (NULL != handle->oidc->state) ? handle->oidc->state : "",
583  (NULL != handle->oidc->state) ? "\"" : "");
584  if (0 == handle->response_code)
585  handle->response_code = MHD_HTTP_BAD_REQUEST;
586  resp = GNUNET_REST_create_response (json_error);
587  if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
588  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
589  MHD_add_response_header (resp,
590  MHD_HTTP_HEADER_CONTENT_TYPE,
591  "application/json");
592  handle->proc (handle->proc_cls, resp, handle->response_code);
594  GNUNET_free (json_error);
595 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_userinfo_error()

static void do_userinfo_error ( void *  cls)
static

Task run on error in userinfo endpoint, sends error header.

Cleans up everything

Parameters
clsthe struct RequestHandle

Definition at line 605 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), handle, RequestHandle::proc, RequestHandle::proc_cls, and RequestHandle::response_code.

Referenced by userinfo_endpoint().

606 {
607  struct RequestHandle *handle = cls;
608  struct MHD_Response *resp;
609  char *error;
610 
611  GNUNET_asprintf (&error,
612  "error=\"%s\", error_description=\"%s\"",
613  handle->emsg,
614  (NULL != handle->edesc) ? handle->edesc : "");
615  resp = GNUNET_REST_create_response ("");
616  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
617  handle->proc (handle->proc_cls, resp, handle->response_code);
619  GNUNET_free (error);
620 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_redirect_error()

static void do_redirect_error ( void *  cls)
static

Task run on error, sends error message and redirects.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 629 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), handle, RequestHandle::oidc, RequestHandle::proc, RequestHandle::proc_cls, OIDC_Variables::redirect_uri, and OIDC_Variables::state.

Referenced by build_authz_response(), code_redirect(), lookup_redirect_uri_result(), oidc_collect_finished_cb(), and oidc_ticket_issue_cb().

630 {
631  struct RequestHandle *handle = cls;
632  struct MHD_Response *resp;
633  char *redirect;
634  GNUNET_asprintf (&redirect,
635  "%s?error=%s&error_description=%s%s%s",
636  handle->oidc->redirect_uri,
637  handle->emsg,
638  handle->edesc,
639  (NULL != handle->oidc->state) ? "&state=" : "",
640  (NULL != handle->oidc->state) ? handle->oidc->state : "");
641  resp = GNUNET_REST_create_response ("");
642  MHD_add_response_header (resp, "Location", redirect);
643  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
645  GNUNET_free (redirect);
646 }
char * redirect_uri
The OIDC redirect uri.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_timeout()

static void do_timeout ( void *  cls)
static

Task run on timeout, sends error message.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 654 of file plugin_rest_openid_connect.c.

References do_error(), handle, and RequestHandle::timeout_task.

Referenced by rest_identity_process_request().

655 {
656  struct RequestHandle *handle = cls;
657 
658  handle->timeout_task = NULL;
659  do_error (handle);
660 }
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void do_error(void *cls)
Task run on error, sends error message.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ return_userinfo_response()

static void return_userinfo_response ( void *  cls)
static

Return attributes for claim.

Parameters
clsthe request handle

Definition at line 668 of file plugin_rest_openid_connect.c.

References cleanup_handle(), GNUNET_free, GNUNET_REST_create_response(), handle, RequestHandle::oidc, RequestHandle::proc, RequestHandle::proc_cls, and OIDC_Variables::response.

Referenced by consume_ticket().

669 {
670  char *result_str;
671  struct RequestHandle *handle = cls;
672  struct MHD_Response *resp;
673 
674  result_str = json_dumps (handle->oidc->response, 0);
675 
676  resp = GNUNET_REST_create_response (result_str);
677  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
678  GNUNET_free (result_str);
679  cleanup_handle (handle);
680 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
json_t * response
The response JSON.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ options_cont()

static void options_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Respond to OPTIONS request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 691 of file plugin_rest_openid_connect.c.

References allow_methods, cleanup_handle(), GNUNET_REST_create_response(), handle, RequestHandle::proc, and RequestHandle::proc_cls.

Referenced by init_cont().

694 {
695  struct MHD_Response *resp;
696  struct RequestHandle *handle = cls;
697 
698  // For now, independent of path return all options
699  resp = GNUNET_REST_create_response (NULL);
700  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
701  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
702  cleanup_handle (handle);
703  return;
704 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
static char * allow_methods
HTTP methods allows for this plugin.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cookie_identity_interpretation()

static void cookie_identity_interpretation ( struct RequestHandle handle)
static

Interprets cookie header and pass its identity keystring to handle.

Definition at line 711 of file plugin_rest_openid_connect.c.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_strdup, GNUNET_TIME_absolute_get(), GNUNET_YES, GNUNET_REST_RequestHandle::header_param_map, OIDC_Variables::login_identity, RequestHandle::oidc, OIDC_COOKIE_HEADER_ACCESS_DENIED, OIDC_COOKIE_HEADER_INFORMATION_KEY, OIDC_COOKIE_HEADER_KEY, RequestHandle::rest_handle, OIDC_Variables::user_cancelled, and value.

Referenced by authorize_endpoint().

712 {
713  struct GNUNET_HashCode cache_key;
714  char *cookies;
715  struct GNUNET_TIME_Absolute current_time, *relog_time;
716  char delimiter[] = "; ";
717  char *tmp_cookies;
718  char *token;
719  char *value;
720 
721  // gets identity of login try with cookie
723  strlen (OIDC_COOKIE_HEADER_KEY),
724  &cache_key);
727  &cache_key))
728  {
729  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
730  return;
731  }
732  // splits cookies and find 'Identity' cookie
733  tmp_cookies =
735  &cache_key);
736  cookies = GNUNET_strdup (tmp_cookies);
737  token = strtok (cookies, delimiter);
738  handle->oidc->user_cancelled = GNUNET_NO;
739  handle->oidc->login_identity = NULL;
740  if (NULL == token)
741  {
743  "Unable to parse cookie: %s\n",
744  cookies);
745  GNUNET_free (cookies);
746  return;
747  }
748 
749  while (NULL != token)
750  {
751  if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
752  {
753  handle->oidc->user_cancelled = GNUNET_YES;
754  GNUNET_free (cookies);
755  return;
756  }
757  if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
758  break;
759  token = strtok (NULL, delimiter);
760  }
761  if (NULL == token)
762  {
764  "No cookie value to process: %s\n",
765  cookies);
766  GNUNET_free (cookies);
767  return;
768  }
769  GNUNET_CRYPTO_hash (token, strlen (token), &cache_key);
770  if (GNUNET_NO ==
772  {
773  GNUNET_log (
775  "Found cookie `%s', but no corresponding expiration entry present...\n",
776  token);
777  GNUNET_free (cookies);
778  return;
779  }
780  relog_time =
782  current_time = GNUNET_TIME_absolute_get ();
783  // 30 min after old login -> redirect to login
784  if (current_time.abs_value_us > relog_time->abs_value_us)
785  {
787  "Found cookie `%s', but it is expired.\n",
788  token);
789  GNUNET_free (cookies);
790  return;
791  }
792  value = strtok (token, OIDC_COOKIE_HEADER_INFORMATION_KEY);
793  GNUNET_assert (NULL != value);
794  handle->oidc->login_identity = GNUNET_strdup (value);
795  GNUNET_free (cookies);
796 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define OIDC_COOKIE_HEADER_INFORMATION_KEY
OIDC cookie header information key.
#define OIDC_COOKIE_HEADER_ACCESS_DENIED
OIDC cookie header if user cancelled.
int user_cancelled
User cancelled authorization/login.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint64_t abs_value_us
The actual value.
struct OIDC_Variables * oidc
OIDC variables.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
#define OIDC_COOKIE_HEADER_KEY
OIDC cookie header key.
#define GNUNET_free(ptr)
Wrapper around free.
char * login_identity
The identity chosen by the user to login.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ login_redirect()

static void login_redirect ( void *  cls)
static

Redirects to login page stored in configuration file.

Definition at line 802 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), OIDC_Variables::client_id, do_error(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_free, GNUNET_OK, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, OIDC_Variables::nonce, RequestHandle::oidc, OIDC_CLIENT_ID_KEY, OIDC_ERROR_KEY_SERVER_ERROR, OIDC_NONCE_KEY, OIDC_REDIRECT_URI_KEY, OIDC_RESPONSE_TYPE_KEY, OIDC_SCOPE_KEY, OIDC_STATE_KEY, RequestHandle::proc, RequestHandle::proc_cls, OIDC_Variables::redirect_uri, RequestHandle::response_code, OIDC_Variables::response_type, OIDC_Variables::scope, and OIDC_Variables::state.

Referenced by build_authz_response(), and code_redirect().

803 {
804  char *login_base_url;
805  char *new_redirect;
806  struct MHD_Response *resp;
807  struct RequestHandle *handle = cls;
808 
810  "reclaim-rest-plugin",
811  "address",
812  &login_base_url))
813  {
814  GNUNET_asprintf (&new_redirect,
815  "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
816  login_base_url,
818  handle->oidc->response_type,
820  handle->oidc->client_id,
822  handle->oidc->redirect_uri,
824  handle->oidc->scope,
826  (NULL != handle->oidc->state) ? handle->oidc->state : "",
828  (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
829  resp = GNUNET_REST_create_response ("");
830  MHD_add_response_header (resp, "Location", new_redirect);
831  GNUNET_free (login_base_url);
832  }
833  else
834  {
836  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
837  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
839  return;
840  }
841  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
842  GNUNET_free (new_redirect);
844 }
char * redirect_uri
The OIDC redirect uri.
char * scope
The list of oidc scopes.
#define OIDC_NONCE_KEY
OIDC nonce key.
char * nonce
The OIDC nonce.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define OIDC_REDIRECT_URI_KEY
OIDC redirect_uri key.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
#define OIDC_STATE_KEY
OIDC state key.
The request handle.
char * response_type
The OIDC response type.
#define OIDC_RESPONSE_TYPE_KEY
OIDC response_type key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * state
The OIDC state.
static void do_error(void *cls)
Task run on error, sends error message.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_SCOPE_KEY
OIDC scope key.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_iteration_error()

static void oidc_iteration_error ( void *  cls)
static

Does internal server error when iteration failed.

Definition at line 850 of file plugin_rest_openid_connect.c.

References do_error(), RequestHandle::emsg, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, OIDC_ERROR_KEY_SERVER_ERROR, and RequestHandle::response_code.

Referenced by code_redirect().

851 {
852  struct RequestHandle *handle = cls;
854  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
856 }
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
The request handle.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
static void do_error(void *cls)
Task run on error, sends error message.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_ticket_issue_cb()

static void oidc_ticket_issue_cb ( void *  cls,
const struct GNUNET_RECLAIM_Ticket ticket 
)
static

Issues ticket and redirects to relying party with the authorization code as parameter.

Otherwise redirects with error

Definition at line 864 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_list, cleanup_handle_delayed(), do_redirect_error(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_STRINGS_data_to_string_alloc(), handle, RequestHandle::idp_op, OIDC_Variables::nonce, RequestHandle::oidc, OIDC_build_authz_code(), OIDC_ERROR_KEY_SERVER_ERROR, RequestHandle::priv_key, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, OIDC_Variables::redirect_uri, OIDC_Variables::response_type, OIDC_Variables::state, ticket, RequestHandle::ticket, and RequestHandle::tld.

Referenced by oidc_collect_finished_cb().

865 {
866  struct RequestHandle *handle = cls;
867  struct MHD_Response *resp;
868  char *ticket_str;
869  char *redirect_uri;
870  char *code_string;
871 
872  handle->idp_op = NULL;
873  if (NULL == ticket)
874  {
876  handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
878  return;
879  }
880  handle->ticket = *ticket;
881  ticket_str =
883  sizeof (struct GNUNET_RECLAIM_Ticket));
884  // TODO change if more attributes are needed (see max_age)
885  code_string = OIDC_build_authz_code (&handle->priv_key,
886  &handle->ticket,
887  handle->attr_list,
888  handle->oidc->nonce);
889  if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
890  (NULL != handle->tld))
891  {
892 
893  GNUNET_asprintf (&redirect_uri,
894  "%s.%s/%s?%s=%s&state=%s",
895  handle->redirect_prefix,
896  handle->tld,
897  handle->redirect_suffix,
898  handle->oidc->response_type,
899  code_string,
900  handle->oidc->state);
901  }
902  else
903  {
904  GNUNET_asprintf (&redirect_uri,
905  "%s?%s=%s&state=%s",
906  handle->oidc->redirect_uri,
907  handle->oidc->response_type,
908  code_string,
909  handle->oidc->state);
910  }
911  resp = GNUNET_REST_create_response ("");
912  MHD_add_response_header (resp, "Location", redirect_uri);
913  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
915  GNUNET_free (redirect_uri);
916  GNUNET_free (ticket_str);
917  GNUNET_free (code_string);
918 }
char * redirect_uri
The OIDC redirect uri.
The authorization ticket.
char * nonce
The OIDC nonce.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * response_type
The OIDC response type.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const char *nonce_str)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:386
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
char * redirect_prefix
The redirect prefix.
struct GNUNET_RECLAIM_Ticket ticket
A ticket.
char * redirect_suffix
The redirect suffix.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:988
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key
Pointer to ego private key.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_collect_finished_cb()

static void oidc_collect_finished_cb ( void *  cls)
static

Definition at line 921 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_it, RequestHandle::attr_list, OIDC_Variables::client_pkey, do_redirect_error(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_RECLAIM_ticket_issue(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, RequestHandle::idp, RequestHandle::idp_op, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_head, RequestHandle::oidc, OIDC_ERROR_KEY_INVALID_SCOPE, oidc_ticket_issue_cb(), RequestHandle::priv_key, and RequestHandle::ticket_it.

Referenced by code_redirect().

922 {
923  struct RequestHandle *handle = cls;
924  handle->attr_it = NULL;
925  handle->ticket_it = NULL;
926  if (NULL == handle->attr_list->list_head)
927  {
929  handle->edesc = GNUNET_strdup ("The requested scope is not available.");
931  return;
932  }
933  handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
934  &handle->priv_key,
935  &handle->oidc->client_pkey,
936  handle->attr_list,
938  handle);
939 }
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
static void oidc_ticket_issue_cb(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
Issues ticket and redirects to relying party with the authorization code as parameter.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, GNUNET_RECLAIM_TicketCallback cb, void *cb_cls)
Issues a ticket to a relying party.
Definition: reclaim_api.c:1051
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
#define OIDC_ERROR_KEY_INVALID_SCOPE
OIDC error key for invalid scopes.
struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key
Pointer to ego private key.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_attr_collect()

static void oidc_attr_collect ( void *  cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey identity,
const struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr 
)
static

Collects all attributes for an ego if in scope parameter.

Definition at line 946 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_it, RequestHandle::attr_list, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::claim, GNUNET_RECLAIM_ATTRIBUTE_Claim::data, GNUNET_RECLAIM_ATTRIBUTE_Claim::data_size, GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_new, GNUNET_RECLAIM_ATTRIBUTE_claim_new(), GNUNET_RECLAIM_get_attributes_next(), GNUNET_strdup, handle, GNUNET_RECLAIM_ATTRIBUTE_Claim::id, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_head, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_tail, GNUNET_RECLAIM_ATTRIBUTE_Claim::name, RequestHandle::oidc, OIDC_Variables::scope, GNUNET_RECLAIM_ATTRIBUTE_Claim::type, and GNUNET_RECLAIM_ATTRIBUTE_Claim::version.

Referenced by code_redirect().

949 {
950  struct RequestHandle *handle = cls;
952  char *scope_variables;
953  char *scope_variable;
954  char delimiter[] = " ";
955 
956  if ((NULL == attr->name) || (NULL == attr->data))
957  {
959  return;
960  }
961 
962  scope_variables = GNUNET_strdup (handle->oidc->scope);
963  scope_variable = strtok (scope_variables, delimiter);
964  while (NULL != scope_variable)
965  {
966  if (0 == strcmp (attr->name, scope_variable))
967  break;
968  scope_variable = strtok (NULL, delimiter);
969  }
970  if (NULL == scope_variable)
971  {
973  GNUNET_free (scope_variables);
974  return;
975  }
976  GNUNET_free (scope_variables);
977 
980  attr->type,
981  attr->data,
982  attr->data_size);
983  le->claim->id = attr->id;
984  le->claim->version = attr->version;
986  handle->attr_list->list_tail,
987  le);
989 }
const char * name
The name of the attribute.
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * claim
The attribute claim.
char * scope
The list of oidc scopes.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_tail
List tail.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_RECLAIM_get_attributes_next(struct GNUNET_RECLAIM_AttributeIterator *it)
Calls the record processor specified in GNUNET_RECLAIM_get_attributes_start for the next record...
Definition: reclaim_api.c:999
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
const void * data
Binary value stored as attribute value.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * GNUNET_RECLAIM_ATTRIBUTE_claim_new(const char *attr_name, uint32_t type, const void *data, size_t data_size)
Create a new attribute claim.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ code_redirect()

static void code_redirect ( void *  cls)
static

Checks time and cookie and redirects accordingly.

Definition at line 996 of file plugin_rest_openid_connect.c.

References GNUNET_TIME_Absolute::abs_value_us, RequestHandle::attr_it, RequestHandle::attr_list, do_redirect_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::ego_entry, RequestHandle::ego_head, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_ecdsa_public_key_from_string(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_IDENTITY_ego_get_public_key(), GNUNET_memcmp, GNUNET_new, GNUNET_OK, GNUNET_RECLAIM_connect(), GNUNET_RECLAIM_get_attributes_start(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_TIME_absolute_get(), GNUNET_YES, handle, RequestHandle::idp, OIDC_Variables::login_identity, login_redirect(), EgoEntry::next, RequestHandle::oidc, oidc_attr_collect(), oidc_collect_finished_cb(), OIDC_ERROR_KEY_INVALID_COOKIE, oidc_iteration_error(), and RequestHandle::priv_key.

Referenced by build_redirect().

997 {
998  struct RequestHandle *handle = cls;
999  struct GNUNET_TIME_Absolute current_time;
1000  struct GNUNET_TIME_Absolute *relog_time;
1002  struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey;
1003  struct GNUNET_HashCode cache_key;
1004  char *identity_cookie;
1005 
1006  GNUNET_asprintf (&identity_cookie,
1007  "Identity=%s",
1008  handle->oidc->login_identity);
1009  GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1010  GNUNET_free (identity_cookie);
1011  // No login time for identity -> redirect to login
1012  if (GNUNET_YES ==
1014  {
1015  relog_time =
1017  current_time = GNUNET_TIME_absolute_get ();
1018  // 30 min after old login -> redirect to login
1019  if (current_time.abs_value_us <= relog_time->abs_value_us)
1020  {
1021  if (GNUNET_OK !=
1023  ->login_identity,
1024  strlen (
1025  handle->oidc
1026  ->login_identity),
1027  &pubkey))
1028  {
1030  handle->edesc =
1031  GNUNET_strdup ("The cookie of a login identity is not valid");
1033  return;
1034  }
1035  // iterate over egos and compare their public key
1036  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1037  handle->ego_entry = handle->ego_entry->next)
1038  {
1039  GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1040  if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1041  {
1042  handle->priv_key =
1044  handle->idp = GNUNET_RECLAIM_connect (cfg);
1045  handle->attr_list =
1047  handle->attr_it =
1049  &handle->priv_key,
1051  handle,
1053  handle,
1055  handle);
1056  return;
1057  }
1058  }
1060  return;
1061  }
1062  }
1063 }
struct GNUNET_RECLAIM_AttributeIterator * GNUNET_RECLAIM_get_attributes_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_AttributeResult proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
List all attributes for a local identity.
Definition: reclaim_api.c:953
static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey
Public key of the zone to look in.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void login_redirect(void *cls)
Redirects to login page stored in configuration file.
uint64_t abs_value_us
The actual value.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
#define OIDC_ERROR_KEY_INVALID_COOKIE
OIDC error key for invalid cookies.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
static void oidc_attr_collect(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
Collects all attributes for an ego if in scope parameter.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:569
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
static void oidc_collect_finished_cb(void *cls)
struct EgoEntry * ego_entry
IDENTITY Operation.
static void oidc_iteration_error(void *cls)
Does internal server error when iteration failed.
struct GNUNET_RECLAIM_Handle * GNUNET_RECLAIM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the re:claimID service.
Definition: reclaim_api.c:779
struct EgoEntry * next
DLL.
#define GNUNET_free(ptr)
Wrapper around free.
char * login_identity
The identity chosen by the user to login.
struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key
Pointer to ego private key.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_redirect()

static void build_redirect ( void *  cls)
static

Definition at line 1067 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), code_redirect(), GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_YES, handle, RequestHandle::oidc, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, OIDC_Variables::redirect_uri, OIDC_Variables::state, RequestHandle::tld, and OIDC_Variables::user_cancelled.

Referenced by lookup_redirect_uri_result().

1068 {
1069  struct RequestHandle *handle = cls;
1070  struct MHD_Response *resp;
1071  char *redirect_uri;
1072 
1073  if (GNUNET_YES == handle->oidc->user_cancelled)
1074  {
1075  if ((NULL != handle->redirect_prefix) &&
1076  (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1077  {
1078  GNUNET_asprintf (&redirect_uri,
1079  "%s.%s/%s?error=%s&error_description=%s&state=%s",
1080  handle->redirect_prefix,
1081  handle->tld,
1082  handle->redirect_suffix,
1083  "access_denied",
1084  "User denied access",
1085  handle->oidc->state);
1086  }
1087  else
1088  {
1089  GNUNET_asprintf (&redirect_uri,
1090  "%s?error=%s&error_description=%s&state=%s",
1091  handle->oidc->redirect_uri,
1092  "access_denied",
1093  "User denied access",
1094  handle->oidc->state);
1095  }
1096  resp = GNUNET_REST_create_response ("");
1097  MHD_add_response_header (resp, "Location", redirect_uri);
1098  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1100  GNUNET_free (redirect_uri);
1101  return;
1102  }
1104 }
char * redirect_uri
The OIDC redirect uri.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
int user_cancelled
User cancelled authorization/login.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void code_redirect(void *cls)
Checks time and cookie and redirects accordingly.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ lookup_redirect_uri_result()

static void lookup_redirect_uri_result ( void *  cls,
uint32_t  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Definition at line 1108 of file plugin_rest_openid_connect.c.

References build_redirect(), OIDC_Variables::client_id, data, data_size, GNUNET_GNSRECORD_Data::data_size, do_redirect_error(), RequestHandle::edesc, RequestHandle::emsg, RequestHandle::gns_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, GNUNET_log, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_strndup, handle, RequestHandle::oidc, OIDC_ERROR_KEY_SERVER_ERROR, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, and OIDC_Variables::redirect_uri.

Referenced by client_redirect().

1111 {
1112  struct RequestHandle *handle = cls;
1113  char *tmp;
1114  char *tmp_key_str;
1115  char *pos;
1116  struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1117 
1118  handle->gns_op = NULL;
1119  if (0 == rd_count)
1120  {
1122  handle->edesc =
1123  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1125  return;
1126  }
1127  for (int i = 0; i < rd_count; i++)
1128  {
1129  if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1130  continue;
1131  if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1132  continue;
1133  tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1134  if (NULL == strstr (tmp, handle->oidc->client_id))
1135  {
1137  "Redirect uri %s does not contain client_id %s\n",
1138  tmp,
1139  handle->oidc->client_id);
1140  }
1141  else
1142  {
1143  pos = strrchr (tmp, (unsigned char) '.');
1144  if (NULL == pos)
1145  {
1147  "Redirect uri %s contains client_id but is malformed\n",
1148  tmp);
1149  GNUNET_free (tmp);
1150  continue;
1151  }
1152  *pos = '\0';
1153  handle->redirect_prefix = GNUNET_strdup (tmp);
1154  tmp_key_str = pos + 1;
1155  pos = strchr (tmp_key_str, (unsigned char) '/');
1156  if (NULL == pos)
1157  {
1159  "Redirect uri %s contains client_id but is malformed\n",
1160  tmp);
1161  GNUNET_free (tmp);
1162  continue;
1163  }
1164  *pos = '\0';
1165  handle->redirect_suffix = GNUNET_strdup (pos + 1);
1166 
1167  GNUNET_STRINGS_string_to_data (tmp_key_str,
1168  strlen (tmp_key_str),
1169  &redirect_zone,
1170  sizeof (redirect_zone));
1171  }
1173  GNUNET_free (tmp);
1174  return;
1175  }
1177  handle->edesc =
1178  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1180 }
static void build_redirect(void *cls)
char * redirect_uri
The OIDC redirect uri.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
size_t data_size
Number of bytes in data.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Record type for reclaim OIDC redirect URIs.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
#define GNUNET_free(ptr)
Wrapper around free.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_redirect()

static void client_redirect ( void *  cls)
static

Initiate redirect back to client.

Definition at line 1187 of file plugin_rest_openid_connect.c.

References OIDC_Variables::client_pkey, RequestHandle::gns_handle, RequestHandle::gns_op, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNS_LO_DEFAULT, GNUNET_GNS_lookup(), GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, handle, lookup_redirect_uri_result(), and RequestHandle::oidc.

Referenced by build_authz_response().

1188 {
1189  struct RequestHandle *handle = cls;
1190 
1191  /* Lookup client redirect uri to verify request */
1192  handle->gns_op =
1193  GNUNET_GNS_lookup (handle->gns_handle,
1195  &handle->oidc->client_pkey,
1199  handle);
1200 }
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
static void lookup_redirect_uri_result(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Record type for reclaim OIDC redirect URIs.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
Defaults, look in cache, then in DHT.
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:337
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_url_parameter_copy()

static char* get_url_parameter_copy ( const struct RequestHandle handle,
const char *  key 
)
static

Definition at line 1203 of file plugin_rest_openid_connect.c.

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_strdup, GNUNET_YES, RequestHandle::rest_handle, GNUNET_REST_RequestHandle::url_param_map, and value.

Referenced by authorize_endpoint(), build_authz_response(), and token_endpoint().

1204 {
1205  struct GNUNET_HashCode hc;
1206  char *value;
1207  GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1209  ->url_param_map,
1210  &hc))
1211  return NULL;
1212  value =
1214  if (NULL == value)
1215  return NULL;
1216  return GNUNET_strdup (value);
1217 }
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static char * value
Value of the record to add/remove.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_YES
Definition: gnunet_common.h:80
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_authz_response()

static void build_authz_response ( void *  cls)
static

Iteration over all results finished, build final response.

Parameters
clsthe struct RequestHandle

Definition at line 1227 of file plugin_rest_openid_connect.c.

References client_redirect(), do_error(), do_redirect_error(), RequestHandle::edesc, RequestHandle::emsg, get_url_parameter_copy(), GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_YES, handle, iterator(), OIDC_Variables::login_identity, login_redirect(), OIDC_Variables::nonce, RequestHandle::oidc, OIDC_ERROR_KEY_ACCESS_DENIED, OIDC_ERROR_KEY_INVALID_REQUEST, OIDC_ERROR_KEY_INVALID_SCOPE, OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE, OIDC_EXPECTED_AUTHORIZATION_SCOPE, OIDC_ignored_parameter_array, OIDC_NONCE_KEY, OIDC_REDIRECT_URI_KEY, OIDC_RESPONSE_TYPE_KEY, OIDC_SCOPE_KEY, OIDC_Variables::redirect_uri, OIDC_Variables::response_type, RequestHandle::rest_handle, OIDC_Variables::scope, GNUNET_REST_RequestHandle::url_param_map, and OIDC_Variables::user_cancelled.

Referenced by authorize_endpoint().

1228 {
1229  struct RequestHandle *handle = cls;
1230  struct GNUNET_HashCode cache_key;
1231 
1232  char *expected_scope;
1233  char delimiter[] = " ";
1234  int number_of_ignored_parameter, iterator;
1235 
1236 
1237  // REQUIRED value: redirect_uri
1238  handle->oidc->redirect_uri =
1240  if (NULL == handle->oidc->redirect_uri)
1241  {
1243  handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1245  return;
1246  }
1247 
1248  // REQUIRED value: response_type
1249  handle->oidc->response_type =
1251  if (NULL == handle->oidc->response_type)
1252  {
1254  handle->edesc = GNUNET_strdup ("missing parameter response_type");
1256  return;
1257  }
1258 
1259  // REQUIRED value: scope
1260  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1261  if (NULL == handle->oidc->scope)
1262  {
1264  handle->edesc = GNUNET_strdup ("missing parameter scope");
1266  return;
1267  }
1268 
1269  // OPTIONAL value: nonce
1270  handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
1271 
1272  // TODO check other values if needed
1273  number_of_ignored_parameter =
1274  sizeof (OIDC_ignored_parameter_array) / sizeof (char *);
1275  for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1276  {
1278  strlen (OIDC_ignored_parameter_array[iterator]),
1279  &cache_key);
1280  if (GNUNET_YES ==
1282  ->url_param_map,
1283  &cache_key))
1284  {
1286  GNUNET_asprintf (&handle->edesc,
1287  "Server will not handle parameter: %s",
1288  OIDC_ignored_parameter_array[iterator]);
1290  return;
1291  }
1292  }
1293 
1294  // We only support authorization code flows.
1295  if (0 != strcmp (handle->oidc->response_type,
1297  {
1299  handle->edesc = GNUNET_strdup ("The authorization server does not support "
1300  "obtaining this authorization code.");
1302  return;
1303  }
1304 
1305  // Checks if scope contains 'openid'
1306  expected_scope = GNUNET_strdup (handle->oidc->scope);
1307  char *test;
1308  test = strtok (expected_scope, delimiter);
1309  while (NULL != test)
1310  {
1311  if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1312  break;
1313  test = strtok (NULL, delimiter);
1314  }
1315  if (NULL == test)
1316  {
1318  handle->edesc =
1319  GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1321  GNUNET_free (expected_scope);
1322  return;
1323  }
1324 
1325  GNUNET_free (expected_scope);
1326  if ((NULL == handle->oidc->login_identity) &&
1327  (GNUNET_NO == handle->oidc->user_cancelled))
1329  else
1331 }
static int iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
char * redirect_uri
The OIDC redirect uri.
char * scope
The list of oidc scopes.
#define OIDC_NONCE_KEY
OIDC nonce key.
char * nonce
The OIDC nonce.
#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE
OIDC expected response_type while authorizing.
#define OIDC_REDIRECT_URI_KEY
OIDC redirect_uri key.
#define GNUNET_NO
Definition: gnunet_common.h:81
int user_cancelled
User cancelled authorization/login.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void login_redirect(void *cls)
Redirects to login page stored in configuration file.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * response_type
The OIDC response type.
#define OIDC_RESPONSE_TYPE_KEY
OIDC response_type key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE
OIDC error key for unsupported response types.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
#define OIDC_ERROR_KEY_ACCESS_DENIED
OIDC error key for denied access.
#define OIDC_EXPECTED_AUTHORIZATION_SCOPE
OIDC expected scope part while authorizing.
static char * OIDC_ignored_parameter_array[]
OIDC ignored parameter array.
static void client_redirect(void *cls)
Initiate redirect back to client.
static void do_error(void *cls)
Task run on error, sends error message.
#define OIDC_SCOPE_KEY
OIDC scope key.
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_free(ptr)
Wrapper around free.
#define OIDC_ERROR_KEY_INVALID_SCOPE
OIDC error key for invalid scopes.
char * login_identity
The identity chosen by the user to login.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tld_iter()

static void tld_iter ( void *  cls,
const char *  section,
const char *  option,
const char *  value 
)
static

Iterate over tlds in config.

Definition at line 1337 of file plugin_rest_openid_connect.c.

References OIDC_Variables::client_pkey, GNUNET_CRYPTO_ecdsa_public_key_from_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_strdup, handle, RequestHandle::oidc, and RequestHandle::tld.

Referenced by authorize_endpoint().

1338 {
1339  struct RequestHandle *handle = cls;
1341 
1342  if (GNUNET_OK !=
1344  {
1345  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1346  return;
1347  }
1348  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1349  handle->tld = GNUNET_strdup (option + 1);
1350 }
static char * pkey
Public key of the zone to look in, in ASCII.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
static char * value
Value of the record to add/remove.
char * tld
The tld for redirect.
static char * option
Name of the option.
Definition: gnunet-config.c:38
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ authorize_endpoint()

static void authorize_endpoint ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Responds to authorization GET and url-encoded POST request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 1360 of file plugin_rest_openid_connect.c.

References build_authz_response(), OIDC_Variables::client_id, OIDC_Variables::client_pkey, cookie_identity_interpretation(), do_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::ego_entry, RequestHandle::ego_head, RequestHandle::ego_tail, RequestHandle::emsg, get_url_parameter_copy(), GNUNET_CONFIGURATION_iterate_section_values(), GNUNET_CRYPTO_ecdsa_key_get_public(), GNUNET_CRYPTO_ecdsa_public_key_from_string(), GNUNET_IDENTITY_ego_get_private_key(), GNUNET_memcmp, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, EgoEntry::identifier, EgoEntry::next, RequestHandle::oidc, OIDC_CLIENT_ID_KEY, OIDC_ERROR_KEY_INVALID_REQUEST, OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT, OIDC_STATE_KEY, RequestHandle::response_code, OIDC_Variables::state, RequestHandle::tld, and tld_iter().

Referenced by init_cont().

1363 {
1364  struct RequestHandle *handle = cls;
1365  struct EgoEntry *tmp_ego;
1366  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1368 
1370 
1371  // RECOMMENDED value: state - REQUIRED for answers
1372  handle->oidc->state = get_url_parameter_copy (handle, OIDC_STATE_KEY);
1373 
1374  // REQUIRED value: client_id
1376  if (NULL == handle->oidc->client_id)
1377  {
1379  handle->edesc = GNUNET_strdup ("missing parameter client_id");
1380  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1382  return;
1383  }
1384 
1385  if (GNUNET_OK !=
1387  strlen (
1388  handle->oidc->client_id),
1389  &handle->oidc->client_pkey))
1390  {
1392  handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1393  "authorization code using this method.");
1394  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1396  return;
1397  }
1398 
1399  // If we know this identity, translated the corresponding TLD
1400  // TODO: We might want to have a reverse lookup functionality for TLDs?
1401  for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1402  {
1403  priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1405  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1406  {
1407  handle->tld = GNUNET_strdup (tmp_ego->identifier);
1408  handle->ego_entry = handle->ego_tail;
1409  }
1410  }
1411  if (NULL == handle->tld)
1413  if (NULL == handle->tld)
1414  handle->tld = GNUNET_strdup (handle->oidc->client_id);
1416 }
static char * pkey
Public key of the zone to look in, in ASCII.
struct EgoEntry * ego_tail
Ego list.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
static void cookie_identity_interpretation(struct RequestHandle *handle)
Interprets cookie header and pass its identity keystring to handle.
#define OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT
OIDC error key for unauthorized clients.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static void tld_iter(void *cls, const char *section, const char *option, const char *value)
Iterate over tlds in config.
Private ECC key encoded for transmission.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
#define OIDC_STATE_KEY
OIDC state key.
The request handle.
The ego list.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
char * tld
The tld for redirect.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
static void build_authz_response(void *cls)
Iteration over all results finished, build final response.
char * state
The OIDC state.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
char * identifier
Ego Identifier.
static void do_error(void *cls)
Task run on error, sends error message.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
struct EgoEntry * ego_entry
IDENTITY Operation.
struct EgoEntry * next
DLL.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ login_cont()

static void login_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Combines an identity with a login time and responds OK to login request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 1426 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), GNUNET_REST_RequestHandle::data, GNUNET_REST_RequestHandle::data_size, GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_free_non_null, GNUNET_log, GNUNET_memcpy, GNUNET_new, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_TIME_relative_get_second_(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_relative_to_absolute(), handle, identity, OIDC_COOKIE_EXPIRATION, RequestHandle::proc, RequestHandle::proc_cls, and RequestHandle::rest_handle.

Referenced by init_cont().

1429 {
1430  struct MHD_Response *resp = GNUNET_REST_create_response ("");
1431  struct RequestHandle *handle = cls;
1432  struct GNUNET_HashCode cache_key;
1433  struct GNUNET_TIME_Absolute *current_time;
1434  struct GNUNET_TIME_Absolute *last_time;
1435  char *cookie;
1436  char *header_val;
1437  json_t *root;
1438  json_error_t error;
1439  json_t *identity;
1440  char term_data[handle->rest_handle->data_size + 1];
1441  term_data[handle->rest_handle->data_size] = '\0';
1442  GNUNET_memcpy (term_data,
1443  handle->rest_handle->data,
1444  handle->rest_handle->data_size);
1445  root = json_loads (term_data, JSON_DECODE_ANY, &error);
1446  identity = json_object_get (root, "identity");
1447  if (! json_is_string (identity))
1448  {
1450  "Error parsing json string from %s\n",
1451  term_data);
1452  handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1453  json_decref (root);
1455  return;
1456  }
1457  GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1458  GNUNET_asprintf (&header_val,
1459  "%s;Max-Age=%d",
1460  cookie,
1462  MHD_add_response_header (resp, "Set-Cookie", header_val);
1463  MHD_add_response_header (resp, "Access-Control-Allow-Methods", "POST");
1464  GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1465 
1466  if (0 != strcmp (json_string_value (identity), "Denied"))
1467  {
1468  current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1469  *current_time = GNUNET_TIME_relative_to_absolute (
1472  last_time =
1474  GNUNET_free_non_null (last_time);
1476  &cache_key,
1477  current_time,
1479  }
1480  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1481  GNUNET_free (cookie);
1482  GNUNET_free (header_val);
1483  json_decref (root);
1485 }
If a value with the given key exists, replace it.
size_t data_size
The POST data size.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
#define OIDC_COOKIE_EXPIRATION
OIDC cookie expiration (in seconds)
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void * proc_cls
The closure of the result processor.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_memcpy(dst, src, n)
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:439
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
const char * data
The POST data.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void cleanup_handle_delayed(void *cls)
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_second_(void)
Return relative time of 1s.
Definition: time.c:183
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_authorization()

static int check_authorization ( struct RequestHandle handle,
struct GNUNET_CRYPTO_EcdsaPublicKey cid 
)
static

Definition at line 1488 of file plugin_rest_openid_connect.c.

References RequestHandle::edesc, RequestHandle::ego_entry, RequestHandle::ego_head, RequestHandle::emsg, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_free_non_null, GNUNET_NO, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_base64_decode(), GNUNET_STRINGS_string_to_data(), GNUNET_SYSERR, GNUNET_REST_RequestHandle::header_param_map, EgoEntry::keystring, EgoEntry::next, OIDC_AUTHORIZATION_HEADER_KEY, OIDC_ERROR_KEY_INVALID_CLIENT, OIDC_ERROR_KEY_SERVER_ERROR, RequestHandle::response_code, and RequestHandle::rest_handle.

Referenced by token_endpoint().

1490 {
1491  struct GNUNET_HashCode cache_key;
1492  char *authorization;
1493  char *credentials;
1494  char *basic_authorization;
1495  char *client_id;
1496  char *pass;
1497  char *expected_pass;
1498 
1501  &cache_key);
1503  ->header_param_map,
1504  &cache_key))
1505  {
1507  handle->edesc = GNUNET_strdup ("missing authorization");
1508  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1509  return GNUNET_SYSERR;
1510  }
1511  authorization =
1513  &cache_key);
1514 
1515  // split header in "Basic" and [content]
1516  credentials = strtok (authorization, " ");
1517  if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1518  {
1520  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1521  return GNUNET_SYSERR;
1522  }
1523  credentials = strtok (NULL, " ");
1524  if (NULL == credentials)
1525  {
1527  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1528  return GNUNET_SYSERR;
1529  }
1530  GNUNET_STRINGS_base64_decode (credentials,
1531  strlen (credentials),
1532  (void **) &basic_authorization);
1533 
1534  if (NULL == basic_authorization)
1535  {
1537  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1538  return GNUNET_SYSERR;
1539  }
1540  client_id = strtok (basic_authorization, ":");
1541  if (NULL == client_id)
1542  {
1543  GNUNET_free_non_null (basic_authorization);
1545  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1546  return GNUNET_SYSERR;
1547  }
1548  pass = strtok (NULL, ":");
1549  if (NULL == pass)
1550  {
1551  GNUNET_free_non_null (basic_authorization);
1553  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1554  return GNUNET_SYSERR;
1555  }
1556 
1557  // check client password
1559  "reclaim-rest-plugin",
1560  "OIDC_CLIENT_SECRET",
1561  &expected_pass))
1562  {
1563  if (0 != strcmp (expected_pass, pass))
1564  {
1565  GNUNET_free_non_null (basic_authorization);
1566  GNUNET_free (expected_pass);
1568  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1569  return GNUNET_SYSERR;
1570  }
1571  GNUNET_free (expected_pass);
1572  }
1573  else
1574  {
1575  GNUNET_free_non_null (basic_authorization);
1577  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1578  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1579  return GNUNET_SYSERR;
1580  }
1581 
1582  // check client_id
1583  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1584  handle->ego_entry = handle->ego_entry->next)
1585  {
1586  if (0 == strcmp (handle->ego_entry->keystring, client_id))
1587  break;
1588  }
1589  if (NULL == handle->ego_entry)
1590  {
1591  GNUNET_free_non_null (basic_authorization);
1593  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1594  return GNUNET_SYSERR;
1595  }
1596  GNUNET_STRINGS_string_to_data (client_id,
1597  strlen (client_id),
1598  cid,
1599  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1600 
1601  GNUNET_free (basic_authorization);
1602  return GNUNET_OK;
1603 }
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
int response_code
HTTP response code.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:2067
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * keystring
Public key string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
struct EgoEntry * ego_head
Ego list.
#define OIDC_ERROR_KEY_INVALID_CLIENT
OIDC error key for invalid client.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
struct EgoEntry * ego_entry
IDENTITY Operation.
struct EgoEntry * next
DLL.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:1021
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_ego()

const struct EgoEntry* find_ego ( struct RequestHandle handle,
struct GNUNET_CRYPTO_EcdsaPublicKey test_key 
)

Definition at line 1606 of file plugin_rest_openid_connect.c.

References EgoEntry::ego, RequestHandle::ego_head, GNUNET_IDENTITY_ego_get_public_key(), GNUNET_memcmp, and EgoEntry::next.

Referenced by token_endpoint(), and userinfo_endpoint().

1608 {
1609  struct EgoEntry *ego_entry;
1610  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1611 
1612  for (ego_entry = handle->ego_head; NULL != ego_entry;
1613  ego_entry = ego_entry->next)
1614  {
1615  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
1616  if (0 == GNUNET_memcmp (&pub_key, test_key))
1617  return ego_entry;
1618  }
1619  return NULL;
1620 }
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:569
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct EgoEntry * next
DLL.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ persist_access_token()

static void persist_access_token ( const struct RequestHandle handle,
const char *  access_token,
const struct GNUNET_RECLAIM_Ticket ticket 
)
static

Definition at line 1623 of file plugin_rest_openid_connect.c.

References GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_new, GNUNET_SYSERR, and ticket.

Referenced by token_endpoint().

1626 {
1627  struct GNUNET_HashCode hc;
1628  struct GNUNET_RECLAIM_Ticket *ticketbuf;
1629 
1630  GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc);
1631  ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
1632  *ticketbuf = *ticket;
1636  &hc,
1637  ticketbuf,
1639 }
The authorization ticket.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ token_endpoint()

static void token_endpoint ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Responds to token url-encoded POST request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 1649 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_Ticket::audience, check_authorization(), cleanup_handle_delayed(), do_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::emsg, find_ego(), get_url_parameter_copy(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_log, GNUNET_OK, GNUNET_RECLAIM_ATTRIBUTE_list_destroy(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_SYSERR, handle, GNUNET_RECLAIM_Ticket::identity, OIDC_access_token_new(), OIDC_build_token_response(), OIDC_CODE_KEY, OIDC_ERROR_KEY_INVALID_REQUEST, OIDC_ERROR_KEY_SERVER_ERROR, OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE, OIDC_GRANT_TYPE_KEY, OIDC_GRANT_TYPE_VALUE, OIDC_id_token_new(), OIDC_parse_authz_code(), persist_access_token(), RequestHandle::proc, RequestHandle::proc_cls, and RequestHandle::response_code.

Referenced by init_cont().

1652 {
1653  struct RequestHandle *handle = cls;
1654  const struct EgoEntry *ego_entry;
1655  struct GNUNET_TIME_Relative expiration_time;
1658  struct GNUNET_CRYPTO_EcdsaPublicKey cid;
1659  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1660  struct GNUNET_HashCode cache_key;
1661  struct MHD_Response *resp;
1662  char *grant_type;
1663  char *code;
1664  char *json_response;
1665  char *id_token;
1666  char *access_token;
1667  char *jwt_secret;
1668  char *nonce;
1669 
1670  /*
1671  * Check Authorization
1672  */
1673  if (GNUNET_SYSERR == check_authorization (handle, &cid))
1674  {
1676  "OIDC authorization for token endpoint failed\n");
1678  return;
1679  }
1680 
1681  /*
1682  * Check parameter
1683  */
1684 
1685  // TODO Do not allow multiple equal parameter names
1686  // REQUIRED grant_type
1688  strlen (OIDC_GRANT_TYPE_KEY),
1689  &cache_key);
1690  grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY);
1691  if (NULL == grant_type)
1692  {
1694  handle->edesc = GNUNET_strdup ("missing parameter grant_type");
1695  handle->response_code = MHD_HTTP_BAD_REQUEST;
1697  return;
1698  }
1699 
1700  // Check parameter grant_type == "authorization_code"
1701  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
1702  {
1704  handle->response_code = MHD_HTTP_BAD_REQUEST;
1705  GNUNET_free (grant_type);
1707  return;
1708  }
1709  GNUNET_free (grant_type);
1710  // REQUIRED code
1711  code = get_url_parameter_copy (handle, OIDC_CODE_KEY);
1712  if (NULL == code)
1713  {
1715  handle->edesc = GNUNET_strdup ("missing parameter code");
1716  handle->response_code = MHD_HTTP_BAD_REQUEST;
1718  return;
1719  }
1720  ego_entry = find_ego (handle, &cid);
1721  if (NULL == ego_entry)
1722  {
1724  handle->edesc = GNUNET_strdup ("Unknown client");
1725  handle->response_code = MHD_HTTP_BAD_REQUEST;
1726  GNUNET_free (code);
1728  return;
1729  }
1730  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1731  // decode code
1732  if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, &ticket, &cl, &nonce))
1733  {
1735  handle->edesc = GNUNET_strdup ("invalid code");
1736  handle->response_code = MHD_HTTP_BAD_REQUEST;
1737  GNUNET_free (code);
1739  return;
1740  }
1741  GNUNET_free (code);
1742 
1743  // create jwt
1745  "reclaim-rest-plugin",
1746  "expiration_time",
1747  &expiration_time))
1748  {
1750  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1751  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1753  return;
1754  }
1755 
1756 
1757  // TODO OPTIONAL acr,amr,azp
1759  "reclaim-rest-plugin",
1760  "jwt_secret",
1761  &jwt_secret))
1762  {
1764  handle->edesc = GNUNET_strdup ("No signing secret configured!");
1765  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1767  return;
1768  }
1769  id_token = OIDC_id_token_new (&ticket.audience,
1770  &ticket.identity,
1771  cl,
1772  &expiration_time,
1773  (NULL != nonce) ? nonce : NULL,
1774  jwt_secret);
1775  access_token = OIDC_access_token_new ();
1776  OIDC_build_token_response (access_token,
1777  id_token,
1778  &expiration_time,
1779  &json_response);
1780 
1781  persist_access_token (handle, access_token, &ticket);
1782  resp = GNUNET_REST_create_response (json_response);
1783  MHD_add_response_header (resp, "Cache-Control", "no-store");
1784  MHD_add_response_header (resp, "Pragma", "no-cache");
1785  MHD_add_response_header (resp, "Content-Type", "application/json");
1786  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1788  GNUNET_free (access_token);
1789  GNUNET_free (json_response);
1790  GNUNET_free (id_token);
1792 }
The authorization ticket.
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
#define OIDC_GRANT_TYPE_KEY
OIDC grant_type key.
static void persist_access_token(const struct RequestHandle *handle, const char *access_token, const struct GNUNET_RECLAIM_Ticket *ticket)
#define OIDC_CODE_KEY
OIDC code key.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
Private ECC key encoded for transmission.
void OIDC_build_token_response(const char *access_token, const char *id_token, const struct GNUNET_TIME_Relative *expiration_time, char **token_response)
Build a token response for a token request TODO: Maybe we should add the scope here?
Definition: oidc_helper.c:620
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
The request handle.
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE
OIDC error key for unsupported grants.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_RECLAIM_ATTRIBUTE_list_destroy(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Destroy claim list.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
int response_code
HTTP response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
int OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, const char *code, struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList **attrs, char **nonce_str)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:514
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int check_authorization(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
static void do_error(void *cls)
Task run on error, sends error message.
static void cleanup_handle_delayed(void *cls)
char * OIDC_access_token_new()
Generate a new access token.
Definition: oidc_helper.c:647
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_GRANT_TYPE_VALUE
OIDC grant_type key.
char * OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:84
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ consume_ticket()

static void consume_ticket ( void *  cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey identity,
const struct GNUNET_RECLAIM_ATTRIBUTE_Claim attr 
)
static

Collects claims and stores them in handle.

Definition at line 1798 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_ATTRIBUTE_Claim::data, GNUNET_RECLAIM_ATTRIBUTE_Claim::data_size, GNUNET_free, GNUNET_RECLAIM_ATTRIBUTE_value_to_string(), GNUNET_SCHEDULER_add_now(), handle, GNUNET_RECLAIM_ATTRIBUTE_Claim::name, RequestHandle::oidc, OIDC_Variables::response, return_userinfo_response(), GNUNET_RECLAIM_ATTRIBUTE_Claim::type, and value.

Referenced by userinfo_endpoint().

1801 {
1802  struct RequestHandle *handle = cls;
1803  char *tmp_value;
1804  json_t *value;
1805 
1806  if (NULL == identity)
1807  {
1809  return;
1810  }
1812  attr->data,
1813  attr->data_size);
1814  value = json_string (tmp_value);
1815  json_object_set_new (handle->oidc->response, attr->name, value);
1816  GNUNET_free (tmp_value);
1817 }
const char * name
The name of the attribute.
char * GNUNET_RECLAIM_ATTRIBUTE_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;claim&#39; of an attribute to a string.
size_t data_size
Number of bytes in data.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
const void * data
Binary value stored as attribute value.
static char * value
Value of the record to add/remove.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void return_userinfo_response(void *cls)
Return attributes for claim.
json_t * response
The response JSON.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ userinfo_endpoint()

static void userinfo_endpoint ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 
)
static

Responds to userinfo GET and url-encoded POST request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 1827 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_Ticket::audience, consume_ticket(), do_userinfo_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::emsg, find_ego(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_NO, GNUNET_RECLAIM_connect(), GNUNET_RECLAIM_ticket_consume(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, GNUNET_REST_RequestHandle::header_param_map, RequestHandle::idp, RequestHandle::idp_op, EgoEntry::keystring, RequestHandle::oidc, OIDC_AUTHORIZATION_HEADER_KEY, OIDC_ERROR_KEY_INVALID_TOKEN, OIDC_Variables::response, RequestHandle::response_code, RequestHandle::rest_handle, and ticket.

Referenced by init_cont().

1830 {
1831  // TODO expiration time
1832  struct RequestHandle *handle = cls;
1833  char delimiter[] = " ";
1834  struct GNUNET_HashCode cache_key;
1835  char *authorization;
1836  char *authorization_type;
1837  char *authorization_access_token;
1838  struct GNUNET_RECLAIM_Ticket *ticket;
1839  const struct EgoEntry *ego_entry;
1840  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1841 
1844  &cache_key);
1846  ->header_param_map,
1847  &cache_key))
1848  {
1850  handle->edesc = GNUNET_strdup ("No Access Token");
1851  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1853  return;
1854  }
1855  authorization =
1857  &cache_key);
1858 
1859  // split header in "Bearer" and access_token
1860  authorization = GNUNET_strdup (authorization);
1861  authorization_type = strtok (authorization, delimiter);
1862  if ((NULL == authorization_type) ||
1863  (0 != strcmp ("Bearer", authorization_type)))
1864  {
1866  handle->edesc = GNUNET_strdup ("No Access Token");
1867  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1869  GNUNET_free (authorization);
1870  return;
1871  }
1872  authorization_access_token = strtok (NULL, delimiter);
1873  if (NULL == authorization_access_token)
1874  {
1876  handle->edesc = GNUNET_strdup ("Access token missing");
1877  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1879  GNUNET_free (authorization);
1880  return;
1881  }
1882 
1883  GNUNET_CRYPTO_hash (authorization_access_token,
1884  strlen (authorization_access_token),
1885  &cache_key);
1886  if (GNUNET_NO ==
1888  &cache_key))
1889  {
1891  handle->edesc = GNUNET_strdup ("The access token expired");
1892  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1894  GNUNET_free (authorization);
1895  return;
1896  }
1897  ticket =
1899  GNUNET_assert (NULL != ticket);
1900  ego_entry = find_ego (handle, &ticket->audience);
1901  if (NULL == ego_entry)
1902  {
1904  handle->edesc = GNUNET_strdup ("The access token expired");
1905  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1907  GNUNET_free (authorization);
1908  return;
1909  }
1910 
1911  handle->idp = GNUNET_RECLAIM_connect (cfg);
1912  handle->oidc->response = json_object ();
1913  json_object_set_new (handle->oidc->response,
1914  "sub",
1915  json_string (ego_entry->keystring));
1916  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1917  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
1918  privkey,
1919  ticket,
1921  handle);
1922  GNUNET_free (authorization);
1923 }
The authorization ticket.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
#define GNUNET_NO
Definition: gnunet_common.h:81
Private ECC key encoded for transmission.
#define OIDC_ERROR_KEY_INVALID_TOKEN
OIDC error key for invalid tokens.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
int response_code
HTTP response code.
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
static void consume_ticket(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
Collects claims and stores them in handle.
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_AttributeResult cb, void *cb_cls)
Consumes an issued ticket.
Definition: reclaim_api.c:1099
json_t * response
The response JSON.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
struct GNUNET_RECLAIM_Handle * GNUNET_RECLAIM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the re:claimID service.
Definition: reclaim_api.c:779
#define GNUNET_free(ptr)
Wrapper around free.
static void do_userinfo_error(void *cls)
Task run on error in userinfo endpoint, sends error header.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_cont()

static void init_cont ( struct RequestHandle handle)
static

Handle rest request.

Parameters
handlethe request handle

Definition at line 1932 of file plugin_rest_openid_connect.c.

References authorize_endpoint(), do_error(), GNUNET_REST_RequestHandlerError::error_code, GNUNET_NO, GNUNET_REST_API_NS_AUTHORIZE, GNUNET_REST_API_NS_LOGIN, GNUNET_REST_API_NS_OIDC, GNUNET_REST_API_NS_TOKEN, GNUNET_REST_API_NS_USERINFO, GNUNET_REST_handle_request(), GNUNET_REST_HANDLER_END, GNUNET_SCHEDULER_add_now(), login_cont(), options_cont(), RequestHandle::response_code, RequestHandle::rest_handle, token_endpoint(), and userinfo_endpoint().

Referenced by list_ego().

1933 {
1935  static const struct GNUNET_REST_RequestHandler handlers[] =
1936  {{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint},
1937  {MHD_HTTP_METHOD_POST,
1939  &authorize_endpoint}, // url-encoded
1940  {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont},
1941  {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint},
1942  {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint},
1943  {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint},
1944  {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont},
1946 
1947  if (GNUNET_NO ==
1948  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1949  {
1950  handle->response_code = err.error_code;
1952  }
1953 }
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_REST_HANDLER_END
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
#define GNUNET_REST_API_NS_AUTHORIZE
Authorize endpoint.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
Definition: rest.c:76
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
static void login_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Combines an identity with a login time and responds OK to login request.
static void userinfo_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to userinfo GET and url-encoded POST request.
#define GNUNET_REST_API_NS_LOGIN
Login namespace.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static void authorize_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to authorization GET and url-encoded POST request.
static void do_error(void *cls)
Task run on error, sends error message.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void token_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to token url-encoded POST request.
#define GNUNET_REST_API_NS_USERINFO
UserInfo endpoint.
#define GNUNET_REST_API_NS_TOKEN
Token endpoint.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ list_ego()

static void list_ego ( void *  cls,
struct GNUNET_IDENTITY_Ego ego,
void **  ctx,
const char *  identifier 
)
static

If listing is enabled, prints information about the egos.

This function is initially called for all egos and then again whenever a ego's identifier changes or if it is deleted. At the end of the initial pass over all egos, the function is once called with 'NULL' for 'ego'. That does NOT mean that the callback won't be invoked in the future or that there was an error.

When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', this function is only called ONCE, and 'NULL' being passed in 'ego' does indicate an error (i.e. name is taken or no default value is known). If 'ego' is non-NULL and if '*ctx' is set in those callbacks, the value WILL be passed to a subsequent call to the identity callback of 'GNUNET_IDENTITY_connect' (if that one was not NULL).

When an identity is renamed, this function is called with the (known) ego but the NEW identifier.

When an identity is deleted, this function is called with the (known) ego and "NULL" for the 'identifier'. In this case, the 'ego' is henceforth invalid (and the 'ctx' should also be cleaned up).

Parameters
clsclosure
egoego handle
ctxcontext for application to store data for this ego (during the lifetime of this process, initially NULL)
identifieridentifier assigned by the user for this ego, NULL if the user just deleted the ego and it must thus no longer be used

Definition at line 1989 of file plugin_rest_openid_connect.c.

References EgoEntry::ego, RequestHandle::ego_head, RequestHandle::ego_tail, GNUNET_assert, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_CRYPTO_ecdsa_public_key_to_string(), GNUNET_free, GNUNET_IDENTITY_ego_get_public_key(), GNUNET_new, GNUNET_strdup, handle, ID_REST_STATE_INIT, ID_REST_STATE_POST_INIT, EgoEntry::identifier, init_cont(), EgoEntry::keystring, EgoEntry::next, and RequestHandle::state.

Referenced by rest_identity_process_request().

1993 {
1994  struct RequestHandle *handle = cls;
1995  struct EgoEntry *ego_entry;
1997 
1998  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1999  {
2000  handle->state = ID_REST_STATE_POST_INIT;
2001  init_cont (handle);
2002  return;
2003  }
2004  GNUNET_assert (NULL != ego);
2005  if (ID_REST_STATE_INIT == handle->state)
2006  {
2007  ego_entry = GNUNET_new (struct EgoEntry);
2010  ego_entry->ego = ego;
2011  ego_entry->identifier = GNUNET_strdup (identifier);
2013  handle->ego_tail,
2014  ego_entry);
2015  return;
2016  }
2017  /* Ego renamed or added */
2018  if (identifier != NULL)
2019  {
2020  for (ego_entry = handle->ego_head; NULL != ego_entry;
2021  ego_entry = ego_entry->next)
2022  {
2023  if (ego_entry->ego == ego)
2024  {
2025  /* Rename */
2026  GNUNET_free (ego_entry->identifier);
2027  ego_entry->identifier = GNUNET_strdup (identifier);
2028  break;
2029  }
2030  }
2031  if (NULL == ego_entry)
2032  {
2033  /* Add */
2034  ego_entry = GNUNET_new (struct EgoEntry);
2037  ego_entry->ego = ego;
2038  ego_entry->identifier = GNUNET_strdup (identifier);
2040  handle->ego_tail,
2041  ego_entry);
2042  }
2043  }
2044  else
2045  {
2046  /* Delete */
2047  for (ego_entry = handle->ego_head; NULL != ego_entry;
2048  ego_entry = ego_entry->next)
2049  {
2050  if (ego_entry->ego == ego)
2051  break;
2052  }
2053  if (NULL != ego_entry)
2055  handle->ego_tail,
2056  ego_entry);
2057  }
2058 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
struct EgoEntry * ego_tail
Ego list.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
The request handle.
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void init_cont(struct RequestHandle *handle)
Handle rest request.
int state
The processing state.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:334
char * keystring
Public key string.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:569
char * identifier
Ego Identifier.
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define ID_REST_STATE_INIT
State while collecting all egos.
struct EgoEntry * next
DLL.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rest_identity_process_request()

static void rest_identity_process_request ( struct GNUNET_REST_RequestHandle rest_handle,
GNUNET_REST_ResultProcessor  proc,
void *  proc_cls 
)
static

Definition at line 2061 of file plugin_rest_openid_connect.c.

References do_timeout(), RequestHandle::gns_handle, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNS_connect(), GNUNET_IDENTITY_connect(), GNUNET_log, GNUNET_NAMESTORE_connect(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_strdup, GNUNET_TIME_UNIT_FOREVER_REL, handle, ID_REST_STATE_INIT, RequestHandle::identity_handle, list_ego(), RequestHandle::namestore_handle, RequestHandle::oidc, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::response_code, RequestHandle::rest_handle, RequestHandle::state, RequestHandle::timeout, RequestHandle::timeout_task, GNUNET_REST_RequestHandle::url, and RequestHandle::url.

Referenced by libgnunet_plugin_rest_openid_connect_init().

2064 {
2065  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2066  handle->oidc = GNUNET_new (struct OIDC_Variables);
2067  if (NULL == OIDC_cookie_jar_map)
2069  if (NULL == OIDC_access_token_map)
2072  handle->response_code = 0;
2074  handle->proc_cls = proc_cls;
2075  handle->proc = proc;
2076  handle->state = ID_REST_STATE_INIT;
2077  handle->rest_handle = rest_handle;
2078 
2079  handle->url = GNUNET_strdup (rest_handle->url);
2080  if (handle->url[strlen (handle->url) - 1] == '/')
2081  handle->url[strlen (handle->url) - 1] = '\0';
2082  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
2083  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
2084  handle->gns_handle = GNUNET_GNS_connect (cfg);
2086  handle->timeout_task =
2087  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
2088  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
2089 }
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:528
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
OIDC needed variables.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
static void do_timeout(void *cls)
Task run on timeout, sends error message.
const char * url
The url as string.
struct GNUNET_TIME_Relative timeout
Timeout.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:263
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
int state
The processing state.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define ID_REST_STATE_INIT
State while collecting all egos.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
struct GNUNET_NAMESTORE_Handle * namestore_handle
Handle to NAMESTORE.
char * url
The url.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_rest_openid_connect_init()

void* libgnunet_plugin_rest_openid_connect_init ( void *  cls)

Entry point for the plugin.

Parameters
clsConfig info
Returns
NULL on error, otherwise the plugin context

Definition at line 2098 of file plugin_rest_openid_connect.c.

References _, allow_methods, Plugin::api, Plugin::cfg, GNUNET_REST_Plugin::cls, GNUNET_asprintf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_REST_API_NS_OIDC, GNUNET_REST_Plugin::name, plugin, GNUNET_REST_Plugin::process_request, and rest_identity_process_request().

2099 {
2100  static struct Plugin plugin;
2101  struct GNUNET_REST_Plugin *api;
2102 
2103  cfg = cls;
2104  if (NULL != plugin.cfg)
2105  return NULL; /* can only initialize once! */
2106  memset (&plugin, 0, sizeof (struct Plugin));
2107  plugin.cfg = cfg;
2108  api = GNUNET_new (struct GNUNET_REST_Plugin);
2109  api->cls = &plugin;
2113  "%s, %s, %s, %s, %s",
2114  MHD_HTTP_METHOD_GET,
2115  MHD_HTTP_METHOD_POST,
2116  MHD_HTTP_METHOD_PUT,
2117  MHD_HTTP_METHOD_DELETE,
2118  MHD_HTTP_METHOD_OPTIONS);
2119 
2121  _ ("OpenID Connect REST API initialized\n"));
2122  return api;
2123 }
void * cls
The closure of the plugin.
struct returned by the initialization function of the plugin
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
void(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * name
Plugin name.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
Here is the call graph for this function:

◆ libgnunet_plugin_rest_openid_connect_done()

void* libgnunet_plugin_rest_openid_connect_done ( void *  cls)

Exit point from the plugin.

Parameters
clsthe plugin context (as returned by "init")
Returns
always NULL

Definition at line 2133 of file plugin_rest_openid_connect.c.

References allow_methods, Plugin::api, Plugin::cfg, GNUNET_REST_Plugin::cls, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterator_create(), GNUNET_CONTAINER_multihashmap_iterator_destroy(), GNUNET_CONTAINER_multihashmap_iterator_next(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_free_non_null, GNUNET_log, GNUNET_YES, plugin, and value.

2134 {
2135  struct GNUNET_REST_Plugin *api = cls;
2136  struct Plugin *plugin = api->cls;
2137  plugin->cfg = NULL;
2138 
2139  struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it;
2140  void *value = NULL;
2141  hashmap_it =
2143  while (GNUNET_YES ==
2144  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2145  GNUNET_free_non_null (value);
2148 
2149  hashmap_it =
2151  while (GNUNET_YES ==
2152  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2153  GNUNET_free_non_null (value);
2157  GNUNET_free (api);
2159  "OpenID Connect REST plugin is finished\n");
2160  return NULL;
2161 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
void * cls
The closure of the plugin.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct returned by the initialization function of the plugin
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

Variable Documentation

◆ OIDC_ignored_parameter_array

char* OIDC_ignored_parameter_array[]
static
Initial value:
= {"display",
"prompt",
"ui_locales",
"response_mode",
"id_token_hint",
"login_hint",
"acr_values"}

OIDC ignored parameter array.

Definition at line 211 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response().

◆ OIDC_cookie_jar_map

struct GNUNET_CONTAINER_MultiHashMap* OIDC_cookie_jar_map

OIDC Hash map that keeps track of issued cookies.

Definition at line 222 of file plugin_rest_openid_connect.c.

◆ OIDC_access_token_map

struct GNUNET_CONTAINER_MultiHashMap* OIDC_access_token_map

Hash map that links the issued access token to the corresponding ticket and ego.

Definition at line 228 of file plugin_rest_openid_connect.c.

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg

The configuration handle.

Handle to our configuration.

Definition at line 233 of file plugin_rest_openid_connect.c.

◆ allow_methods

char* allow_methods
static

HTTP methods allows for this plugin.

Definition at line 238 of file plugin_rest_openid_connect.c.

Referenced by libgnunet_plugin_rest_openid_connect_done(), libgnunet_plugin_rest_openid_connect_init(), and options_cont().