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

Go to the source code of this file.

Data Structures

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

Macros

#define GNUNET_REST_API_NS_OIDC   "/openid"
 REST root namespace. More...
 
#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"
 Authorize endpoint. More...
 
#define GNUNET_REST_API_NS_TOKEN   "/openid/token"
 Token endpoint. More...
 
#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"
 UserInfo endpoint. More...
 
#define GNUNET_REST_API_NS_LOGIN   "/openid/login"
 Login namespace. More...
 
#define ID_REST_STATE_INIT   0
 State while collecting all egos. More...
 
#define ID_REST_STATE_POST_INIT   1
 Done collecting egos. More...
 
#define OIDC_GRANT_TYPE_KEY   "grant_type"
 OIDC grant_type key. More...
 
#define OIDC_GRANT_TYPE_VALUE   "authorization_code"
 OIDC grant_type key. More...
 
#define OIDC_CODE_KEY   "code"
 OIDC code key. More...
 
#define OIDC_RESPONSE_TYPE_KEY   "response_type"
 OIDC response_type key. More...
 
#define OIDC_CLIENT_ID_KEY   "client_id"
 OIDC client_id key. More...
 
#define OIDC_SCOPE_KEY   "scope"
 OIDC scope key. More...
 
#define OIDC_REDIRECT_URI_KEY   "redirect_uri"
 OIDC redirect_uri key. More...
 
#define OIDC_STATE_KEY   "state"
 OIDC state key. More...
 
#define OIDC_NONCE_KEY   "nonce"
 OIDC nonce key. More...
 
#define OIDC_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 510 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().

511 {
512  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
513  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
514  struct EgoEntry *ego_entry;
515  struct EgoEntry *ego_tmp;
516 
517  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
518  if (NULL != handle->timeout_task)
520  if (NULL != handle->identity_handle)
522  if (NULL != handle->attr_it)
524  if (NULL != handle->ticket_it)
526  if (NULL != handle->idp)
528  GNUNET_free_non_null(handle->url);
529  GNUNET_free_non_null(handle->tld);
532  GNUNET_free_non_null(handle->emsg);
533  GNUNET_free_non_null(handle->edesc);
534  if (NULL != handle->gns_op)
536  if (NULL != handle->gns_handle)
538 
539  if (NULL != handle->namestore_handle)
541  if (NULL != handle->oidc)
542  {
545  GNUNET_free_non_null(handle->oidc->nonce);
548  GNUNET_free_non_null(handle->oidc->scope);
549  GNUNET_free_non_null(handle->oidc->state);
550  json_decref(handle->oidc->response);
551  GNUNET_free(handle->oidc);
552  }
553  if (NULL != handle->attr_list)
554  {
555  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
556  {
557  claim_tmp = claim_entry;
558  claim_entry = claim_entry->next;
559  GNUNET_free(claim_tmp->claim);
560  GNUNET_free(claim_tmp);
561  }
562  GNUNET_free(handle->attr_list);
563  }
564  for (ego_entry = handle->ego_head; NULL != ego_entry;)
565  {
566  ego_tmp = ego_entry;
567  ego_entry = ego_entry->next;
568  GNUNET_free(ego_tmp->identifier);
569  GNUNET_free(ego_tmp->keystring);
570  GNUNET_free(ego_tmp);
571  }
572  GNUNET_free(handle);
573 }
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:814
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1203
#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:282
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:835
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:1015
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:306
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:956
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 576 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().

577 {
578  cleanup_handle(cls);
579 }
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 588 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().

