GNUnet  0.11.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_CODE_CHALLENGE_KEY   "code_challenge"
 OIDC PKCE code challenge. More...
 
#define OIDC_CODE_VERIFIER_KEY   "code_verifier"
 OIDC PKCE code verifier. 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_CODE_CHALLENGE_KEY

#define OIDC_CODE_CHALLENGE_KEY   "code_challenge"

OIDC PKCE code challenge.

Definition at line 125 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint(), and login_redirect().

◆ OIDC_CODE_VERIFIER_KEY

#define OIDC_CODE_VERIFIER_KEY   "code_verifier"

OIDC PKCE code verifier.

Definition at line 130 of file plugin_rest_openid_connect.c.

Referenced by token_endpoint().

◆ OIDC_COOKIE_EXPIRATION

#define OIDC_COOKIE_EXPIRATION   3

OIDC cookie expiration (in seconds)

Definition at line 135 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 140 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 145 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 150 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 155 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 160 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 165 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 170 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 175 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 180 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 185 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 190 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 200 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 205 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 210 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 215 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 514 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().

515 {
516  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
517  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
518  struct EgoEntry *ego_entry;
519  struct EgoEntry *ego_tmp;
520 
521  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
522  if (NULL != handle->timeout_task)
524  if (NULL != handle->identity_handle)
526  if (NULL != handle->attr_it)
528  if (NULL != handle->ticket_it)
530  if (NULL != handle->idp)
531  GNUNET_RECLAIM_disconnect (handle->idp);
532  GNUNET_free_non_null (handle->url);
533  GNUNET_free_non_null (handle->tld);
536  GNUNET_free_non_null (handle->emsg);
537  GNUNET_free_non_null (handle->edesc);
538  if (NULL != handle->gns_op)
540  if (NULL != handle->gns_handle)
542 
543  if (NULL != handle->namestore_handle)
545  if (NULL != handle->oidc)
546  {
549  GNUNET_free_non_null (handle->oidc->nonce);
552  GNUNET_free_non_null (handle->oidc->scope);
553  GNUNET_free_non_null (handle->oidc->state);
554  json_decref (handle->oidc->response);
555  GNUNET_free (handle->oidc);
556  }
557  if (NULL != handle->attr_list)
558  {
559  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
560  {
561  claim_tmp = claim_entry;
562  claim_entry = claim_entry->next;
563  GNUNET_free (claim_tmp->claim);
564  GNUNET_free (claim_tmp);
565  }
566  GNUNET_free (handle->attr_list);
567  }
568  for (ego_entry = handle->ego_head; NULL != ego_entry;)
569  {
570  ego_tmp = ego_entry;
571  ego_entry = ego_entry->next;
572  GNUNET_free (ego_tmp->identifier);
573  GNUNET_free (ego_tmp->keystring);
574  GNUNET_free (ego_tmp);
575  }
576  GNUNET_free (handle);
577 }
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:1209
#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:284
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:837
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:1021
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:308
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:966
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 581 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().

582 {
583  cleanup_handle (cls);
584 }
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 593 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().