589 {
590  struct RequestHandle *handle = cls;
591  struct MHD_Response *resp;
592  char *json_error;
593 
594  GNUNET_asprintf(&json_error,
595  "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
596  handle->emsg,
597  (NULL != handle->edesc) ? handle->edesc : "",
598  (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
599  (NULL != handle->oidc->state) ? handle->oidc->state : "",
600  (NULL != handle->oidc->state) ? "\"" : "");
601  if (0 == handle->response_code)
602  handle->response_code = MHD_HTTP_BAD_REQUEST;
603  resp = GNUNET_REST_create_response(json_error);
604  if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
605  MHD_add_response_header(resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
606  MHD_add_response_header(resp,
607  MHD_HTTP_HEADER_CONTENT_TYPE,
608  "application/json");
609  handle->proc(handle->proc_cls, resp, handle->response_code);
611  GNUNET_free(json_error);
612 }
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:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_userinfo_error()

static void do_userinfo_error ( void *  cls)
static

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

Cleans up everything

Parameters
clsthe struct RequestHandle

Definition at line 622 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().

623 {
624  struct RequestHandle *handle = cls;
625  struct MHD_Response *resp;
626  char *error;
627 
628  GNUNET_asprintf(&error,
629  "error=\"%s\", error_description=\"%s\"",
630  handle->emsg,
631  (NULL != handle->edesc) ? handle->edesc : "");
632  resp = GNUNET_REST_create_response("");
633  MHD_add_response_header(resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
634  handle->proc(handle->proc_cls, resp, handle->response_code);
636  GNUNET_free(error);
637 }
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:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_redirect_error()

static void do_redirect_error ( void *  cls)
static

Task run on error, sends error message and redirects.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 646 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().

647 {
648  struct RequestHandle *handle = cls;
649  struct MHD_Response *resp;
650  char *redirect;
651 
652  GNUNET_asprintf(&redirect,
653  "%s?error=%s&error_description=%s%s%s",
654  handle->oidc->redirect_uri,
655  handle->emsg,
656  handle->edesc,
657  (NULL != handle->oidc->state) ? "&state=" : "",
658  (NULL != handle->oidc->state) ? handle->oidc->state : "");
659  resp = GNUNET_REST_create_response("");
660  MHD_add_response_header(resp, "Location", redirect);
661  handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
663  GNUNET_free(redirect);
664 }
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:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_timeout()

static void do_timeout ( void *  cls)
static

Task run on timeout, sends error message.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 672 of file plugin_rest_openid_connect.c.

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

Referenced by rest_identity_process_request().

673 {
674  struct RequestHandle *handle = cls;
675 
676  handle->timeout_task = NULL;
677  do_error(handle);
678 }
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 686 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().

687 {
688  char *result_str;
689  struct RequestHandle *handle = cls;
690  struct MHD_Response *resp;
691 
692  result_str = json_dumps(handle->oidc->response, 0);
693 
694  resp = GNUNET_REST_create_response(result_str);
695  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
696  GNUNET_free(result_str);
697  cleanup_handle(handle);
698 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
json_t * response
The response JSON.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ options_cont()

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

Respond to OPTIONS request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 709 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().

712 {
713  struct MHD_Response *resp;
714  struct RequestHandle *handle = cls;
715 
716  // For now, independent of path return all options
717  resp = GNUNET_REST_create_response(NULL);
718  MHD_add_response_header(resp, "Access-Control-Allow-Methods", allow_methods);
719  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
720  cleanup_handle(handle);
721  return;
722 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
static char * allow_methods
HTTP methods allows for this plugin.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cookie_identity_interpretation()

static void cookie_identity_interpretation ( struct RequestHandle handle)
static

Interprets cookie header and pass its identity keystring to handle.

Definition at line 729 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().

730 {
731  struct GNUNET_HashCode cache_key;
732  char *cookies;
733  struct GNUNET_TIME_Absolute current_time, *relog_time;
734  char delimiter[] = "; ";
735  char *tmp_cookies;
736  char *token;
737  char *value;
738 
739  // gets identity of login try with cookie
741  strlen(OIDC_COOKIE_HEADER_KEY),
742  &cache_key);
745  &cache_key))
746  {
747  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
748  return;
749  }
750  // splits cookies and find 'Identity' cookie
751  tmp_cookies =
753  &cache_key);
754  cookies = GNUNET_strdup(tmp_cookies);
755  token = strtok(cookies, delimiter);
756  handle->oidc->user_cancelled = GNUNET_NO;
757  handle->oidc->login_identity = NULL;
758  if (NULL == token)
759  {
761  "Unable to parse cookie: %s\n",
762  cookies);
763  GNUNET_free(cookies);
764  return;
765  }
766 
767  while (NULL != token)
768  {
769  if (0 == strcmp(token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
770  {
771  handle->oidc->user_cancelled = GNUNET_YES;
772  GNUNET_free(cookies);
773  return;
774  }
775  if (NULL != strstr(token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
776  break;
777  token = strtok(NULL, delimiter);
778  }
779  if (NULL == token)
780  {
782  "No cookie value to process: %s\n",
783  cookies);
784  GNUNET_free(cookies);
785  return;
786  }
787  GNUNET_CRYPTO_hash(token, strlen(token), &cache_key);
788  if (GNUNET_NO ==
790  {
791  GNUNET_log(
793  "Found cookie `%s', but no corresponding expiration entry present...\n",
794  token);
795  GNUNET_free(cookies);
796  return;
797  }
798  relog_time =
800  current_time = GNUNET_TIME_absolute_get();
801  // 30 min after old login -> redirect to login
802  if (current_time.abs_value_us > relog_time->abs_value_us)
803  {
805  "Found cookie `%s', but it is expired.\n",
806  token);
807  GNUNET_free(cookies);
808  return;
809  }
810  value = strtok(token, OIDC_COOKIE_HEADER_INFORMATION_KEY);
811  GNUNET_assert(NULL != value);
812  handle->oidc->login_identity = GNUNET_strdup(value);
813  GNUNET_free(cookies);
814 }
#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:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h: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 820 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().

821 {
822  char *login_base_url;
823  char *new_redirect;
824  struct MHD_Response *resp;
825  struct RequestHandle *handle = cls;
826 
828  "reclaim-rest-plugin",
829  "address",
830  &login_base_url))
831  {
832  GNUNET_asprintf(&new_redirect,
833  "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
834  login_base_url,
836  handle->oidc->response_type,
838  handle->oidc->client_id,
840  handle->oidc->redirect_uri,
842  handle->oidc->scope,
844  (NULL != handle->oidc->state) ? handle->oidc->state : "",
846  (NULL != handle->oidc->code_challenge) ? handle->oidc->code_challenge : "",
848  (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
849  resp = GNUNET_REST_create_response("");
850  MHD_add_response_header(resp, "Location", new_redirect);
851  GNUNET_free(login_base_url);
852  }
853  else
854  {
856  handle->edesc = GNUNET_strdup("gnunet configuration failed");
857  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
859  return;
860  }
861  handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
862  GNUNET_free(new_redirect);
864 }
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:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * state
The OIDC state.
static void do_error(void *cls)
Task run on error, sends error message.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_SCOPE_KEY
OIDC scope key.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
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 870 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().

871 {
872  struct RequestHandle *handle = cls;
873 
875  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
877 }
#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:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
static void do_error(void *cls)
Task run on error, sends error message.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_ticket_issue_cb()

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

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

Otherwise redirects with error

Definition at line 885 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().

886 {
887  struct RequestHandle *handle = cls;
888  struct MHD_Response *resp;
889  char *ticket_str;
890  char *redirect_uri;
891  char *code_string;
892 
893  handle->idp_op = NULL;
894  if (NULL == ticket)
895  {
897  handle->edesc = GNUNET_strdup("Server cannot generate ticket.");
899  return;
900  }
901  handle->ticket = *ticket;
902  ticket_str =
904  sizeof(struct GNUNET_RECLAIM_Ticket));
905  // TODO change if more attributes are needed (see max_age)
906  code_string = OIDC_build_authz_code(&handle->priv_key,
907  &handle->ticket,
908  handle->attr_list,
909  handle->oidc->nonce,
910  handle->oidc->code_challenge);
911  if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
912  (NULL != handle->tld))
913  {
914  GNUNET_asprintf(&redirect_uri,
915  "%s.%s/%s?%s=%s&state=%s",
916  handle->redirect_prefix,
917  handle->tld,
918  handle->redirect_suffix,
919  handle->oidc->response_type,
920  code_string,
921  handle->oidc->state);
922  }
923  else
924  {
925  GNUNET_asprintf(&redirect_uri,
926  "%s?%s=%s&state=%s",
927  handle->oidc->redirect_uri,
928  handle->oidc->response_type,
929  code_string,
930  handle->oidc->state);
931  }
932  resp = GNUNET_REST_create_response("");
933  MHD_add_response_header(resp, "Location", redirect_uri);
934  handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
936  GNUNET_free(redirect_uri);
937  GNUNET_free(ticket_str);
938  GNUNET_free(code_string);
939 }
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:1264
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:56
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:921
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:454
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 942 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().

943 {
944  struct RequestHandle *handle = cls;
945 
946  handle->attr_it = NULL;
947  handle->ticket_it = NULL;
948  if (NULL == handle->attr_list->list_head)
949  {
951  handle->edesc = GNUNET_strdup("The requested scope is not available.");
953  return;
954  }
955  handle->idp_op = GNUNET_RECLAIM_ticket_issue(handle->idp,
956  &handle->priv_key,
957  &handle->oidc->client_pkey,
958  handle->attr_list,
960  handle);
961 }
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:1264
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:1046
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 968 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().

971 {
972  struct RequestHandle *handle = cls;
974  char *scope_variables;
975  char *scope_variable;
976  char delimiter[] = " ";
977 
978  if ((NULL == attr->name) || (NULL == attr->data))
979  {
981  return;
982  }
983 
984  scope_variables = GNUNET_strdup(handle->oidc->scope);
985  scope_variable = strtok(scope_variables, delimiter);
986  while (NULL != scope_variable)
987  {
988  if (0 == strcmp(attr->name, scope_variable))
989  break;
990  scope_variable = strtok(NULL, delimiter);
991  }
992  if (NULL == scope_variable)
993  {
995  GNUNET_free(scope_variables);
996  return;
997  }
998  GNUNET_free(scope_variables);
999 
1002  attr->type,
1003  attr->data,
1004  attr->data_size);
1005  le->claim->id = attr->id;
1006  le->claim->version = attr->version;
1008  handle->attr_list->list_tail,
1009  le);
1011 }
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:994
#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 1018 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().