594 {
595  struct RequestHandle *handle = cls;
596  struct MHD_Response *resp;
597  char *json_error;
598 
599  GNUNET_asprintf (&json_error,
600  "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
601  handle->emsg,
602  (NULL != handle->edesc) ? handle->edesc : "",
603  (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
604  (NULL != handle->oidc->state) ? handle->oidc->state : "",
605  (NULL != handle->oidc->state) ? "\"" : "");
606  if (0 == handle->response_code)
607  handle->response_code = MHD_HTTP_BAD_REQUEST;
608  resp = GNUNET_REST_create_response (json_error);
609  if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
610  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
611  MHD_add_response_header (resp,
612  MHD_HTTP_HEADER_CONTENT_TYPE,
613  "application/json");
614  handle->proc (handle->proc_cls, resp, handle->response_code);
616  GNUNET_free (json_error);
617 }
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:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
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:57
#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 627 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().

628 {
629  struct RequestHandle *handle = cls;
630  struct MHD_Response *resp;
631  char *error;
632 
633  GNUNET_asprintf (&error,
634  "error=\"%s\", error_description=\"%s\"",
635  handle->emsg,
636  (NULL != handle->edesc) ? handle->edesc : "");
637  resp = GNUNET_REST_create_response ("");
638  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
639  handle->proc (handle->proc_cls, resp, handle->response_code);
641  GNUNET_free (error);
642 }
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:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
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:57
#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 651 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().

652 {
653  struct RequestHandle *handle = cls;
654  struct MHD_Response *resp;
655  char *redirect;
656 
657  GNUNET_asprintf (&redirect,
658  "%s?error=%s&error_description=%s%s%s",
659  handle->oidc->redirect_uri,
660  handle->emsg,
661  handle->edesc,
662  (NULL != handle->oidc->state) ? "&state=" : "",
663  (NULL != handle->oidc->state) ? handle->oidc->state : "");
664  resp = GNUNET_REST_create_response ("");
665  MHD_add_response_header (resp, "Location", redirect);
666  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
668  GNUNET_free (redirect);
669 }
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:1280
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:57
#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 678 of file plugin_rest_openid_connect.c.

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

Referenced by rest_identity_process_request().

679 {
680  struct RequestHandle *handle = cls;
681 
682  handle->timeout_task = NULL;
683  do_error (handle);
684 }
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 693 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().

694 {
695  char *result_str;
696  struct RequestHandle *handle = cls;
697  struct MHD_Response *resp;
698 
699  result_str = json_dumps (handle->oidc->response, 0);
700 
701  resp = GNUNET_REST_create_response (result_str);
702  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
703  GNUNET_free (result_str);
704  cleanup_handle (handle);
705 }
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:57
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 716 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().

719 {
720  struct MHD_Response *resp;
721  struct RequestHandle *handle = cls;
722 
723  // For now, independent of path return all options
724  resp = GNUNET_REST_create_response (NULL);
725  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
726  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
727  cleanup_handle (handle);
728  return;
729 }
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:57
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 736 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().

737 {
738  struct GNUNET_HashCode cache_key;
739  char *cookies;
740  struct GNUNET_TIME_Absolute current_time, *relog_time;
741  char delimiter[] = "; ";
742  char *tmp_cookies;
743  char *token;
744  char *value;
745 
746  // gets identity of login try with cookie
748  strlen (OIDC_COOKIE_HEADER_KEY),
749  &cache_key);
752  &cache_key))
753  {
754  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
755  return;
756  }
757  // splits cookies and find 'Identity' cookie
758  tmp_cookies =
760  &cache_key);
761  cookies = GNUNET_strdup (tmp_cookies);
762  token = strtok (cookies, delimiter);
763  handle->oidc->user_cancelled = GNUNET_NO;
764  handle->oidc->login_identity = NULL;
765  if (NULL == token)
766  {
768  "Unable to parse cookie: %s\n",
769  cookies);
770  GNUNET_free (cookies);
771  return;
772  }
773 
774  while (NULL != token)
775  {
776  if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
777  {
778  handle->oidc->user_cancelled = GNUNET_YES;
779  GNUNET_free (cookies);
780  return;
781  }
782  if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
783  break;
784  token = strtok (NULL, delimiter);
785  }
786  if (NULL == token)
787  {
789  "No cookie value to process: %s\n",
790  cookies);
791  GNUNET_free (cookies);
792  return;
793  }
794  GNUNET_CRYPTO_hash (token, strlen (token), &cache_key);
795  if (GNUNET_NO ==
797  {
798  GNUNET_log (
800  "Found cookie `%s', but no corresponding expiration entry present...\n",
801  token);
802  GNUNET_free (cookies);
803  return;
804  }
805  relog_time =
807  current_time = GNUNET_TIME_absolute_get ();
808  // 30 min after old login -> redirect to login
809  if (current_time.abs_value_us > relog_time->abs_value_us)
810  {
812  "Found cookie `%s', but it is expired.\n",
813  token);
814  GNUNET_free (cookies);
815  return;
816  }
817  value = strtok (token, OIDC_COOKIE_HEADER_INFORMATION_KEY);
818  GNUNET_assert (NULL != value);
819  handle->oidc->login_identity = GNUNET_strdup (value);
820  GNUNET_free (cookies);
821 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
#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:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
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:77
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 828 of file plugin_rest_openid_connect.c.

References cleanup_handle_delayed(), OIDC_Variables::client_id, OIDC_Variables::code_challenge, 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_CODE_CHALLENGE_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().

829 {
830  char *login_base_url;
831  char *new_redirect;
832  struct MHD_Response *resp;
833  struct RequestHandle *handle = cls;
834 
836  "reclaim-rest-plugin",
837  "address",
838  &login_base_url))
839  {
840  GNUNET_asprintf (&new_redirect,
841  "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
842  login_base_url,
844  handle->oidc->response_type,
846  handle->oidc->client_id,
848  handle->oidc->redirect_uri,
850  handle->oidc->scope,
852  (NULL != handle->oidc->state) ? handle->oidc->state : "",
854  (NULL != handle->oidc->code_challenge) ?
855  handle->oidc->code_challenge : "",
857  (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
858  resp = GNUNET_REST_create_response ("");
859  MHD_add_response_header (resp, "Location", new_redirect);
860  GNUNET_free (login_base_url);
861  }
862  else
863  {
865  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
866  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
868  return;
869  }
870  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
871  GNUNET_free (new_redirect);
873 }
char * redirect_uri
The OIDC redirect uri.
char * scope
The list of oidc scopes.
#define OIDC_NONCE_KEY
OIDC nonce key.
#define OIDC_CODE_CHALLENGE_KEY
OIDC PKCE code challenge.
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:75
#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:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
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:57
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.
char * code_challenge
The PKCE code_challenge.
#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 880 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().

881 {
882  struct RequestHandle *handle = cls;
883 
885  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
887 }
#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:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
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 895 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_list, cleanup_handle_delayed(), OIDC_Variables::code_challenge, 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().

896 {
897  struct RequestHandle *handle = cls;
898  struct MHD_Response *resp;
899  char *ticket_str;
900  char *redirect_uri;
901  char *code_string;
902 
903  handle->idp_op = NULL;
904  if (NULL == ticket)
905  {
907  handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
909  return;
910  }
911  handle->ticket = *ticket;
912  ticket_str =
914  sizeof(struct GNUNET_RECLAIM_Ticket));
915  // TODO change if more attributes are needed (see max_age)
916  code_string = OIDC_build_authz_code (&handle->priv_key,
917  &handle->ticket,
918  handle->attr_list,
919  handle->oidc->nonce,
920  handle->oidc->code_challenge);
921  if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
922  (NULL != handle->tld))
923  {
924  GNUNET_asprintf (&redirect_uri,
925  "%s.%s/%s?%s=%s&state=%s",
926  handle->redirect_prefix,
927  handle->tld,
928  handle->redirect_suffix,
929  handle->oidc->response_type,
930  code_string,
931  handle->oidc->state);
932  }
933  else
934  {
935  GNUNET_asprintf (&redirect_uri,
936  "%s?%s=%s&state=%s",
937  handle->oidc->redirect_uri,
938  handle->oidc->response_type,
939  code_string,
940  handle->oidc->state);
941  }
942  resp = GNUNET_REST_create_response ("");
943  MHD_add_response_header (resp, "Location", redirect_uri);
944  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
946  GNUNET_free (redirect_uri);
947  GNUNET_free (ticket_str);
948  GNUNET_free (code_string);
949 }
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:1280
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
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:57
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:920
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, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:463
char * code_challenge
The PKCE code_challenge.
#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 953 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().

954 {
955  struct RequestHandle *handle = cls;
956 
957  handle->attr_it = NULL;
958  handle->ticket_it = NULL;
959  if (NULL == handle->attr_list->list_head)
960  {
962  handle->edesc = GNUNET_strdup ("The requested scope is not available.");
964  return;
965  }
966  handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
967  &handle->priv_key,
968  &handle->oidc->client_pkey,
969  handle->attr_list,
971  handle);
972 }
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:1280
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:1052
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 979 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().

982 {
983  struct RequestHandle *handle = cls;
985  char *scope_variables;
986  char *scope_variable;
987  char delimiter[] = " ";
988 
989  if ((NULL == attr->name) || (NULL == attr->data))
990  {
992  return;
993  }
994 
995  scope_variables = GNUNET_strdup (handle->oidc->scope);
996  scope_variable = strtok (scope_variables, delimiter);
997  while (NULL != scope_variable)
998  {
999  if (0 == strcmp (attr->name, scope_variable))
1000  break;
1001  scope_variable = strtok (NULL, delimiter);
1002  }
1003  if (NULL == scope_variable)
1004  {
1006  GNUNET_free (scope_variables);
1007  return;
1008  }
1009  GNUNET_free (scope_variables);
1010 
1013  attr->type,
1014  attr->data,
1015  attr->data_size);
1016  le->claim->id = attr->id;
1017  le->claim->version = attr->version;
1019  handle->attr_list->list_tail,
1020  le);
1022 }
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:1000
#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 1029 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().

1030 {
1031  struct RequestHandle *handle = cls;
1032  struct GNUNET_TIME_Absolute current_time;
1033  struct GNUNET_TIME_Absolute *relog_time;
1035  struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey;
1036  struct GNUNET_HashCode cache_key;
1037  char *identity_cookie;
1038 
1039  GNUNET_asprintf (&identity_cookie,
1040  "Identity=%s",
1041  handle->oidc->login_identity);
1042  GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1043  GNUNET_free (identity_cookie);
1044  // No login time for identity -> redirect to login
1045  if (GNUNET_YES ==
1047  {
1048  relog_time =
1050  current_time = GNUNET_TIME_absolute_get ();
1051  // 30 min after old login -> redirect to login
1052  if (current_time.abs_value_us <= relog_time->abs_value_us)
1053  {
1054  if (GNUNET_OK !=
1056  ->login_identity,
1057  strlen (
1058  handle->oidc
1059  ->login_identity),
1060  &pubkey))
1061  {
1063  handle->edesc =
1064  GNUNET_strdup ("The cookie of a login identity is not valid");
1066  return;
1067  }
1068  // iterate over egos and compare their public key
1069  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1070  handle->ego_entry = handle->ego_entry->next)
1071  {
1072  GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1073  if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1074  {
1075  handle->priv_key =
1077  handle->idp = GNUNET_RECLAIM_connect (cfg);
1078  handle->attr_list =
1080  handle->attr_it =
1082  &handle->priv_key,
1084  handle,
1086  handle,
1088  handle);
1089  return;
1090  }
1091  }
1093  return;
1094  }
1095  }
1096 }
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:954
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:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:48
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:1280
#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:568
#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:466
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:77
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 1100 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().