1019 {
1020  struct RequestHandle *handle = cls;
1021  struct GNUNET_TIME_Absolute current_time;
1022  struct GNUNET_TIME_Absolute *relog_time;
1024  struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey;
1025  struct GNUNET_HashCode cache_key;
1026  char *identity_cookie;
1027 
1028  GNUNET_asprintf(&identity_cookie,
1029  "Identity=%s",
1030  handle->oidc->login_identity);
1031  GNUNET_CRYPTO_hash(identity_cookie, strlen(identity_cookie), &cache_key);
1032  GNUNET_free(identity_cookie);
1033  // No login time for identity -> redirect to login
1034  if (GNUNET_YES ==
1036  {
1037  relog_time =
1039  current_time = GNUNET_TIME_absolute_get();
1040  // 30 min after old login -> redirect to login
1041  if (current_time.abs_value_us <= relog_time->abs_value_us)
1042  {
1043  if (GNUNET_OK !=
1045  ->login_identity,
1046  strlen(
1047  handle->oidc
1048  ->login_identity),
1049  &pubkey))
1050  {
1052  handle->edesc =
1053  GNUNET_strdup("The cookie of a login identity is not valid");
1055  return;
1056  }
1057  // iterate over egos and compare their public key
1058  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1059  handle->ego_entry = handle->ego_entry->next)
1060  {
1061  GNUNET_IDENTITY_ego_get_public_key(handle->ego_entry->ego, &ego_pkey);
1062  if (0 == GNUNET_memcmp(&ego_pkey, &pubkey))
1063  {
1064  handle->priv_key =
1066  handle->idp = GNUNET_RECLAIM_connect(cfg);
1067  handle->attr_list =
1069  handle->attr_it =
1071  &handle->priv_key,
1073  handle,
1075  handle,
1077  handle);
1078  return;
1079  }
1080  }
1082  return;
1083  }
1084  }
1085 }
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:948
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:553
#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:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
#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:566
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h: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:774
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 1089 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().