1101 {
1102  struct RequestHandle *handle = cls;
1103  struct MHD_Response *resp;
1104  char *redirect_uri;
1105 
1106  if (GNUNET_YES == handle->oidc->user_cancelled)
1107  {
1108  if ((NULL != handle->redirect_prefix) &&
1109  (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1110  {
1111  GNUNET_asprintf (&redirect_uri,
1112  "%s.%s/%s?error=%s&error_description=%s&state=%s",
1113  handle->redirect_prefix,
1114  handle->tld,
1115  handle->redirect_suffix,
1116  "access_denied",
1117  "User denied access",
1118  handle->oidc->state);
1119  }
1120  else
1121  {
1122  GNUNET_asprintf (&redirect_uri,
1123  "%s?error=%s&error_description=%s&state=%s",
1124  handle->oidc->redirect_uri,
1125  "access_denied",
1126  "User denied access",
1127  handle->oidc->state);
1128  }
1129  resp = GNUNET_REST_create_response ("");
1130  MHD_add_response_header (resp, "Location", redirect_uri);
1131  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1133  GNUNET_free (redirect_uri);
1134  return;
1135  }
1137 }
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:1280
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:57
#define GNUNET_YES
Definition: gnunet_common.h:77
#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 1141 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().

1144 {
1145  struct RequestHandle *handle = cls;
1146  char *tmp;
1147  char *tmp_key_str;
1148  char *pos;
1149  struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1150 
1151  handle->gns_op = NULL;
1152  if (0 == rd_count)
1153  {
1155  handle->edesc =
1156  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1158  return;
1159  }
1160  for (int i = 0; i < rd_count; i++)
1161  {
1162  if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1163  continue;
1164  if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1165  continue;
1166  tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1167  if (NULL == strstr (tmp, handle->oidc->client_id))
1168  {
1170  "Redirect uri %s does not contain client_id %s\n",
1171  tmp,
1172  handle->oidc->client_id);
1173  }
1174  else
1175  {
1176  pos = strrchr (tmp, (unsigned char) '.');
1177  if (NULL == pos)
1178  {
1180  "Redirect uri %s contains client_id but is malformed\n",
1181  tmp);
1182  GNUNET_free (tmp);
1183  continue;
1184  }
1185  *pos = '\0';
1186  handle->redirect_prefix = GNUNET_strdup (tmp);
1187  tmp_key_str = pos + 1;
1188  pos = strchr (tmp_key_str, (unsigned char) '/');
1189  if (NULL == pos)
1190  {
1192  "Redirect uri %s contains client_id but is malformed\n",
1193  tmp);
1194  GNUNET_free (tmp);
1195  continue;
1196  }
1197  *pos = '\0';
1198  handle->redirect_suffix = GNUNET_strdup (pos + 1);
1199 
1200  GNUNET_STRINGS_string_to_data (tmp_key_str,
1201  strlen (tmp_key_str),
1202  &redirect_zone,
1203  sizeof(redirect_zone));
1204  }
1206  GNUNET_free (tmp);
1207  return;
1208  }
1210  handle->edesc =
1211  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1213 }
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.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
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:1280
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.
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:952
#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 1220 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().

1221 {
1222  struct RequestHandle *handle = cls;
1223 
1224  /* Lookup client redirect uri to verify request */
1225  handle->gns_op =
1226  GNUNET_GNS_lookup (handle->gns_handle,
1228  &handle->oidc->client_pkey,
1232  handle);
1233 }
#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:336
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 1237 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().

1238 {
1239  struct GNUNET_HashCode hc;
1240  char *value;
1241 
1242  GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1244  ->url_param_map,
1245  &hc))
1246  return NULL;
1247  value =
1249  if (NULL == value)
1250  return NULL;
1251  return GNUNET_strdup (value);
1252 }
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:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_YES
Definition: gnunet_common.h:77
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 1262 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().