1090 {
1091  struct RequestHandle *handle = cls;
1092  struct MHD_Response *resp;
1093  char *redirect_uri;
1094 
1095  if (GNUNET_YES == handle->oidc->user_cancelled)
1096  {
1097  if ((NULL != handle->redirect_prefix) &&
1098  (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1099  {
1100  GNUNET_asprintf(&redirect_uri,
1101  "%s.%s/%s?error=%s&error_description=%s&state=%s",
1102  handle->redirect_prefix,
1103  handle->tld,
1104  handle->redirect_suffix,
1105  "access_denied",
1106  "User denied access",
1107  handle->oidc->state);
1108  }
1109  else
1110  {
1111  GNUNET_asprintf(&redirect_uri,
1112  "%s?error=%s&error_description=%s&state=%s",
1113  handle->oidc->redirect_uri,
1114  "access_denied",
1115  "User denied access",
1116  handle->oidc->state);
1117  }
1118  resp = GNUNET_REST_create_response("");
1119  MHD_add_response_header(resp, "Location", redirect_uri);
1120  handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
1122  GNUNET_free(redirect_uri);
1123  return;
1124  }
1126 }
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:1264
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void code_redirect(void *cls)
Checks time and cookie and redirects accordingly.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_YES
Definition: gnunet_common.h: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 1130 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().

1133 {
1134  struct RequestHandle *handle = cls;
1135  char *tmp;
1136  char *tmp_key_str;
1137  char *pos;
1138  struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1139 
1140  handle->gns_op = NULL;
1141  if (0 == rd_count)
1142  {
1144  handle->edesc =
1145  GNUNET_strdup("Server cannot generate ticket, redirect uri not found.");
1147  return;
1148  }
1149  for (int i = 0; i < rd_count; i++)
1150  {
1151  if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1152  continue;
1153  if (0 != strncmp(rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1154  continue;
1155  tmp = GNUNET_strndup(rd[i].data, rd[i].data_size);
1156  if (NULL == strstr(tmp, handle->oidc->client_id))
1157  {
1159  "Redirect uri %s does not contain client_id %s\n",
1160  tmp,
1161  handle->oidc->client_id);
1162  }
1163  else
1164  {
1165  pos = strrchr(tmp, (unsigned char)'.');
1166  if (NULL == pos)
1167  {
1169  "Redirect uri %s contains client_id but is malformed\n",
1170  tmp);
1171  GNUNET_free(tmp);
1172  continue;
1173  }
1174  *pos = '\0';
1175  handle->redirect_prefix = GNUNET_strdup(tmp);
1176  tmp_key_str = pos + 1;
1177  pos = strchr(tmp_key_str, (unsigned char)'/');
1178  if (NULL == pos)
1179  {
1181  "Redirect uri %s contains client_id but is malformed\n",
1182  tmp);
1183  GNUNET_free(tmp);
1184  continue;
1185  }
1186  *pos = '\0';
1187  handle->redirect_suffix = GNUNET_strdup(pos + 1);
1188 
1189  GNUNET_STRINGS_string_to_data(tmp_key_str,
1190  strlen(tmp_key_str),
1191  &redirect_zone,
1192  sizeof(redirect_zone));
1193  }
1195  GNUNET_free(tmp);
1196  return;
1197  }
1199  handle->edesc =
1200  GNUNET_strdup("Server cannot generate ticket, redirect uri not found.");
1202 }
static void build_redirect(void *cls)
char * redirect_uri
The OIDC redirect uri.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
size_t data_size
Number of bytes in data.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Record type for reclaim OIDC redirect URIs.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:953
#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 1209 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().

1210 {
1211  struct RequestHandle *handle = cls;
1212 
1213  /* Lookup client redirect uri to verify request */
1214  handle->gns_op =
1215  GNUNET_GNS_lookup(handle->gns_handle,
1217  &handle->oidc->client_pkey,
1221  handle);
1222 }
#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:334
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 1225 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().

1226 {
1227  struct GNUNET_HashCode hc;
1228  char *value;
1229 
1230  GNUNET_CRYPTO_hash(key, strlen(key), &hc);
1232  ->url_param_map,
1233  &hc))
1234  return NULL;
1235  value =
1237  if (NULL == value)
1238  return NULL;
1239  return GNUNET_strdup(value);
1240 }
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static char * value
Value of the record to add/remove.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_YES
Definition: gnunet_common.h: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 1250 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().

1251 {
1252  struct RequestHandle *handle = cls;
1253  struct GNUNET_HashCode cache_key;
1254 
1255  char *expected_scope;
1256  char delimiter[] = " ";
1257  int number_of_ignored_parameter, iterator;
1258 
1259 
1260  // REQUIRED value: redirect_uri
1261  handle->oidc->redirect_uri =
1263  if (NULL == handle->oidc->redirect_uri)
1264  {
1266  handle->edesc = GNUNET_strdup("missing parameter redirect_uri");
1268  return;
1269  }
1270 
1271  // REQUIRED value: response_type
1272  handle->oidc->response_type =
1274  if (NULL == handle->oidc->response_type)
1275  {
1277  handle->edesc = GNUNET_strdup("missing parameter response_type");
1279  return;
1280  }
1281 
1282  // REQUIRED value: scope
1283  handle->oidc->scope = get_url_parameter_copy(handle, OIDC_SCOPE_KEY);
1284  if (NULL == handle->oidc->scope)
1285  {
1287  handle->edesc = GNUNET_strdup("missing parameter scope");
1289  return;
1290  }
1291 
1292  // OPTIONAL value: nonce
1293  handle->oidc->nonce = get_url_parameter_copy(handle, OIDC_NONCE_KEY);
1294 
1295  // TODO check other values if needed
1296  number_of_ignored_parameter =
1297  sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1298  for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1299  {
1301  strlen(OIDC_ignored_parameter_array[iterator]),
1302  &cache_key);
1303  if (GNUNET_YES ==
1305  ->url_param_map,
1306  &cache_key))
1307  {
1309  GNUNET_asprintf(&handle->edesc,
1310  "Server will not handle parameter: %s",
1311  OIDC_ignored_parameter_array[iterator]);
1313  return;
1314  }
1315  }
1316 
1317  // We only support authorization code flows.
1318  if (0 != strcmp(handle->oidc->response_type,
1320  {
1322  handle->edesc = GNUNET_strdup("The authorization server does not support "
1323  "obtaining this authorization code.");
1325  return;
1326  }
1327 
1328  // Checks if scope contains 'openid'
1329  expected_scope = GNUNET_strdup(handle->oidc->scope);
1330  char *test;
1331  test = strtok(expected_scope, delimiter);
1332  while (NULL != test)
1333  {
1334  if (0 == strcmp(OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1335  break;
1336  test = strtok(NULL, delimiter);
1337  }
1338  if (NULL == test)
1339  {
1341  handle->edesc =
1342  GNUNET_strdup("The requested scope is invalid, unknown, or malformed.");
1344  GNUNET_free(expected_scope);
1345  return;
1346  }
1347 
1348  GNUNET_free(expected_scope);
1349  if ((NULL == handle->oidc->login_identity) &&
1350  (GNUNET_NO == handle->oidc->user_cancelled))
1352  else
1354 }
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:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE
OIDC error key for unsupported response types.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
#define OIDC_ERROR_KEY_ACCESS_DENIED
OIDC error key for denied access.
#define OIDC_EXPECTED_AUTHORIZATION_SCOPE
OIDC expected scope part while authorizing.
static char * OIDC_ignored_parameter_array[]
OIDC ignored parameter array.
static void client_redirect(void *cls)
Initiate redirect back to client.
static void do_error(void *cls)
Task run on error, sends error message.
#define OIDC_SCOPE_KEY
OIDC scope key.
#define GNUNET_YES
Definition: gnunet_common.h: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 1360 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().

1361 {
1362  struct RequestHandle *handle = cls;
1364 
1365  if (GNUNET_OK !=
1367  {
1368  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1369  return;
1370  }
1371  if (0 == GNUNET_memcmp(&pkey, &handle->oidc->client_pkey))
1372  handle->tld = GNUNET_strdup(option + 1);
1373 }
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:468
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ authorize_endpoint()

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

Responds to authorization GET and url-encoded POST request.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 1383 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().

1386 {
1387  struct RequestHandle *handle = cls;
1388  struct EgoEntry *tmp_ego;
1389  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1391 
1393 
1394  // RECOMMENDED value: state - REQUIRED for answers
1395  handle->oidc->state = get_url_parameter_copy(handle, OIDC_STATE_KEY);
1396 
1397  // REQUIRED value: client_id
1399  if (NULL == handle->oidc->client_id)
1400  {
1402  handle->edesc = GNUNET_strdup("missing parameter client_id");
1403  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1405  return;
1406  }
1407 
1408  // OPTIONAL value: code_challenge
1410  if (NULL == handle->oidc->code_challenge)
1411  {
1413  "OAuth authorization request does not contain PKCE parameters!\n");
1414  }
1415 
1416  if (GNUNET_OK !=
1418  strlen(
1419  handle->oidc->client_id),
1420  &handle->oidc->client_pkey))
1421  {
1423  handle->edesc = GNUNET_strdup("The client is not authorized to request an "
1424  "authorization code using this method.");
1425  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1427  return;
1428  }
1429 
1430  // If we know this identity, translated the corresponding TLD
1431  // TODO: We might want to have a reverse lookup functionality for TLDs?
1432  for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1433  {
1434  priv_key = GNUNET_IDENTITY_ego_get_private_key(tmp_ego->ego);
1436  if (0 == GNUNET_memcmp(&pkey, &handle->oidc->client_pkey))
1437  {
1438  handle->tld = GNUNET_strdup(tmp_ego->identifier);
1439  handle->ego_entry = handle->ego_tail;
1440  }
1441  }
1442  if (NULL == handle->tld)
1444  if (NULL == handle->tld)
1445  handle->tld = GNUNET_strdup(handle->oidc->client_id);
1447 }
#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:553
#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:1264
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
char * tld
The tld for redirect.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
HTTP response code.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
static void build_authz_response(void *cls)
Iteration over all results finished, build final response.
char * state
The OIDC state.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
char * identifier
Ego Identifier.
static void do_error(void *cls)
Task run on error, sends error message.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#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 1457 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().

1460 {
1461  struct MHD_Response *resp = GNUNET_REST_create_response("");
1462  struct RequestHandle *handle = cls;
1463  struct GNUNET_HashCode cache_key;
1464  struct GNUNET_TIME_Absolute *current_time;
1465  struct GNUNET_TIME_Absolute *last_time;
1466  char *cookie;
1467  char *header_val;
1468  json_t *root;
1469  json_error_t error;
1470  json_t *identity;
1471  char term_data[handle->rest_handle->data_size + 1];
1472 
1473  term_data[handle->rest_handle->data_size] = '\0';
1474  GNUNET_memcpy(term_data,
1475  handle->rest_handle->data,
1476  handle->rest_handle->data_size);
1477  root = json_loads(term_data, JSON_DECODE_ANY, &error);
1478  identity = json_object_get(root, "identity");
1479  if (!json_is_string(identity))
1480  {
1482  "Error parsing json string from %s\n",
1483  term_data);
1484  handle->proc(handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1485  json_decref(root);
1487  return;
1488  }
1489  GNUNET_asprintf(&cookie, "Identity=%s", json_string_value(identity));
1490  GNUNET_asprintf(&header_val,
1491  "%s;Max-Age=%d",
1492  cookie,
1494  MHD_add_response_header(resp, "Set-Cookie", header_val);
1495  MHD_add_response_header(resp, "Access-Control-Allow-Methods", "POST");
1496  GNUNET_CRYPTO_hash(cookie, strlen(cookie), &cache_key);
1497 
1498  if (0 != strcmp(json_string_value(identity), "Denied"))
1499  {
1500  current_time = GNUNET_new(struct GNUNET_TIME_Absolute);
1501  *current_time = GNUNET_TIME_relative_to_absolute(
1504  last_time =
1506  GNUNET_free_non_null(last_time);
1508  &cache_key,
1509  current_time,
1511  }
1512  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
1513  GNUNET_free(cookie);
1514  GNUNET_free(header_val);
1515  json_decref(root);
1517 }
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:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
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:440
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
const char * data
The POST data.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void cleanup_handle_delayed(void *cls)
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_second_(void)
Return relative time of 1s.
Definition: time.c:183
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_authorization()

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

Definition at line 1520 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().

1522 {
1523  struct GNUNET_HashCode cache_key;
1524  char *authorization;
1525  char *credentials;
1526  char *basic_authorization;
1527  char *client_id;
1528  char *pass;
1529  char *expected_pass;
1530 
1533  &cache_key);
1535  ->header_param_map,
1536  &cache_key))
1537  {
1539  handle->edesc = GNUNET_strdup("missing authorization");
1540  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1541  return GNUNET_SYSERR;
1542  }
1543  authorization =
1545  &cache_key);
1546 
1547  // split header in "Basic" and [content]
1548  credentials = strtok(authorization, " ");
1549  if ((NULL == credentials) || (0 != strcmp("Basic", credentials)))
1550  {
1552  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1553  return GNUNET_SYSERR;
1554  }
1555  credentials = strtok(NULL, " ");
1556  if (NULL == credentials)
1557  {
1559  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1560  return GNUNET_SYSERR;
1561  }
1562  GNUNET_STRINGS_base64_decode(credentials,
1563  strlen(credentials),
1564  (void **)&basic_authorization);
1565 
1566  if (NULL == basic_authorization)
1567  {
1569  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1570  return GNUNET_SYSERR;
1571  }
1572  client_id = strtok(basic_authorization, ":");
1573  if (NULL == client_id)
1574  {
1575  GNUNET_free_non_null(basic_authorization);
1577  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1578  return GNUNET_SYSERR;
1579  }
1580  pass = strtok(NULL, ":");
1581  if (NULL == pass)
1582  {
1583  GNUNET_free_non_null(basic_authorization);
1585  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1586  return GNUNET_SYSERR;
1587  }
1588 
1589  // check client password
1591  "reclaim-rest-plugin",
1592  "OIDC_CLIENT_SECRET",
1593  &expected_pass))
1594  {
1595  if (0 != strcmp(expected_pass, pass))
1596  {
1597  GNUNET_free_non_null(basic_authorization);
1598  GNUNET_free(expected_pass);
1600  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1601  return GNUNET_SYSERR;
1602  }
1603  GNUNET_free(expected_pass);
1604  }
1605  else
1606  {
1607  GNUNET_free_non_null(basic_authorization);
1609  handle->edesc = GNUNET_strdup("gnunet configuration failed");
1610  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1611  return GNUNET_SYSERR;
1612  }
1613 
1614  // check client_id
1615  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1616  handle->ego_entry = handle->ego_entry->next)
1617  {
1618  if (0 == strcmp(handle->ego_entry->keystring, client_id))
1619  break;
1620  }
1621  if (NULL == handle->ego_entry)
1622  {
1623  GNUNET_free_non_null(basic_authorization);
1625  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1626  return GNUNET_SYSERR;
1627  }
1629  strlen(client_id),
1630  cid,
1631  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1632 
1633  GNUNET_free(basic_authorization);
1634  return GNUNET_OK;
1635 }
#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:44
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
int response_code
HTTP response code.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c: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:953
#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 1638 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().