1263 {
1264  struct RequestHandle *handle = cls;
1265  struct GNUNET_HashCode cache_key;
1266 
1267  char *expected_scope;
1268  char delimiter[] = " ";
1269  int number_of_ignored_parameter, iterator;
1270 
1271 
1272  // REQUIRED value: redirect_uri
1273  handle->oidc->redirect_uri =
1275  if (NULL == handle->oidc->redirect_uri)
1276  {
1278  handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1280  return;
1281  }
1282 
1283  // REQUIRED value: response_type
1284  handle->oidc->response_type =
1286  if (NULL == handle->oidc->response_type)
1287  {
1289  handle->edesc = GNUNET_strdup ("missing parameter response_type");
1291  return;
1292  }
1293 
1294  // REQUIRED value: scope
1295  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1296  if (NULL == handle->oidc->scope)
1297  {
1299  handle->edesc = GNUNET_strdup ("missing parameter scope");
1301  return;
1302  }
1303 
1304  // OPTIONAL value: nonce
1305  handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
1306 
1307  // TODO check other values if needed
1308  number_of_ignored_parameter =
1309  sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1310  for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1311  {
1313  strlen (OIDC_ignored_parameter_array[iterator]),
1314  &cache_key);
1315  if (GNUNET_YES ==
1317  ->url_param_map,
1318  &cache_key))
1319  {
1321  GNUNET_asprintf (&handle->edesc,
1322  "Server will not handle parameter: %s",
1323  OIDC_ignored_parameter_array[iterator]);
1325  return;
1326  }
1327  }
1328 
1329  // We only support authorization code flows.
1330  if (0 != strcmp (handle->oidc->response_type,
1332  {
1334  handle->edesc = GNUNET_strdup ("The authorization server does not support "
1335  "obtaining this authorization code.");
1337  return;
1338  }
1339 
1340  // Checks if scope contains 'openid'
1341  expected_scope = GNUNET_strdup (handle->oidc->scope);
1342  char *test;
1343  test = strtok (expected_scope, delimiter);
1344  while (NULL != test)
1345  {
1346  if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1347  break;
1348  test = strtok (NULL, delimiter);
1349  }
1350  if (NULL == test)
1351  {
1353  handle->edesc =
1354  GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1356  GNUNET_free (expected_scope);
1357  return;
1358  }
1359 
1360  GNUNET_free (expected_scope);
1361  if ((NULL == handle->oidc->login_identity) &&
1362  (GNUNET_NO == handle->oidc->user_cancelled))
1364  else
1366 }
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:78
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:48
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:1280
#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
Rest connection.
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:77
#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 1373 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().

1374 {
1375  struct RequestHandle *handle = cls;
1377 
1378  if (GNUNET_OK !=
1380  {
1381  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1382  return;
1383  }
1384  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1385  handle->tld = GNUNET_strdup (option + 1);
1386 }
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:75
#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:466
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 1397 of file plugin_rest_openid_connect.c.

References build_authz_response(), OIDC_Variables::client_id, OIDC_Variables::client_pkey, OIDC_Variables::code_challenge, 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_ERROR_TYPE_WARNING, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, EgoEntry::identifier, EgoEntry::next, RequestHandle::oidc, OIDC_CLIENT_ID_KEY, OIDC_CODE_CHALLENGE_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().

1400 {
1401  struct RequestHandle *handle = cls;
1402  struct EgoEntry *tmp_ego;
1403  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1405 
1407 
1408  // RECOMMENDED value: state - REQUIRED for answers
1409  handle->oidc->state = get_url_parameter_copy (handle, OIDC_STATE_KEY);
1410 
1411  // REQUIRED value: client_id
1413  if (NULL == handle->oidc->client_id)
1414  {
1416  handle->edesc = GNUNET_strdup ("missing parameter client_id");
1417  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1419  return;
1420  }
1421 
1422  // OPTIONAL value: code_challenge
1423  handle->oidc->code_challenge = get_url_parameter_copy (handle,
1425  if (NULL == handle->oidc->code_challenge)
1426  {
1428  "OAuth authorization request does not contain PKCE parameters!\n");
1429  }
1430 
1431  if (GNUNET_OK !=
1433  strlen (
1434  handle->oidc->client_id),
1435  &handle->oidc->client_pkey))
1436  {
1438  handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1439  "authorization code using this method.");
1440  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1442  return;
1443  }
1444 
1445  // If we know this identity, translated the corresponding TLD
1446  // TODO: We might want to have a reverse lookup functionality for TLDs?
1447  for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1448  {
1449  priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1451  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1452  {
1453  handle->tld = GNUNET_strdup (tmp_ego->identifier);
1454  handle->ego_entry = handle->ego_tail;
1455  }
1456  }
1457  if (NULL == handle->tld)
1459  if (NULL == handle->tld)
1460  handle->tld = GNUNET_strdup (handle->oidc->client_id);
1462 }
#define OIDC_CODE_CHALLENGE_KEY
OIDC PKCE code challenge.
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:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:1280
#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
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:239
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:466
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
char * code_challenge
The PKCE code_challenge.
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 1473 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().

1476 {
1477  struct MHD_Response *resp = GNUNET_REST_create_response ("");
1478  struct RequestHandle *handle = cls;
1479  struct GNUNET_HashCode cache_key;
1480  struct GNUNET_TIME_Absolute *current_time;
1481  struct GNUNET_TIME_Absolute *last_time;
1482  char *cookie;
1483  char *header_val;
1484  json_t *root;
1485  json_error_t error;
1486  json_t *identity;
1487  char term_data[handle->rest_handle->data_size + 1];
1488 
1489  term_data[handle->rest_handle->data_size] = '\0';
1490  GNUNET_memcpy (term_data,
1491  handle->rest_handle->data,
1492  handle->rest_handle->data_size);
1493  root = json_loads (term_data, JSON_DECODE_ANY, &error);
1494  identity = json_object_get (root, "identity");
1495  if (! json_is_string (identity))
1496  {
1498  "Error parsing json string from %s\n",
1499  term_data);
1500  handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1501  json_decref (root);
1503  return;
1504  }
1505  GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1506  GNUNET_asprintf (&header_val,
1507  "%s;Max-Age=%d",
1508  cookie,
1510  MHD_add_response_header (resp, "Set-Cookie", header_val);
1511  MHD_add_response_header (resp, "Access-Control-Allow-Methods", "POST");
1512  GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1513 
1514  if (0 != strcmp (json_string_value (identity), "Denied"))
1515  {
1516  current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1517  *current_time = GNUNET_TIME_relative_to_absolute (
1520  last_time =
1522  GNUNET_free_non_null (last_time);
1524  &cache_key,
1525  current_time,
1527  }
1528  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1529  GNUNET_free (cookie);
1530  GNUNET_free (header_val);
1531  json_decref (root);
1533 }
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:246
#define OIDC_COOKIE_EXPIRATION
OIDC cookie expiration (in seconds)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
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:1280
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:442
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
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:57
#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 1537 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().

1539 {
1540  struct GNUNET_HashCode cache_key;
1541  char *authorization;
1542  char *credentials;
1543  char *basic_authorization;
1544  char *client_id;
1545  char *pass;
1546  char *expected_pass;
1547 
1550  &cache_key);
1552  ->header_param_map,
1553  &cache_key))
1554  {
1556  handle->edesc = GNUNET_strdup ("missing authorization");
1557  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1558  return GNUNET_SYSERR;
1559  }
1560  authorization =
1562  &cache_key);
1563 
1564  // split header in "Basic" and [content]
1565  credentials = strtok (authorization, " ");
1566  if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1567  {
1569  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1570  return GNUNET_SYSERR;
1571  }
1572  credentials = strtok (NULL, " ");
1573  if (NULL == credentials)
1574  {
1576  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1577  return GNUNET_SYSERR;
1578  }
1579  GNUNET_STRINGS_base64_decode (credentials,
1580  strlen (credentials),
1581  (void **) &basic_authorization);
1582 
1583  if (NULL == basic_authorization)
1584  {
1586  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1587  return GNUNET_SYSERR;
1588  }
1589  client_id = strtok (basic_authorization, ":");
1590  if (NULL == client_id)
1591  {
1592  GNUNET_free_non_null (basic_authorization);
1594  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1595  return GNUNET_SYSERR;
1596  }
1597  pass = strtok (NULL, ":");
1598  if (NULL == pass)
1599  {
1600  GNUNET_free_non_null (basic_authorization);
1602  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1603  return GNUNET_SYSERR;
1604  }
1605 
1606  // check client password
1608  "reclaim-rest-plugin",
1609  "OIDC_CLIENT_SECRET",
1610  &expected_pass))
1611  {
1612  if (0 != strcmp (expected_pass, pass))
1613  {
1614  GNUNET_free_non_null (basic_authorization);
1615  GNUNET_free (expected_pass);
1617  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1618  return GNUNET_SYSERR;
1619  }
1620  GNUNET_free (expected_pass);
1621  }
1622  else
1623  {
1624  GNUNET_free_non_null (basic_authorization);
1626  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1627  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1628  return GNUNET_SYSERR;
1629  }
1630 
1631  // check client_id
1632  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1633  handle->ego_entry = handle->ego_entry->next)
1634  {
1635  if (0 == strcmp (handle->ego_entry->keystring, client_id))
1636  break;
1637  }
1638  if (NULL == handle->ego_entry)
1639  {
1640  GNUNET_free_non_null (basic_authorization);
1642  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1643  return GNUNET_SYSERR;
1644  }
1645  GNUNET_STRINGS_string_to_data (client_id,
1646  strlen (client_id),
1647  cid,
1648  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1649 
1650  GNUNET_free (basic_authorization);
1651  return GNUNET_OK;
1652 }
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
int response_code
Response code.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1920
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:76
#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:952
#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 1656 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().

1658 {
1659  struct EgoEntry *ego_entry;
1660  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1661 
1662  for (ego_entry = handle->ego_head; NULL != ego_entry;
1663  ego_entry = ego_entry->next)
1664  {
1665  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
1666  if (0 == GNUNET_memcmp (&pub_key, test_key))
1667  return ego_entry;
1668  }
1669  return NULL;
1670 }
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:568
#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 1674 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().

1677 {
1678  struct GNUNET_HashCode hc;
1679  struct GNUNET_RECLAIM_Ticket *ticketbuf;
1680 
1681  GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc);
1682  ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
1683  *ticketbuf = *ticket;
1687  &hc,
1688  ticketbuf,
1690 }
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:48
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:76
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 1701 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_ERROR_TYPE_WARNING, 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_CODE_VERIFIER_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().

1704 {
1705  struct RequestHandle *handle = cls;
1706  const struct EgoEntry *ego_entry;
1707  struct GNUNET_TIME_Relative expiration_time;
1710  struct GNUNET_CRYPTO_EcdsaPublicKey cid;
1711  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1712  struct GNUNET_HashCode cache_key;
1713  struct MHD_Response *resp;
1714  char *grant_type;
1715  char *code;
1716  char *json_response;
1717  char *id_token;
1718  char *access_token;
1719  char *jwt_secret;
1720  char *nonce;
1721  char *code_verifier;
1722 
1723  /*
1724  * Check Authorization
1725  */
1726  if (GNUNET_SYSERR == check_authorization (handle, &cid))
1727  {
1729  "OIDC authorization for token endpoint failed\n");
1731  return;
1732  }
1733 
1734  /*
1735  * Check parameter
1736  */
1737 
1738  // TODO Do not allow multiple equal parameter names
1739  // REQUIRED grant_type
1741  strlen (OIDC_GRANT_TYPE_KEY),
1742  &cache_key);
1743  grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY);
1744  if (NULL == grant_type)
1745  {
1747  handle->edesc = GNUNET_strdup ("missing parameter grant_type");
1748  handle->response_code = MHD_HTTP_BAD_REQUEST;
1750  return;
1751  }
1752 
1753  // Check parameter grant_type == "authorization_code"
1754  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
1755  {
1757  handle->response_code = MHD_HTTP_BAD_REQUEST;
1758  GNUNET_free (grant_type);
1760  return;
1761  }
1762  GNUNET_free (grant_type);
1763  // REQUIRED code
1764  code = get_url_parameter_copy (handle, OIDC_CODE_KEY);
1765  if (NULL == code)
1766  {
1768  handle->edesc = GNUNET_strdup ("missing parameter code");
1769  handle->response_code = MHD_HTTP_BAD_REQUEST;
1771  return;
1772  }
1773  ego_entry = find_ego (handle, &cid);
1774  if (NULL == ego_entry)
1775  {
1777  handle->edesc = GNUNET_strdup ("Unknown client");
1778  handle->response_code = MHD_HTTP_BAD_REQUEST;
1779  GNUNET_free (code);
1781  return;
1782  }
1783  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1784 
1785  // REQUIRED code verifier
1786  code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY);
1787  if (NULL == code_verifier)
1788  {
1790  "OAuth authorization request does not contain PKCE parameters!\n");
1791 
1792  }
1793 
1794  // decode code
1795  if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket,
1796  &cl, &nonce))
1797  {
1799  handle->edesc = GNUNET_strdup ("invalid code");
1800  handle->response_code = MHD_HTTP_BAD_REQUEST;
1801  GNUNET_free (code);
1803  return;
1804  }
1805  GNUNET_free (code);
1806 
1807  // create jwt
1809  "reclaim-rest-plugin",
1810  "expiration_time",
1811  &expiration_time))
1812  {
1814  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1815  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1817  return;
1818  }
1819 
1820 
1821  // TODO OPTIONAL acr,amr,azp
1823  "reclaim-rest-plugin",
1824  "jwt_secret",
1825  &jwt_secret))
1826  {
1828  handle->edesc = GNUNET_strdup ("No signing secret configured!");
1829  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1831  return;
1832  }
1833  id_token = OIDC_id_token_new (&ticket.audience,
1834  &ticket.identity,
1835  cl,
1836  &expiration_time,
1837  (NULL != nonce) ? nonce : NULL,
1838  jwt_secret);
1839  access_token = OIDC_access_token_new ();
1840  OIDC_build_token_response (access_token,
1841  id_token,
1842  &expiration_time,
1843  &json_response);
1844 
1845  persist_access_token (handle, access_token, &ticket);
1846  resp = GNUNET_REST_create_response (json_response);
1847  MHD_add_response_header (resp, "Cache-Control", "no-store");
1848  MHD_add_response_header (resp, "Pragma", "no-cache");
1849  MHD_add_response_header (resp, "Content-Type", "application/json");
1850  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1852  GNUNET_free (access_token);
1853  GNUNET_free (json_response);
1854  GNUNET_free (id_token);
1856 }
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:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:741
#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:48
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:1280
#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_CODE_VERIFIER_KEY
OIDC PKCE code verifier.
A 512-bit hashcode.
int response_code
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.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *ecdsa_priv, const char *code, const char *code_verifier, 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:598
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:769
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:57
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:119
#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 1863 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().