1640 {
1641  struct EgoEntry *ego_entry;
1642  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1643 
1644  for (ego_entry = handle->ego_head; NULL != ego_entry;
1645  ego_entry = ego_entry->next)
1646  {
1647  GNUNET_IDENTITY_ego_get_public_key(ego_entry->ego, &pub_key);
1648  if (0 == GNUNET_memcmp(&pub_key, test_key))
1649  return ego_entry;
1650  }
1651  return NULL;
1652 }
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:566
#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 1655 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().

1658 {
1659  struct GNUNET_HashCode hc;
1660  struct GNUNET_RECLAIM_Ticket *ticketbuf;
1661 
1662  GNUNET_CRYPTO_hash(access_token, strlen(access_token), &hc);
1663  ticketbuf = GNUNET_new(struct GNUNET_RECLAIM_Ticket);
1664  *ticketbuf = *ticket;
1668  &hc,
1669  ticketbuf,
1671 }
The authorization ticket.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_SYSERR
Definition: gnunet_common.h: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 1681 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_Ticket::audience, check_authorization(), cleanup_handle_delayed(), do_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::emsg, find_ego(), get_url_parameter_copy(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_log, GNUNET_OK, GNUNET_RECLAIM_ATTRIBUTE_list_destroy(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_SYSERR, handle, GNUNET_RECLAIM_Ticket::identity, OIDC_access_token_new(), OIDC_build_token_response(), OIDC_CODE_KEY, OIDC_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().

1684 {
1685  struct RequestHandle *handle = cls;
1686  const struct EgoEntry *ego_entry;
1687  struct GNUNET_TIME_Relative expiration_time;
1690  struct GNUNET_CRYPTO_EcdsaPublicKey cid;
1691  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1692  struct GNUNET_HashCode cache_key;
1693  struct MHD_Response *resp;
1694  char *grant_type;
1695  char *code;
1696  char *json_response;
1697  char *id_token;
1698  char *access_token;
1699  char *jwt_secret;
1700  char *nonce;
1701  char *code_verifier;
1702 
1703  /*
1704  * Check Authorization
1705  */
1706  if (GNUNET_SYSERR == check_authorization(handle, &cid))
1707  {
1709  "OIDC authorization for token endpoint failed\n");
1711  return;
1712  }
1713 
1714  /*
1715  * Check parameter
1716  */
1717 
1718  // TODO Do not allow multiple equal parameter names
1719  // REQUIRED grant_type
1721  strlen(OIDC_GRANT_TYPE_KEY),
1722  &cache_key);
1723  grant_type = get_url_parameter_copy(handle, OIDC_GRANT_TYPE_KEY);
1724  if (NULL == grant_type)
1725  {
1727  handle->edesc = GNUNET_strdup("missing parameter grant_type");
1728  handle->response_code = MHD_HTTP_BAD_REQUEST;
1730  return;
1731  }
1732 
1733  // Check parameter grant_type == "authorization_code"
1734  if (0 != strcmp(OIDC_GRANT_TYPE_VALUE, grant_type))
1735  {
1737  handle->response_code = MHD_HTTP_BAD_REQUEST;
1738  GNUNET_free(grant_type);
1740  return;
1741  }
1742  GNUNET_free(grant_type);
1743  // REQUIRED code
1744  code = get_url_parameter_copy(handle, OIDC_CODE_KEY);
1745  if (NULL == code)
1746  {
1748  handle->edesc = GNUNET_strdup("missing parameter code");
1749  handle->response_code = MHD_HTTP_BAD_REQUEST;
1751  return;
1752  }
1753  ego_entry = find_ego(handle, &cid);
1754  if (NULL == ego_entry)
1755  {
1757  handle->edesc = GNUNET_strdup("Unknown client");
1758  handle->response_code = MHD_HTTP_BAD_REQUEST;
1759  GNUNET_free(code);
1761  return;
1762  }
1763  privkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
1764 
1765  // REQUIRED code verifier
1766  code_verifier = get_url_parameter_copy(handle, OIDC_CODE_VERIFIER_KEY);
1767  if (NULL == code_verifier)
1768  {
1770  handle->edesc = GNUNET_strdup("missing parameter code_verifier");
1771  handle->response_code = MHD_HTTP_BAD_REQUEST;
1773  return;
1774  }
1775 
1776  // decode code
1777  if (GNUNET_OK != OIDC_parse_authz_code(privkey, code, code_verifier, &ticket, &cl, &nonce))
1778  {
1780  handle->edesc = GNUNET_strdup("invalid code");
1781  handle->response_code = MHD_HTTP_BAD_REQUEST;
1782  GNUNET_free(code);
1784  return;
1785  }
1786  GNUNET_free(code);
1787 
1788  // create jwt
1790  "reclaim-rest-plugin",
1791  "expiration_time",
1792  &expiration_time))
1793  {
1795  handle->edesc = GNUNET_strdup("gnunet configuration failed");
1796  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1798  return;
1799  }
1800 
1801 
1802  // TODO OPTIONAL acr,amr,azp
1804  "reclaim-rest-plugin",
1805  "jwt_secret",
1806  &jwt_secret))
1807  {
1809  handle->edesc = GNUNET_strdup("No signing secret configured!");
1810  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1812  return;
1813  }
1814  id_token = OIDC_id_token_new(&ticket.audience,
1815  &ticket.identity,
1816  cl,
1817  &expiration_time,
1818  (NULL != nonce) ? nonce : NULL,
1819  jwt_secret);
1820  access_token = OIDC_access_token_new();
1821  OIDC_build_token_response(access_token,
1822  id_token,
1823  &expiration_time,
1824  &json_response);
1825 
1826  persist_access_token(handle, access_token, &ticket);
1827  resp = GNUNET_REST_create_response(json_response);
1828  MHD_add_response_header(resp, "Cache-Control", "no-store");
1829  MHD_add_response_header(resp, "Pragma", "no-cache");
1830  MHD_add_response_header(resp, "Content-Type", "application/json");
1831  handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
1833  GNUNET_free(access_token);
1834  GNUNET_free(json_response);
1835  GNUNET_free(id_token);
1837 }
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:553
#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:724
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
The request handle.
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE
OIDC error key for unsupported grants.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_RECLAIM_ATTRIBUTE_list_destroy(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Destroy claim list.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
#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
HTTP response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
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:588
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:751
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:56
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_GRANT_TYPE_VALUE
OIDC grant_type key.
char * OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:115
#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 1843 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().

1846 {
1847  struct RequestHandle *handle = cls;
1848  char *tmp_value;
1849  json_t *value;
1850 
1851  if (NULL == identity)
1852  {
1854  return;
1855  }
1857  attr->data,
1858  attr->data_size);
1859  value = json_string(tmp_value);
1860  json_object_set_new(handle->oidc->response, attr->name, value);
1861  GNUNET_free(tmp_value);
1862 }
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:1264
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 1872 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().

1875 {
1876  // TODO expiration time
1877  struct RequestHandle *handle = cls;
1878  char delimiter[] = " ";
1879  struct GNUNET_HashCode cache_key;
1880  char *authorization;
1881  char *authorization_type;
1882  char *authorization_access_token;
1883  struct GNUNET_RECLAIM_Ticket *ticket;
1884  const struct EgoEntry *ego_entry;
1885  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1886 
1889  &cache_key);
1891  ->header_param_map,
1892  &cache_key))
1893  {
1895  handle->edesc = GNUNET_strdup("No Access Token");
1896  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1898  return;
1899  }
1900  authorization =
1902  &cache_key);
1903 
1904  // split header in "Bearer" and access_token
1905  authorization = GNUNET_strdup(authorization);
1906  authorization_type = strtok(authorization, delimiter);
1907  if ((NULL == authorization_type) ||
1908  (0 != strcmp("Bearer", authorization_type)))
1909  {
1911  handle->edesc = GNUNET_strdup("No Access Token");
1912  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1914  GNUNET_free(authorization);
1915  return;
1916  }
1917  authorization_access_token = strtok(NULL, delimiter);
1918  if (NULL == authorization_access_token)
1919  {
1921  handle->edesc = GNUNET_strdup("Access token missing");
1922  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1924  GNUNET_free(authorization);
1925  return;
1926  }
1927 
1928  GNUNET_CRYPTO_hash(authorization_access_token,
1929  strlen(authorization_access_token),
1930  &cache_key);
1931  if (GNUNET_NO ==
1933  &cache_key))
1934  {
1936  handle->edesc = GNUNET_strdup("The access token expired");
1937  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1939  GNUNET_free(authorization);
1940  return;
1941  }
1942  ticket =
1944  GNUNET_assert(NULL != ticket);
1945  ego_entry = find_ego(handle, &ticket->audience);
1946  if (NULL == ego_entry)
1947  {
1949  handle->edesc = GNUNET_strdup("The access token expired");
1950  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1952  GNUNET_free(authorization);
1953  return;
1954  }
1955 
1956  handle->idp = GNUNET_RECLAIM_connect(cfg);
1957  handle->oidc->response = json_object();
1958  json_object_set_new(handle->oidc->response,
1959  "sub",
1960  json_string(ego_entry->keystring));
1961  privkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
1962  handle->idp_op = GNUNET_RECLAIM_ticket_consume(handle->idp,
1963  privkey,
1964  ticket,
1966  handle);
1967  GNUNET_free(authorization);
1968 }
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:553
#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:44
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1264
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
A 512-bit hashcode.
int response_code
HTTP response code.
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
static void consume_ticket(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
Collects claims and stores them in handle.
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, const struct GNUNET_RECLAIM_Ticket *ticket, GNUNET_RECLAIM_AttributeResult cb, void *cb_cls)
Consumes an issued ticket.
Definition: reclaim_api.c:1095
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:774
#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 1977 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().

1978 {
1980  static const struct GNUNET_REST_RequestHandler handlers[] =
1981  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
1982  { MHD_HTTP_METHOD_POST,
1984  &authorize_endpoint }, // url-encoded
1985  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
1986  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
1987  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
1988  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
1989  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
1991 
1992  if (GNUNET_NO ==
1993  GNUNET_REST_handle_request(handle->rest_handle, handlers, &err, handle))
1994  {
1995  handle->response_code = err.error_code;
1997  }
1998 }
#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:1264
#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:75
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
static void login_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Combines an identity with a login time and responds OK to login request.
static void userinfo_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to userinfo GET and url-encoded POST request.
#define GNUNET_REST_API_NS_LOGIN
Login namespace.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static void authorize_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to authorization GET and url-encoded POST request.
static void do_error(void *cls)
Task run on error, sends error message.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void token_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to token url-encoded POST request.
#define GNUNET_REST_API_NS_USERINFO
UserInfo endpoint.
#define GNUNET_REST_API_NS_TOKEN
Token endpoint.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ list_ego()

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