1866 {
1867  struct RequestHandle *handle = cls;
1868  char *tmp_value;
1869  json_t *value;
1870 
1871  if (NULL == identity)
1872  {
1874  return;
1875  }
1877  attr->data,
1878  attr->data_size);
1879  value = json_string (tmp_value);
1880  json_object_set_new (handle->oidc->response, attr->name, value);
1881  GNUNET_free (tmp_value);
1882 }
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:1280
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 1893 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().

1896 {
1897  // TODO expiration time
1898  struct RequestHandle *handle = cls;
1899  char delimiter[] = " ";
1900  struct GNUNET_HashCode cache_key;
1901  char *authorization;
1902  char *authorization_type;
1903  char *authorization_access_token;
1904  struct GNUNET_RECLAIM_Ticket *ticket;
1905  const struct EgoEntry *ego_entry;
1906  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1907 
1910  &cache_key);
1912  ->header_param_map,
1913  &cache_key))
1914  {
1916  handle->edesc = GNUNET_strdup ("No Access Token");
1917  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1919  return;
1920  }
1921  authorization =
1923  &cache_key);
1924 
1925  // split header in "Bearer" and access_token
1926  authorization = GNUNET_strdup (authorization);
1927  authorization_type = strtok (authorization, delimiter);
1928  if ((NULL == authorization_type) ||
1929  (0 != strcmp ("Bearer", authorization_type)))
1930  {
1932  handle->edesc = GNUNET_strdup ("No Access Token");
1933  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1935  GNUNET_free (authorization);
1936  return;
1937  }
1938  authorization_access_token = strtok (NULL, delimiter);
1939  if (NULL == authorization_access_token)
1940  {
1942  handle->edesc = GNUNET_strdup ("Access token missing");
1943  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1945  GNUNET_free (authorization);
1946  return;
1947  }
1948 
1949  GNUNET_CRYPTO_hash (authorization_access_token,
1950  strlen (authorization_access_token),
1951  &cache_key);
1952  if (GNUNET_NO ==
1954  &cache_key))
1955  {
1957  handle->edesc = GNUNET_strdup ("The access token expired");
1958  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1960  GNUNET_free (authorization);
1961  return;
1962  }
1963  ticket =
1965  GNUNET_assert (NULL != ticket);
1966  ego_entry = find_ego (handle, &ticket->audience);
1967  if (NULL == ego_entry)
1968  {
1970  handle->edesc = GNUNET_strdup ("The access token expired");
1971  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1973  GNUNET_free (authorization);
1974  return;
1975  }
1976 
1977  handle->idp = GNUNET_RECLAIM_connect (cfg);
1978  handle->oidc->response = json_object ();
1979  json_object_set_new (handle->oidc->response,
1980  "sub",
1981  json_string (ego_entry->keystring));
1982  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1983  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
1984  privkey,
1985  ticket,
1987  handle);
1988  GNUNET_free (authorization);
1989 }
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:555
#define GNUNET_NO
Definition: gnunet_common.h:78
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:48
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:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
int response_code
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:1101
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 1998 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().