If listing is enabled, prints information about the egos.

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

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

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

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

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

Definition at line 2034 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().

2038 {
2039  struct RequestHandle *handle = cls;
2040  struct EgoEntry *ego_entry;
2042 
2043  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
2044  {
2045  handle->state = ID_REST_STATE_POST_INIT;
2046  init_cont(handle);
2047  return;
2048  }
2049  GNUNET_assert(NULL != ego);
2050  if (ID_REST_STATE_INIT == handle->state)
2051 
2052  {
2053  ego_entry = GNUNET_new(struct EgoEntry);
2056  ego_entry->ego = ego;
2057  ego_entry->identifier = GNUNET_strdup(identifier);
2059  handle->ego_tail,
2060  ego_entry);
2061  return;
2062  }
2063  /* Ego renamed or added */
2064  if (identifier != NULL)
2065  {
2066  for (ego_entry = handle->ego_head; NULL != ego_entry;
2067  ego_entry = ego_entry->next)
2068  {
2069  if (ego_entry->ego == ego)
2070  {
2071  /* Rename */
2072  GNUNET_free(ego_entry->identifier);
2073  ego_entry->identifier = GNUNET_strdup(identifier);
2074  break;
2075  }
2076  }
2077  if (NULL == ego_entry)
2078  {
2079  /* Add */
2080  ego_entry = GNUNET_new(struct EgoEntry);
2083  ego_entry->ego = ego;
2084  ego_entry->identifier = GNUNET_strdup(identifier);
2086  handle->ego_tail,
2087  ego_entry);
2088  }
2089  }
2090  else
2091  {
2092  /* Delete */
2093  for (ego_entry = handle->ego_head; NULL != ego_entry;
2094  ego_entry = ego_entry->next)
2095  {
2096  if (ego_entry->ego == ego)
2097  break;
2098  }
2099  if (NULL != ego_entry)
2101  handle->ego_tail,
2102  ego_entry);
2103  }
2104 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_CRYPTO_EddsaPrivateKey * pk
Private key of this peer.
struct EgoEntry * ego_tail
Ego list.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
The request handle.
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void init_cont(struct RequestHandle *handle)
Handle rest request.
int state
The processing state.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:334
char * keystring
Public key string.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:566
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 2107 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().

2110 {
2111  struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
2112 
2113  handle->oidc = GNUNET_new(struct OIDC_Variables);
2114  if (NULL == OIDC_cookie_jar_map)
2116  if (NULL == OIDC_access_token_map)
2119  handle->response_code = 0;
2121  handle->proc_cls = proc_cls;
2122  handle->proc = proc;
2123  handle->state = ID_REST_STATE_INIT;
2124  handle->rest_handle = rest_handle;
2125 
2126  handle->url = GNUNET_strdup(rest_handle->url);
2127  if (handle->url[strlen(handle->url) - 1] == '/')
2128  handle->url[strlen(handle->url) - 1] = '\0';
2129  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
2130  handle->identity_handle = GNUNET_IDENTITY_connect(cfg, &list_ego, handle);
2131  handle->gns_handle = GNUNET_GNS_connect(cfg);
2133  handle->timeout_task =
2134  GNUNET_SCHEDULER_add_delayed(handle->timeout, &do_timeout, handle);
2135  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
2136 }
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:525
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:1237
static void do_timeout(void *cls)
Task run on timeout, sends error message.
const char * url
The url as string.
struct GNUNET_TIME_Relative timeout
Timeout.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:260
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
int response_code
HTTP response code.
int state
The processing state.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define ID_REST_STATE_INIT
State while collecting all egos.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
struct GNUNET_NAMESTORE_Handle * namestore_handle
Handle to NAMESTORE.
char * url
The url.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_rest_openid_connect_init()

void* libgnunet_plugin_rest_openid_connect_init ( void *  cls)

Entry point for the plugin.

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

Definition at line 2145 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().

2146 {
2147  static struct Plugin plugin;
2148  struct GNUNET_REST_Plugin *api;
2149 
2150  cfg = cls;
2151  if (NULL != plugin.cfg)
2152  return NULL; /* can only initialize once! */
2153  memset(&plugin, 0, sizeof(struct Plugin));
2154  plugin.cfg = cfg;
2155  api = GNUNET_new(struct GNUNET_REST_Plugin);
2156  api->cls = &plugin;
2160  "%s, %s, %s, %s, %s",
2161  MHD_HTTP_METHOD_GET,
2162  MHD_HTTP_METHOD_POST,
2163  MHD_HTTP_METHOD_PUT,
2164  MHD_HTTP_METHOD_DELETE,
2165  MHD_HTTP_METHOD_OPTIONS);
2166 
2168  _("OpenID Connect REST API initialized\n"));
2169  return api;
2170 }
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
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * name
Plugin name.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
Here is the call graph for this function:

◆ libgnunet_plugin_rest_openid_connect_done()

void* libgnunet_plugin_rest_openid_connect_done ( void *  cls)

Exit point from the plugin.

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

Definition at line 2180 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.

2181 {
2182  struct GNUNET_REST_Plugin *api = cls;
2183  struct Plugin *plugin = api->cls;
2184 
2185  plugin->cfg = NULL;
2186 
2187  struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it;
2188  void *value = NULL;
2189  hashmap_it =
2191  while (GNUNET_YES ==
2192  GNUNET_CONTAINER_multihashmap_iterator_next(hashmap_it, NULL, value))
2193  GNUNET_free_non_null(value);
2196 
2197  hashmap_it =
2199  while (GNUNET_YES ==
2200  GNUNET_CONTAINER_multihashmap_iterator_next(hashmap_it, NULL, value))
2201  GNUNET_free_non_null(value);
2205  GNUNET_free(api);
2207  "OpenID Connect REST plugin is finished\n");
2208  return NULL;
2209 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
void * cls
The closure of the plugin.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct returned by the initialization function of the plugin
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h: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().