1999 {
2001  static const struct GNUNET_REST_RequestHandler handlers[] =
2002  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
2003  { MHD_HTTP_METHOD_POST,
2005  &authorize_endpoint }, // url-encoded
2006  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
2007  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
2008  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2009  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2010  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
2012 
2013  if (GNUNET_NO ==
2014  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
2015  {
2016  handle->response_code = err.error_code;
2018  }
2019 }
#define GNUNET_NO
Definition: gnunet_common.h:78
#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:1280
#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:77
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
int response_code
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 2056 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().

2060 {
2061  struct RequestHandle *handle = cls;
2062  struct EgoEntry *ego_entry;
2064 
2065  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
2066  {
2067  handle->state = ID_REST_STATE_POST_INIT;
2068  init_cont (handle);
2069  return;
2070  }
2071  GNUNET_assert (NULL != ego);
2072  if (ID_REST_STATE_INIT == handle->state)
2073 
2074  {
2075  ego_entry = GNUNET_new (struct EgoEntry);
2078  ego_entry->ego = ego;
2079  ego_entry->identifier = GNUNET_strdup (identifier);
2081  handle->ego_tail,
2082  ego_entry);
2083  return;
2084  }
2085  /* Ego renamed or added */
2086  if (identifier != NULL)
2087  {
2088  for (ego_entry = handle->ego_head; NULL != ego_entry;
2089  ego_entry = ego_entry->next)
2090  {
2091  if (ego_entry->ego == ego)
2092  {
2093  /* Rename */
2094  GNUNET_free (ego_entry->identifier);
2095  ego_entry->identifier = GNUNET_strdup (identifier);
2096  break;
2097  }
2098  }
2099  if (NULL == ego_entry)
2100  {
2101  /* Add */
2102  ego_entry = GNUNET_new (struct EgoEntry);
2105  ego_entry->ego = ego;
2106  ego_entry->identifier = GNUNET_strdup (identifier);
2108  handle->ego_tail,
2109  ego_entry);
2110  }
2111  }
2112  else
2113  {
2114  /* Delete */
2115  for (ego_entry = handle->ego_head; NULL != ego_entry;
2116  ego_entry = ego_entry->next)
2117  {
2118  if (ego_entry->ego == ego)
2119  break;
2120  }
2121  if (NULL != ego_entry)
2123  handle->ego_tail,
2124  ego_entry);
2125  }
2126 }
#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:332
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:568
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 2130 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().

2133 {
2134  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2135 
2136  handle->oidc = GNUNET_new (struct OIDC_Variables);
2137  if (NULL == OIDC_cookie_jar_map)
2139  if (NULL == OIDC_access_token_map)
2142  handle->response_code = 0;
2144  handle->proc_cls = proc_cls;
2145  handle->proc = proc;
2146  handle->state = ID_REST_STATE_INIT;
2147  handle->rest_handle = rest_handle;
2148 
2149  handle->url = GNUNET_strdup (rest_handle->url);
2150  if (handle->url[strlen (handle->url) - 1] == '/')
2151  handle->url[strlen (handle->url) - 1] = '\0';
2152  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
2153  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
2154  handle->gns_handle = GNUNET_GNS_connect (cfg);
2156  handle->timeout_task =
2157  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
2158  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
2159 }
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:527
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define GNUNET_NO
Definition: gnunet_common.h:78
#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:1253
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
Desired timeout for the lookup (default is no 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:262
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
int response_code
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 2169 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().

2170 {
2171  static struct Plugin plugin;
2172  struct GNUNET_REST_Plugin *api;
2173 
2174  cfg = cls;
2175  if (NULL != plugin.cfg)
2176  return NULL; /* can only initialize once! */
2177  memset (&plugin, 0, sizeof(struct Plugin));
2178  plugin.cfg = cfg;
2179  api = GNUNET_new (struct GNUNET_REST_Plugin);
2180  api->cls = &plugin;
2184  "%s, %s, %s, %s, %s",
2185  MHD_HTTP_METHOD_GET,
2186  MHD_HTTP_METHOD_POST,
2187  MHD_HTTP_METHOD_PUT,
2188  MHD_HTTP_METHOD_DELETE,
2189  MHD_HTTP_METHOD_OPTIONS);
2190 
2192  _ ("OpenID Connect REST API initialized\n"));
2193  return api;
2194 }
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:181
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * name
Plugin name.
static char * plugin
Solver plugin name as string.
#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 2204 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.

2205 {
2206  struct GNUNET_REST_Plugin *api = cls;
2207  struct Plugin *plugin = api->cls;
2208 
2209  plugin->cfg = NULL;
2210 
2211  struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it;
2212  void *value = NULL;
2213  hashmap_it =
2215  while (GNUNET_YES ==
2216  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2217  GNUNET_free_non_null (value);
2220 
2221  hashmap_it =
2223  while (GNUNET_YES ==
2224  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2225  GNUNET_free_non_null (value);
2229  GNUNET_free (api);
2231  "OpenID Connect REST plugin is finished\n");
2232  return NULL;
2233 }
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 char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static char * plugin
Solver plugin name as string.
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:77
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 221 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 232 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 238 of file plugin_rest_openid_connect.c.

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg

The configuration handle.

Handle to our configuration.

Definition at line 243 of file plugin_rest_openid_connect.c.

◆ allow_methods

char* allow_methods
static

HTTP methods allows for this plugin.

Definition at line 248 of file plugin_rest_openid_connect.c.

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