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

Go to the source code of this file.

Data Structures

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

Macros

#define GNUNET_REST_API_NS_OIDC   "/openid"
 REST root namespace. More...
 
#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"
 Authorize endpoint. More...
 
#define GNUNET_REST_API_NS_TOKEN   "/openid/token"
 Token endpoint. More...
 
#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"
 UserInfo endpoint. More...
 
#define GNUNET_REST_API_NS_LOGIN   "/openid/login"
 Login namespace. More...
 
#define ID_REST_STATE_INIT   0
 State while collecting all egos. More...
 
#define ID_REST_STATE_POST_INIT   1
 Done collecting egos. More...
 
#define OIDC_GRANT_TYPE_KEY   "grant_type"
 OIDC grant_type key. More...
 
#define OIDC_GRANT_TYPE_VALUE   "authorization_code"
 OIDC grant_type key. More...
 
#define OIDC_CODE_KEY   "code"
 OIDC code key. More...
 
#define OIDC_RESPONSE_TYPE_KEY   "response_type"
 OIDC response_type key. More...
 
#define OIDC_CLIENT_ID_KEY   "client_id"
 OIDC client_id key. More...
 
#define OIDC_SCOPE_KEY   "scope"
 OIDC scope key. More...
 
#define OIDC_REDIRECT_URI_KEY   "redirect_uri"
 OIDC redirect_uri key. More...
 
#define OIDC_STATE_KEY   "state"
 OIDC state key. More...
 
#define OIDC_NONCE_KEY   "nonce"
 OIDC nonce key. More...
 
#define OIDC_CLAIMS_KEY   "claims"
 OIDC claims 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, const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 Collects all attributes/references 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, const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
 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 authorize_endpoint(), 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_CLAIMS_KEY

#define OIDC_CLAIMS_KEY   "claims"

OIDC claims key.

Definition at line 125 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 130 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 135 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 140 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 145 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 150 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 155 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 160 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 165 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 170 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 175 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 180 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 185 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 190 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 195 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 205 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 210 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 215 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 220 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 524 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::attest, 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, EgoEntry::next, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::next, OIDC_Variables::nonce, RequestHandle::oidc, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, OIDC_Variables::redirect_uri, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::reference, 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().

525 {
526  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
527  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
528  struct EgoEntry *ego_entry;
529  struct EgoEntry *ego_tmp;
530 
531  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
532  if (NULL != handle->timeout_task)
534  if (NULL != handle->identity_handle)
536  if (NULL != handle->attr_it)
538  if (NULL != handle->ticket_it)
540  if (NULL != handle->idp)
541  GNUNET_RECLAIM_disconnect (handle->idp);
542  GNUNET_free_non_null (handle->url);
543  GNUNET_free_non_null (handle->tld);
546  GNUNET_free_non_null (handle->emsg);
547  GNUNET_free_non_null (handle->edesc);
548  if (NULL != handle->gns_op)
550  if (NULL != handle->gns_handle)
552 
553  if (NULL != handle->namestore_handle)
555  if (NULL != handle->oidc)
556  {
559  GNUNET_free_non_null (handle->oidc->nonce);
562  GNUNET_free_non_null (handle->oidc->scope);
563  GNUNET_free_non_null (handle->oidc->state);
564  json_decref (handle->oidc->response);
565  GNUNET_free (handle->oidc);
566  }
567  if (NULL != handle->attr_list)
568  {
569  for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
570  {
571  claim_tmp = claim_entry;
572  claim_entry = claim_entry->next;
573  if (NULL != claim_tmp->claim)
574  GNUNET_free (claim_tmp->claim);
575  if (NULL != claim_tmp->attest)
576  GNUNET_free (claim_tmp->attest);
577  if (NULL != claim_tmp->reference)
578  GNUNET_free (claim_tmp->reference);
579  GNUNET_free (claim_tmp);
580  }
581  GNUNET_free (handle->attr_list);
582  }
583  for (ego_entry = handle->ego_head; NULL != ego_entry;)
584  {
585  ego_tmp = ego_entry;
586  ego_entry = ego_entry->next;
587  GNUNET_free (ego_tmp->identifier);
588  GNUNET_free (ego_tmp->keystring);
589  GNUNET_free (ego_tmp);
590  }
591  GNUNET_free (handle);
592 }
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_RECLAIM_ATTESTATION_REFERENCE * reference
The reference.
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:1044
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1613
#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.
struct GNUNET_RECLAIM_ATTESTATION_Claim * attest
The attestation claim.
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:290
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
char * tld
The tld for redirect.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:837
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
char * state
The OIDC state.
char * identifier
Ego Identifier.
char * redirect_prefix
The redirect prefix.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
struct EgoEntry * ego_head
Ego list.
void GNUNET_RECLAIM_get_attributes_stop(struct GNUNET_RECLAIM_AttributeIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1425
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:314
json_t * response
The response JSON.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * next
DLL.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NAMESTORE_Handle * namestore_handle
Handle to NAMESTORE.
char * login_identity
The identity chosen by the user to login.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
char * url
The url.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_handle_delayed()

static void cleanup_handle_delayed ( void *  cls)
static

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

597 {
598  cleanup_handle (cls);
599 }
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 608 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().

609 {
610  struct RequestHandle *handle = cls;
611  struct MHD_Response *resp;
612  char *json_error;
613 
614  GNUNET_asprintf (&json_error,
615  "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
616  handle->emsg,
617  (NULL != handle->edesc) ? handle->edesc : "",
618  (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
619  (NULL != handle->oidc->state) ? handle->oidc->state : "",
620  (NULL != handle->oidc->state) ? "\"" : "");
621  if (0 == handle->response_code)
622  handle->response_code = MHD_HTTP_BAD_REQUEST;
623  resp = GNUNET_REST_create_response (json_error);
624  if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
625  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
626  MHD_add_response_header (resp,
627  MHD_HTTP_HEADER_CONTENT_TYPE,
628  "application/json");
629  handle->proc (handle->proc_cls, resp, handle->response_code);
631  GNUNET_free (json_error);
632 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
Response code.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_userinfo_error()

static void do_userinfo_error ( void *  cls)
static

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

Cleans up everything

Parameters
clsthe struct RequestHandle

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

643 {
644  struct RequestHandle *handle = cls;
645  struct MHD_Response *resp;
646  char *error;
647 
648  GNUNET_asprintf (&error,
649  "error=\"%s\", error_description=\"%s\"",
650  handle->emsg,
651  (NULL != handle->edesc) ? handle->edesc : "");
652  resp = GNUNET_REST_create_response ("");
653  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
654  handle->proc (handle->proc_cls, resp, handle->response_code);
656  GNUNET_free (error);
657 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
Response code.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_redirect_error()

static void do_redirect_error ( void *  cls)
static

Task run on error, sends error message and redirects.

Cleans up everything.

Parameters
clsthe struct RequestHandle

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

667 {
668  struct RequestHandle *handle = cls;
669  struct MHD_Response *resp;
670  char *redirect;
671 
672  GNUNET_asprintf (&redirect,
673  "%s?error=%s&error_description=%s%s%s",
674  handle->oidc->redirect_uri,
675  handle->emsg,
676  handle->edesc,
677  (NULL != handle->oidc->state) ? "&state=" : "",
678  (NULL != handle->oidc->state) ? handle->oidc->state : "");
679  resp = GNUNET_REST_create_response ("");
680  MHD_add_response_header (resp, "Location", redirect);
681  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
683  GNUNET_free (redirect);
684 }
char * redirect_uri
The OIDC redirect uri.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_timeout()

static void do_timeout ( void *  cls)
static

Task run on timeout, sends error message.

Cleans up everything.

Parameters
clsthe struct RequestHandle

Definition at line 693 of file plugin_rest_openid_connect.c.

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

Referenced by rest_identity_process_request().

694 {
695  struct RequestHandle *handle = cls;
696 
697  handle->timeout_task = NULL;
698  do_error (handle);
699 }
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 708 of file plugin_rest_openid_connect.c.

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

Referenced by consume_ticket().

709 {
710  char *result_str;
711  struct RequestHandle *handle = cls;
712  struct MHD_Response *resp;
713 
714  result_str = json_dumps (handle->oidc->response, 0);
715  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"ID-Token: %s\n",result_str);
716  resp = GNUNET_REST_create_response (result_str);
717  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
718  GNUNET_free (result_str);
719  cleanup_handle (handle);
720 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_log(kind,...)
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 731 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().

734 {
735  struct MHD_Response *resp;
736  struct RequestHandle *handle = cls;
737 
738  // For now, independent of path return all options
739  resp = GNUNET_REST_create_response (NULL);
740  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
741  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
742  cleanup_handle (handle);
743  return;
744 }
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * proc_cls
The closure of the result processor.
The request handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
static char * allow_methods
HTTP methods allows for this plugin.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cookie_identity_interpretation()

static void cookie_identity_interpretation ( struct RequestHandle handle)
static

Interprets cookie header and pass its identity keystring to handle.

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

752 {
753  struct GNUNET_HashCode cache_key;
754  char *cookies;
755  struct GNUNET_TIME_Absolute current_time, *relog_time;
756  char delimiter[] = "; ";
757  char *tmp_cookies;
758  char *token;
759  char *value;
760 
761  // gets identity of login try with cookie
763  strlen (OIDC_COOKIE_HEADER_KEY),
764  &cache_key);
767  &cache_key))
768  {
769  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
770  return;
771  }
772  // splits cookies and find 'Identity' cookie
773  tmp_cookies =
775  &cache_key);
776  cookies = GNUNET_strdup (tmp_cookies);
777  token = strtok (cookies, delimiter);
778  handle->oidc->user_cancelled = GNUNET_NO;
779  handle->oidc->login_identity = NULL;
780  if (NULL == token)
781  {
783  "Unable to parse cookie: %s\n",
784  cookies);
785  GNUNET_free (cookies);
786  return;
787  }
788 
789  while (NULL != token)
790  {
791  if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
792  {
793  handle->oidc->user_cancelled = GNUNET_YES;
794  GNUNET_free (cookies);
795  return;
796  }
797  if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
798  break;
799  token = strtok (NULL, delimiter);
800  }
801  if (NULL == token)
802  {
804  "No cookie value to process: %s\n",
805  cookies);
806  GNUNET_free (cookies);
807  return;
808  }
809  GNUNET_CRYPTO_hash (token, strlen (token), &cache_key);
810  if (GNUNET_NO ==
812  {
813  GNUNET_log (
815  "Found cookie `%s', but no corresponding expiration entry present...\n",
816  token);
817  GNUNET_free (cookies);
818  return;
819  }
820  relog_time =
822  current_time = GNUNET_TIME_absolute_get ();
823  // 30 min after old login -> redirect to login
824  if (current_time.abs_value_us > relog_time->abs_value_us)
825  {
827  "Found cookie `%s', but it is expired.\n",
828  token);
829  GNUNET_free (cookies);
830  return;
831  }
832  value = strtok (token, OIDC_COOKIE_HEADER_INFORMATION_KEY);
833  GNUNET_assert (NULL != value);
834  handle->oidc->login_identity = GNUNET_strdup (value);
835  GNUNET_free (cookies);
836 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:86
#define OIDC_COOKIE_HEADER_INFORMATION_KEY
OIDC cookie header information key.
#define OIDC_COOKIE_HEADER_ACCESS_DENIED
OIDC cookie header if user cancelled.
int user_cancelled
User cancelled authorization/login.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint64_t abs_value_us
The actual value.
struct OIDC_Variables * oidc
OIDC variables.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:85
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 843 of file plugin_rest_openid_connect.c.

References OIDC_Variables::claims, 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_CLAIMS_KEY, 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().

844 {
845  char *login_base_url;
846  char *new_redirect;
847  struct MHD_Response *resp;
848  struct RequestHandle *handle = cls;
849 
851  "reclaim-rest-plugin",
852  "address",
853  &login_base_url))
854  {
855  GNUNET_asprintf (&new_redirect,
856  "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
857  login_base_url,
859  handle->oidc->response_type,
861  handle->oidc->client_id,
863  handle->oidc->redirect_uri,
865  handle->oidc->scope,
867  (NULL != handle->oidc->state) ? handle->oidc->state : "",
869  (NULL != handle->oidc->code_challenge) ?
870  handle->oidc->code_challenge : "",
872  (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "",
874  (NULL != handle->oidc->claims) ? handle->oidc->claims :
875  "");
876  resp = GNUNET_REST_create_response ("");
877  MHD_add_response_header (resp, "Location", new_redirect);
878  GNUNET_free (login_base_url);
879  }
880  else
881  {
883  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
884  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
886  return;
887  }
888  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
889  GNUNET_free (new_redirect);
891 }
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 OIDC_CLAIMS_KEY
OIDC claims key.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
#define OIDC_STATE_KEY
OIDC state key.
The request handle.
char * response_type
The OIDC response type.
#define OIDC_RESPONSE_TYPE_KEY
OIDC response_type key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
Response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * claims
The OIDC claims.
char * state
The OIDC state.
static void do_error(void *cls)
Task run on error, sends error message.
static void cleanup_handle_delayed(void *cls)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_SCOPE_KEY
OIDC scope key.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
char * code_challenge
The PKCE code_challenge.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_iteration_error()

static void oidc_iteration_error ( void *  cls)
static

Does internal server error when iteration failed.

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

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

◆ oidc_ticket_issue_cb()

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

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

Otherwise redirects with error

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

914 {
915  struct RequestHandle *handle = cls;
916  struct MHD_Response *resp;
917  char *ticket_str;
918  char *redirect_uri;
919  char *code_string;
920 
921  handle->idp_op = NULL;
922  if (NULL == ticket)
923  {
925  handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
927  return;
928  }
929  handle->ticket = *ticket;
930  ticket_str =
932  sizeof(struct GNUNET_RECLAIM_Ticket));
933  // TODO change if more attributes are needed (see max_age)
934  code_string = OIDC_build_authz_code (&handle->priv_key,
935  &handle->ticket,
936  handle->attr_list,
937  handle->oidc->nonce,
938  handle->oidc->code_challenge);
939  if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
940  (NULL != handle->tld))
941  {
942  GNUNET_asprintf (&redirect_uri,
943  "%s.%s/%s?%s=%s&state=%s",
944  handle->redirect_prefix,
945  handle->tld,
946  handle->redirect_suffix,
947  handle->oidc->response_type,
948  code_string,
949  handle->oidc->state);
950  }
951  else
952  {
953  GNUNET_asprintf (&redirect_uri,
954  "%s?%s=%s&state=%s",
955  handle->oidc->redirect_uri,
956  handle->oidc->response_type,
957  code_string,
958  handle->oidc->state);
959  }
960  resp = GNUNET_REST_create_response ("");
961  MHD_add_response_header (resp, "Location", redirect_uri);
962  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
964  GNUNET_free (redirect_uri);
965  GNUNET_free (ticket_str);
966  GNUNET_free (code_string);
967 }
char * redirect_uri
The OIDC redirect uri.
The authorization ticket.
char * nonce
The OIDC nonce.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * response_type
The OIDC response type.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
char * redirect_prefix
The redirect prefix.
struct GNUNET_RECLAIM_Ticket ticket
A ticket.
char * redirect_suffix
The redirect suffix.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:920
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const char *nonce_str, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:573
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 971 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().

972 {
973  struct RequestHandle *handle = cls;
974 
975  handle->attr_it = NULL;
976  handle->ticket_it = NULL;
977  if (NULL == handle->attr_list->list_head)
978  {
980  handle->edesc = GNUNET_strdup ("The requested scope is not available.");
982  return;
983  }
984  handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp,
985  &handle->priv_key,
986  &handle->oidc->client_pkey,
987  handle->attr_list,
989  handle);
990 }
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
static void oidc_ticket_issue_cb(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
Issues ticket and redirects to relying party with the authorization code as parameter.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
char * emsg
Error response message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, GNUNET_RECLAIM_TicketCallback cb, void *cb_cls)
Issues a ticket to a relying party.
Definition: reclaim_api.c:1456
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,
const struct GNUNET_RECLAIM_ATTESTATION_Claim attest,
const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE reference 
)
static

Collects all attributes/references for an ego if in scope parameter.

Definition at line 997 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::attest, RequestHandle::attr_it, RequestHandle::attr_list, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::claim, GNUNET_RECLAIM_ATTRIBUTE_Claim::data, GNUNET_RECLAIM_ATTESTATION_Claim::data, GNUNET_RECLAIM_ATTRIBUTE_Claim::data_size, GNUNET_RECLAIM_ATTESTATION_Claim::data_size, GNUNET_RECLAIM_ATTRIBUTE_Claim::flag, GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_new, GNUNET_RECLAIM_ATTESTATION_claim_new(), GNUNET_RECLAIM_ATTESTATION_reference_new(), GNUNET_RECLAIM_ATTRIBUTE_claim_new(), GNUNET_RECLAIM_get_attributes_next(), GNUNET_strdup, handle, GNUNET_RECLAIM_ATTRIBUTE_Claim::id, GNUNET_RECLAIM_ATTESTATION_Claim::id, GNUNET_RECLAIM_ATTESTATION_REFERENCE::id, GNUNET_RECLAIM_ATTESTATION_REFERENCE::id_attest, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_head, GNUNET_RECLAIM_ATTRIBUTE_ClaimList::list_tail, GNUNET_RECLAIM_ATTRIBUTE_Claim::name, GNUNET_RECLAIM_ATTESTATION_Claim::name, GNUNET_RECLAIM_ATTESTATION_REFERENCE::name, RequestHandle::oidc, GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry::reference, GNUNET_RECLAIM_ATTESTATION_REFERENCE::reference_value, OIDC_Variables::scope, GNUNET_RECLAIM_ATTRIBUTE_Claim::type, and GNUNET_RECLAIM_ATTESTATION_Claim::type.

Referenced by code_redirect().

1002 {
1003  struct RequestHandle *handle = cls;
1005  char *scope_variables;
1006  char *scope_variable;
1007  char delimiter[] = " ";
1008 
1009  if ((NULL == attr) && (NULL == reference))
1010  {
1012  return;
1013  }
1014  if (NULL != reference)
1015  {
1016  if ((NULL == reference->name) || (NULL == reference->reference_value))
1017  {
1018  return;
1019  }
1020  scope_variables = GNUNET_strdup (handle->oidc->scope);
1021  scope_variable = strtok (scope_variables, delimiter);
1022  while (NULL != scope_variable)
1023  {
1024  if (0 == strcmp (reference->name, scope_variable))
1025  break;
1026  scope_variable = strtok (NULL, delimiter);
1027  }
1028  if (NULL == scope_variable)
1029  {
1030  GNUNET_free (scope_variables);
1031  return;
1032  }
1033  GNUNET_free (scope_variables);
1037  le->claim = NULL;
1038  le->reference = NULL;
1040  attest->type,
1041  attest->data,
1042  attest->data_size);
1043  le->attest->id = attest->id;
1044  le2->attest = NULL;
1045  le2->claim = NULL;
1047  reference->
1048  reference_value);
1049  le2->reference->id = reference->id;
1050  le2->reference->id_attest = reference->id_attest;
1052  handle->attr_list->list_tail,
1053  le);
1055  handle->attr_list->list_tail,
1056  le2);
1057  }
1058  else if (NULL != attr)
1059  {
1060  if ((NULL == attr->name) || (NULL == attr->data))
1061  {
1063  return;
1064  }
1065  scope_variables = GNUNET_strdup (handle->oidc->scope);
1066  scope_variable = strtok (scope_variables, delimiter);
1067  while (NULL != scope_variable)
1068  {
1069  if (0 == strcmp (attr->name, scope_variable))
1070  break;
1071  scope_variable = strtok (NULL, delimiter);
1072  }
1073  if (NULL == scope_variable)
1074  {
1076  GNUNET_free (scope_variables);
1077  return;
1078  }
1079  GNUNET_free (scope_variables);
1081  le->reference = NULL;
1082  le->attest = NULL;
1084  attr->type,
1085  attr->data,
1086  attr->data_size);
1087  le->claim->id = attr->id;
1088  le->claim->flag = attr->flag;
1089 
1091  handle->attr_list->list_tail,
1092  le);
1094  }
1095 }
const char * name
The name of the attribute.
struct GNUNET_RECLAIM_ATTRIBUTE_Claim * claim
The attribute claim.
struct GNUNET_RECLAIM_ATTESTATION_Claim * GNUNET_RECLAIM_ATTESTATION_claim_new(const char *attr_name, uint32_t type, const void *data, size_t data_size)
Create a new attestation.
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.
struct GNUNET_RECLAIM_ATTESTATION_REFERENCE * reference
The reference.
const char * reference_value
The name of the attribute/attestation reference value.
#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:1404
uint64_t id_attest
Referenced ID of Attestation.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct OIDC_Variables * oidc
OIDC variables.
struct GNUNET_RECLAIM_ATTESTATION_Claim * attest
The attestation claim.
The request handle.
const void * data
Binary value stored as attribute value.
struct GNUNET_RECLAIM_ATTESTATION_REFERENCE * GNUNET_RECLAIM_ATTESTATION_reference_new(const char *attr_name, const char *ref_value)
Create a new attestation reference.
size_t data_size
Number of bytes in data.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
const char * name
The name of the attribute.
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.
const char * name
The name of the attribute/attestation reference value.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry * list_head
List head.
#define GNUNET_free(ptr)
Wrapper around free.
const void * data
Binary value stored as attribute value.
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 1102 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().

1103 {
1104  struct RequestHandle *handle = cls;
1105  struct GNUNET_TIME_Absolute current_time;
1106  struct GNUNET_TIME_Absolute *relog_time;
1108  struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey;
1109  struct GNUNET_HashCode cache_key;
1110  char *identity_cookie;
1111 
1112  GNUNET_asprintf (&identity_cookie,
1113  "Identity=%s",
1114  handle->oidc->login_identity);
1115  GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1116  GNUNET_free (identity_cookie);
1117  // No login time for identity -> redirect to login
1118  if (GNUNET_YES ==
1120  {
1121  relog_time =
1123  current_time = GNUNET_TIME_absolute_get ();
1124  // 30 min after old login -> redirect to login
1125  if (current_time.abs_value_us <= relog_time->abs_value_us)
1126  {
1127  if (GNUNET_OK !=
1129  ->login_identity,
1130  strlen (
1131  handle->oidc
1132  ->login_identity),
1133  &pubkey))
1134  {
1136  handle->edesc =
1137  GNUNET_strdup ("The cookie of a login identity is not valid");
1139  return;
1140  }
1141  // iterate over egos and compare their public key
1142  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1143  handle->ego_entry = handle->ego_entry->next)
1144  {
1145  GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1146  if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1147  {
1148  handle->priv_key =
1150  handle->idp = GNUNET_RECLAIM_connect (cfg);
1151  handle->attr_list =
1153  handle->attr_it =
1155  &handle->priv_key,
1157  handle,
1159  handle,
1161  handle);
1162  return;
1163  }
1164  }
1166  return;
1167  }
1168  }
1169 }
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:1358
static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey
Public key of the zone to look in.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
static void oidc_attr_collect(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
Collects all attributes/references for an ego if in scope parameter.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void login_redirect(void *cls)
Redirects to login page stored in configuration file.
uint64_t abs_value_us
The actual value.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define OIDC_ERROR_KEY_INVALID_COOKIE
OIDC error key for invalid cookies.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList * attr_list
Attribute claim list.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:568
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:357
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:85
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:1004
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 1173 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().

1174 {
1175  struct RequestHandle *handle = cls;
1176  struct MHD_Response *resp;
1177  char *redirect_uri;
1178 
1179  if (GNUNET_YES == handle->oidc->user_cancelled)
1180  {
1181  if ((NULL != handle->redirect_prefix) &&
1182  (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1183  {
1184  GNUNET_asprintf (&redirect_uri,
1185  "%s.%s/%s?error=%s&error_description=%s&state=%s",
1186  handle->redirect_prefix,
1187  handle->tld,
1188  handle->redirect_suffix,
1189  "access_denied",
1190  "User denied access",
1191  handle->oidc->state);
1192  }
1193  else
1194  {
1195  GNUNET_asprintf (&redirect_uri,
1196  "%s?error=%s&error_description=%s&state=%s",
1197  handle->oidc->redirect_uri,
1198  "access_denied",
1199  "User denied access",
1200  handle->oidc->state);
1201  }
1202  resp = GNUNET_REST_create_response ("");
1203  MHD_add_response_header (resp, "Location", redirect_uri);
1204  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1206  GNUNET_free (redirect_uri);
1207  return;
1208  }
1210 }
char * redirect_uri
The OIDC redirect uri.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
int user_cancelled
User cancelled authorization/login.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void code_redirect(void *cls)
Checks time and cookie and redirects accordingly.
char * state
The OIDC state.
static void cleanup_handle_delayed(void *cls)
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_YES
Definition: gnunet_common.h:85
#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 1214 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().

1217 {
1218  struct RequestHandle *handle = cls;
1219  char *tmp;
1220  char *tmp_key_str;
1221  char *pos;
1222  struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1223 
1224  handle->gns_op = NULL;
1225  if (0 == rd_count)
1226  {
1228  handle->edesc =
1229  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1231  return;
1232  }
1233  for (int i = 0; i < rd_count; i++)
1234  {
1235  if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1236  continue;
1237  if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1238  continue;
1239  tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1240  if (NULL == strstr (tmp, handle->oidc->client_id))
1241  {
1243  "Redirect uri %s does not contain client_id %s\n",
1244  tmp,
1245  handle->oidc->client_id);
1246  }
1247  else
1248  {
1249  pos = strrchr (tmp, (unsigned char) '.');
1250  if (NULL == pos)
1251  {
1253  "Redirect uri %s contains client_id but is malformed\n",
1254  tmp);
1255  GNUNET_free (tmp);
1256  continue;
1257  }
1258  *pos = '\0';
1259  handle->redirect_prefix = GNUNET_strdup (tmp);
1260  tmp_key_str = pos + 1;
1261  pos = strchr (tmp_key_str, (unsigned char) '/');
1262  if (NULL == pos)
1263  {
1265  "Redirect uri %s contains client_id but is malformed\n",
1266  tmp);
1267  GNUNET_free (tmp);
1268  continue;
1269  }
1270  *pos = '\0';
1271  handle->redirect_suffix = GNUNET_strdup (pos + 1);
1272 
1273  GNUNET_STRINGS_string_to_data (tmp_key_str,
1274  strlen (tmp_key_str),
1275  &redirect_zone,
1276  sizeof(redirect_zone));
1277  }
1279  GNUNET_free (tmp);
1280  return;
1281  }
1283  handle->edesc =
1284  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1286 }
static void build_redirect(void *cls)
char * redirect_uri
The OIDC redirect uri.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
size_t data_size
Number of bytes in data.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Record type for reclaim OIDC redirect URIs.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
char * redirect_prefix
The redirect prefix.
char * redirect_suffix
The redirect suffix.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
uint32_t data
The data value.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:952
#define GNUNET_free(ptr)
Wrapper around free.
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_redirect()

static void client_redirect ( void *  cls)
static

Initiate redirect back to client.

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

1294 {
1295  struct RequestHandle *handle = cls;
1296 
1297  /* Lookup client redirect uri to verify request */
1298  handle->gns_op =
1299  GNUNET_GNS_lookup (handle->gns_handle,
1301  &handle->oidc->client_pkey,
1305  handle);
1306 }
#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:412
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 1310 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().

1311 {
1312  struct GNUNET_HashCode hc;
1313  char *value;
1314 
1315  GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1317  ->url_param_map,
1318  &hc))
1319  return NULL;
1320  value =
1322  if (NULL == value)
1323  return NULL;
1324  return GNUNET_strdup (value);
1325 }
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
static char * value
Value of the record to add/remove.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_YES
Definition: gnunet_common.h:85
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 1335 of file plugin_rest_openid_connect.c.

References OIDC_Variables::claims, 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_CLAIMS_KEY, 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().

1336 {
1337  struct RequestHandle *handle = cls;
1338  struct GNUNET_HashCode cache_key;
1339 
1340  char *expected_scope;
1341  char delimiter[] = " ";
1342  int number_of_ignored_parameter, iterator;
1343 
1344 
1345  // REQUIRED value: redirect_uri
1346  handle->oidc->redirect_uri =
1348  if (NULL == handle->oidc->redirect_uri)
1349  {
1351  handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1353  return;
1354  }
1355 
1356  // REQUIRED value: response_type
1357  handle->oidc->response_type =
1359  if (NULL == handle->oidc->response_type)
1360  {
1362  handle->edesc = GNUNET_strdup ("missing parameter response_type");
1364  return;
1365  }
1366 
1367  // REQUIRED value: scope
1368  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1369  if (NULL == handle->oidc->scope)
1370  {
1372  handle->edesc = GNUNET_strdup ("missing parameter scope");
1374  return;
1375  }
1376 
1377  // OPTIONAL value: nonce
1378  handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
1379 
1380  // OPTIONAL value: claims
1381  handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
1382 
1383  // TODO check other values if needed
1384  number_of_ignored_parameter =
1385  sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1386  for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1387  {
1389  strlen (OIDC_ignored_parameter_array[iterator]),
1390  &cache_key);
1391  if (GNUNET_YES ==
1393  ->url_param_map,
1394  &cache_key))
1395  {
1397  GNUNET_asprintf (&handle->edesc,
1398  "Server will not handle parameter: %s",
1399  OIDC_ignored_parameter_array[iterator]);
1401  return;
1402  }
1403  }
1404 
1405  // We only support authorization code flows.
1406  if (0 != strcmp (handle->oidc->response_type,
1408  {
1410  handle->edesc = GNUNET_strdup ("The authorization server does not support "
1411  "obtaining this authorization code.");
1413  return;
1414  }
1415 
1416  // Checks if scope contains 'openid'
1417  expected_scope = GNUNET_strdup (handle->oidc->scope);
1418  char *test;
1419  test = strtok (expected_scope, delimiter);
1420  while (NULL != test)
1421  {
1422  if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1423  break;
1424  test = strtok (NULL, delimiter);
1425  }
1426  if (NULL == test)
1427  {
1429  handle->edesc =
1430  GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1432  GNUNET_free (expected_scope);
1433  return;
1434  }
1435 
1436  GNUNET_free (expected_scope);
1437  if ((NULL == handle->oidc->login_identity) &&
1438  (GNUNET_NO == handle->oidc->user_cancelled))
1440  else
1442 }
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 OIDC_CLAIMS_KEY
OIDC claims key.
#define GNUNET_NO
Definition: gnunet_common.h:86
int user_cancelled
User cancelled authorization/login.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static void login_redirect(void *cls)
Redirects to login page stored in configuration file.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
char * response_type
The OIDC response type.
#define OIDC_RESPONSE_TYPE_KEY
OIDC response_type key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * emsg
Error response message.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE
OIDC error key for unsupported response types.
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
char * claims
The OIDC claims.
#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:85
#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 1449 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().

1450 {
1451  struct RequestHandle *handle = cls;
1453 
1454  if (GNUNET_OK !=
1456  {
1457  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1458  return;
1459  }
1460  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1461  handle->tld = GNUNET_strdup (option + 1);
1462 }
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:83
#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:357
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 1473 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_DEBUG, 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_SCOPE_KEY, OIDC_STATE_KEY, RequestHandle::response_code, OIDC_Variables::scope, OIDC_Variables::state, RequestHandle::tld, and tld_iter().

Referenced by init_cont().

1476 {
1477  struct RequestHandle *handle = cls;
1478  struct EgoEntry *tmp_ego;
1479  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1481 
1483 
1484  // RECOMMENDED value: state - REQUIRED for answers
1485  handle->oidc->state = get_url_parameter_copy (handle, OIDC_STATE_KEY);
1486 
1487  // REQUIRED value: client_id
1489  if (NULL == handle->oidc->client_id)
1490  {
1492  handle->edesc = GNUNET_strdup ("missing parameter client_id");
1493  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1495  return;
1496  }
1497 
1498  // OPTIONAL value: code_challenge
1499  handle->oidc->code_challenge = get_url_parameter_copy (handle,
1501  if (NULL == handle->oidc->code_challenge)
1502  {
1504  "OAuth authorization request does not contain PKCE parameters!\n");
1505  }
1506 
1507  if (GNUNET_OK !=
1509  strlen (
1510  handle->oidc->client_id),
1511  &handle->oidc->client_pkey))
1512  {
1514  handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1515  "authorization code using this method.");
1516  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1518  return;
1519  }
1520 
1521  // If we know this identity, translated the corresponding TLD
1522  // TODO: We might want to have a reverse lookup functionality for TLDs?
1523  for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1524  {
1525  priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1527  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1528  {
1529  handle->tld = GNUNET_strdup (tmp_ego->identifier);
1530  handle->ego_entry = handle->ego_tail;
1531  }
1532  }
1533  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1535  handle->oidc->scope));
1536  if (NULL == handle->tld)
1538  if (NULL == handle->tld)
1539  handle->tld = GNUNET_strdup (handle->oidc->client_id);
1541 }
char * scope
The list of oidc scopes.
#define OIDC_CODE_CHALLENGE_KEY
OIDC PKCE code challenge.
static char * pkey
Public key of the zone to look in, in ASCII.
struct EgoEntry * ego_tail
Ego list.
void GNUNET_CONFIGURATION_iterate_section_values(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, GNUNET_CONFIGURATION_Iterator iter, void *iter_cls)
Iterate over values of a section in the configuration.
static void cookie_identity_interpretation(struct RequestHandle *handle)
Interprets cookie header and pass its identity keystring to handle.
#define OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT
OIDC error key for unauthorized clients.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
static void tld_iter(void *cls, const char *section, const char *option, const char *value)
Iterate over tlds in config.
Private ECC key encoded for transmission.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
#define OIDC_STATE_KEY
OIDC state key.
The request handle.
The ego list.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
char * tld
The tld for redirect.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
int response_code
Response code.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:172
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:357
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_SCOPE_KEY
OIDC scope key.
#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 1552 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().

1555 {
1556  struct MHD_Response *resp = GNUNET_REST_create_response ("");
1557  struct RequestHandle *handle = cls;
1558  struct GNUNET_HashCode cache_key;
1559  struct GNUNET_TIME_Absolute *current_time;
1560  struct GNUNET_TIME_Absolute *last_time;
1561  char *cookie;
1562  char *header_val;
1563  json_t *root;
1564  json_error_t error;
1565  json_t *identity;
1566  char term_data[handle->rest_handle->data_size + 1];
1567 
1568  term_data[handle->rest_handle->data_size] = '\0';
1569  GNUNET_memcpy (term_data,
1570  handle->rest_handle->data,
1571  handle->rest_handle->data_size);
1572  root = json_loads (term_data, JSON_DECODE_ANY, &error);
1573  identity = json_object_get (root, "identity");
1574  if (! json_is_string (identity))
1575  {
1577  "Error parsing json string from %s\n",
1578  term_data);
1579  handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1580  json_decref (root);
1582  return;
1583  }
1584  GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1585  GNUNET_asprintf (&header_val,
1586  "%s;Max-Age=%d",
1587  cookie,
1589  MHD_add_response_header (resp, "Set-Cookie", header_val);
1590  MHD_add_response_header (resp, "Access-Control-Allow-Methods", "POST");
1591  GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1592 
1593  if (0 != strcmp (json_string_value (identity), "Denied"))
1594  {
1595  current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1596  *current_time = GNUNET_TIME_relative_to_absolute (
1599  last_time =
1601  GNUNET_free_non_null (last_time);
1603  &cache_key,
1604  current_time,
1606  }
1607  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1608  GNUNET_free (cookie);
1609  GNUNET_free (header_val);
1610  json_decref (root);
1612 }
If a value with the given key exists, replace it.
size_t data_size
The POST data size.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define OIDC_COOKIE_EXPIRATION
OIDC cookie expiration (in seconds)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void * proc_cls
The closure of the result processor.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:442
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
const char * data
The POST data.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void cleanup_handle_delayed(void *cls)
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_second_(void)
Return relative time of 1s.
Definition: time.c:183
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_authorization()

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

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

1618 {
1619  struct GNUNET_HashCode cache_key;
1620  char *authorization;
1621  char *credentials;
1622  char *basic_authorization;
1623  char *client_id;
1624  char *pass;
1625  char *expected_pass;
1626 
1629  &cache_key);
1631  ->header_param_map,
1632  &cache_key))
1633  {
1635  handle->edesc = GNUNET_strdup ("missing authorization");
1636  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1637  return GNUNET_SYSERR;
1638  }
1639  authorization =
1641  &cache_key);
1642 
1643  // split header in "Basic" and [content]
1644  credentials = strtok (authorization, " ");
1645  if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1646  {
1648  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1649  return GNUNET_SYSERR;
1650  }
1651  credentials = strtok (NULL, " ");
1652  if (NULL == credentials)
1653  {
1655  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1656  return GNUNET_SYSERR;
1657  }
1658  GNUNET_STRINGS_base64_decode (credentials,
1659  strlen (credentials),
1660  (void **) &basic_authorization);
1661 
1662  if (NULL == basic_authorization)
1663  {
1665  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1666  return GNUNET_SYSERR;
1667  }
1668  client_id = strtok (basic_authorization, ":");
1669  if (NULL == client_id)
1670  {
1671  GNUNET_free_non_null (basic_authorization);
1673  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1674  return GNUNET_SYSERR;
1675  }
1676  pass = strtok (NULL, ":");
1677  if (NULL == pass)
1678  {
1679  GNUNET_free_non_null (basic_authorization);
1681  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1682  return GNUNET_SYSERR;
1683  }
1684 
1685  // check client password
1687  "reclaim-rest-plugin",
1688  "OIDC_CLIENT_SECRET",
1689  &expected_pass))
1690  {
1691  if (0 != strcmp (expected_pass, pass))
1692  {
1693  GNUNET_free_non_null (basic_authorization);
1694  GNUNET_free (expected_pass);
1696  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1697  return GNUNET_SYSERR;
1698  }
1699  GNUNET_free (expected_pass);
1700  }
1701  else
1702  {
1703  GNUNET_free_non_null (basic_authorization);
1705  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1706  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1707  return GNUNET_SYSERR;
1708  }
1709 
1710  // check client_id
1711  for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1712  handle->ego_entry = handle->ego_entry->next)
1713  {
1714  if (0 == strcmp (handle->ego_entry->keystring, client_id))
1715  break;
1716  }
1717  if (NULL == handle->ego_entry)
1718  {
1719  GNUNET_free_non_null (basic_authorization);
1721  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1722  return GNUNET_SYSERR;
1723  }
1724  GNUNET_STRINGS_string_to_data (client_id,
1725  strlen (client_id),
1726  cid,
1727  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1728 
1729  GNUNET_free (basic_authorization);
1730  return GNUNET_OK;
1731 }
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
int response_code
Response code.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1920
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
char * keystring
Public key string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
struct EgoEntry * ego_head
Ego list.
#define OIDC_ERROR_KEY_INVALID_CLIENT
OIDC error key for invalid client.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
struct EgoEntry * ego_entry
IDENTITY Operation.
struct EgoEntry * next
DLL.
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:952
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_ego()

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

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

1737 {
1738  struct EgoEntry *ego_entry;
1739  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1740 
1741  for (ego_entry = handle->ego_head; NULL != ego_entry;
1742  ego_entry = ego_entry->next)
1743  {
1744  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
1745  if (0 == GNUNET_memcmp (&pub_key, test_key))
1746  return ego_entry;
1747  }
1748  return NULL;
1749 }
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:568
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct EgoEntry * next
DLL.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ persist_access_token()

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

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

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

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

Referenced by init_cont().

1783 {
1784  struct RequestHandle *handle = cls;
1785  const struct EgoEntry *ego_entry;
1786  struct GNUNET_TIME_Relative expiration_time;
1789  struct GNUNET_CRYPTO_EcdsaPublicKey cid;
1790  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1791  struct GNUNET_HashCode cache_key;
1792  struct MHD_Response *resp;
1793  char *grant_type;
1794  char *code;
1795  char *json_response;
1796  char *id_token;
1797  char *access_token;
1798  char *jwt_secret;
1799  char *nonce;
1800  char *code_verifier;
1801 
1802  /*
1803  * Check Authorization
1804  */
1805  if (GNUNET_SYSERR == check_authorization (handle, &cid))
1806  {
1808  "OIDC authorization for token endpoint failed\n");
1810  return;
1811  }
1812 
1813  /*
1814  * Check parameter
1815  */
1816 
1817  // TODO Do not allow multiple equal parameter names
1818  // REQUIRED grant_type
1820  strlen (OIDC_GRANT_TYPE_KEY),
1821  &cache_key);
1822  grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY);
1823  if (NULL == grant_type)
1824  {
1826  handle->edesc = GNUNET_strdup ("missing parameter grant_type");
1827  handle->response_code = MHD_HTTP_BAD_REQUEST;
1829  return;
1830  }
1831 
1832  // Check parameter grant_type == "authorization_code"
1833  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
1834  {
1836  handle->response_code = MHD_HTTP_BAD_REQUEST;
1837  GNUNET_free (grant_type);
1839  return;
1840  }
1841  GNUNET_free (grant_type);
1842  // REQUIRED code
1843  code = get_url_parameter_copy (handle, OIDC_CODE_KEY);
1844  if (NULL == code)
1845  {
1847  handle->edesc = GNUNET_strdup ("missing parameter code");
1848  handle->response_code = MHD_HTTP_BAD_REQUEST;
1850  return;
1851  }
1852  ego_entry = find_ego (handle, &cid);
1853  if (NULL == ego_entry)
1854  {
1856  handle->edesc = GNUNET_strdup ("Unknown client");
1857  handle->response_code = MHD_HTTP_BAD_REQUEST;
1858  GNUNET_free (code);
1860  return;
1861  }
1862  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1863 
1864  // REQUIRED code verifier
1865  code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY);
1866  if (NULL == code_verifier)
1867  {
1869  "OAuth authorization request does not contain PKCE parameters!\n");
1870 
1871  }
1872 
1873  // decode code
1874  if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket,
1875  &cl, &nonce))
1876  {
1878  handle->edesc = GNUNET_strdup ("invalid code");
1879  handle->response_code = MHD_HTTP_BAD_REQUEST;
1880  GNUNET_free (code);
1882  return;
1883  }
1884  GNUNET_free (code);
1885 
1886  // create jwt
1888  "reclaim-rest-plugin",
1889  "expiration_time",
1890  &expiration_time))
1891  {
1893  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1894  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1896  return;
1897  }
1898 
1899 
1900  // TODO OPTIONAL acr,amr,azp
1902  "reclaim-rest-plugin",
1903  "jwt_secret",
1904  &jwt_secret))
1905  {
1907  handle->edesc = GNUNET_strdup ("No signing secret configured!");
1908  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1910  return;
1911  }
1912  id_token = OIDC_id_token_new (&ticket.audience,
1913  &ticket.identity,
1914  cl,
1915  &expiration_time,
1916  (NULL != nonce) ? nonce : NULL,
1917  jwt_secret);
1918  access_token = OIDC_access_token_new ();
1919  OIDC_build_token_response (access_token,
1920  id_token,
1921  &expiration_time,
1922  &json_response);
1923 
1924  persist_access_token (handle, access_token, &ticket);
1925  resp = GNUNET_REST_create_response (json_response);
1926  MHD_add_response_header (resp, "Cache-Control", "no-store");
1927  MHD_add_response_header (resp, "Pragma", "no-cache");
1928  MHD_add_response_header (resp, "Content-Type", "application/json");
1929  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1931  GNUNET_free (access_token);
1932  GNUNET_free (json_response);
1933  GNUNET_free (id_token);
1935 }
The authorization ticket.
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
#define OIDC_GRANT_TYPE_KEY
OIDC grant_type key.
static void persist_access_token(const struct RequestHandle *handle, const char *access_token, const struct GNUNET_RECLAIM_Ticket *ticket)
#define OIDC_CODE_KEY
OIDC code key.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:555
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:83
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:851
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
char * edesc
Error response description.
The request handle.
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE
OIDC error key for unsupported grants.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_RECLAIM_ATTRIBUTE_list_destroy(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs)
Destroy claim list.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define OIDC_CODE_VERIFIER_KEY
OIDC PKCE code verifier.
A 512-bit hashcode.
int response_code
Response code.
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
#define GNUNET_SYSERR
Definition: gnunet_common.h:84
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:708
static int check_authorization(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
char * OIDC_id_token_new(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:119
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:879
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
A list of GNUNET_RECLAIM_ATTRIBUTE_Claim structures.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_GRANT_TYPE_VALUE
OIDC grant_type key.
#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,
const struct GNUNET_RECLAIM_ATTESTATION_Claim attest,
const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE reference 
)
static

Collects claims and stores them in handle.

Definition at line 1942 of file plugin_rest_openid_connect.c.

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

Referenced by userinfo_endpoint().

1947 {
1948  struct RequestHandle *handle = cls;
1949  if (NULL == identity)
1950  {
1952  return;
1953  }
1954  if (NULL != attr)
1955  {
1956  char *tmp_value;
1957  json_t *value;
1959  attr->data,
1960  attr->data_size);
1961  value = json_string (tmp_value);
1962  json_object_set_new (handle->oidc->response, attr->name, value);
1963  GNUNET_free (tmp_value);
1964  }
1965  else if ((NULL != attest) && (NULL != reference))
1966  {
1967  json_t *claim_sources;
1968  json_t *claim_sources_jwt;
1969  json_t *claim_names;
1970  char *attest_val_str;
1971  claim_sources=json_object_get(handle->oidc->response,"_claim_sources");
1972  claim_names=json_object_get(handle->oidc->response,"_claim_names");
1973  attest_val_str = GNUNET_RECLAIM_ATTESTATION_value_to_string (attest->type,
1974  attest->data,
1975  attest->
1976  data_size);
1977  if ((NULL == claim_sources) && (NULL == claim_names) )
1978  {
1979  claim_sources = json_object ();
1980  claim_names = json_object ();
1981  }
1982  char *source_name;
1983  int i = 0;
1984  GNUNET_asprintf (&source_name,"src%d",i);
1985  while (NULL != (claim_sources_jwt = json_object_get (claim_sources,
1986  source_name)))
1987  {
1988  if (0 == strcmp (json_string_value (json_object_get (claim_sources_jwt,
1989  "JWT")),
1990  attest_val_str))
1991  {
1992  // Adapt only the claim names
1993  json_object_set_new (claim_names, reference->name, json_string (
1994  source_name));
1995  json_object_set (handle->oidc->response, "_claim_names",claim_names);
1996  handle->oidc->response = json_deep_copy(handle->oidc->response);
1997  break;
1998  }
1999  i++;
2000  GNUNET_asprintf (&source_name,"src%d",i);
2001  }
2002 
2003  // Create new one
2004  if (NULL == claim_sources_jwt)
2005  {
2006  claim_sources_jwt = json_object ();
2007  // Set the JWT for names
2008  json_object_set_new (claim_names, reference->name, json_string (
2009  source_name));
2010  // Set the JWT for the inner source
2011  json_object_set_new (claim_sources_jwt, "JWT", json_string (
2012  attest_val_str));
2013  // Set the JWT for the source
2014  json_object_set_new (claim_sources, source_name,claim_sources_jwt);
2015  // Set as claims
2016  json_object_set (handle->oidc->response, "_claim_names", claim_names);
2017  json_object_set (handle->oidc->response, "_claim_sources",claim_sources);
2018  handle->oidc->response = json_deep_copy(handle->oidc->response);
2019  }
2020 
2021  json_decref (claim_sources);
2022  json_decref (claim_names);
2023  json_decref (claim_sources_jwt);
2024  GNUNET_free (attest_val_str);
2025  }
2026  else
2027  {
2028  // REMARK: We should not find any claim, one of attest/ref is NULL
2029  }
2030 }
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.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
const void * data
Binary value stored as attribute value.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static char * value
Value of the record to add/remove.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void return_userinfo_response(void *cls)
Return attributes for claim.
char * GNUNET_RECLAIM_ATTESTATION_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;claim&#39; of an attestation to a string.
const char * name
The name of the attribute/attestation reference value.
json_t * response
The response JSON.
#define GNUNET_free(ptr)
Wrapper around free.
const void * data
Binary value stored as attribute value.
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 2041 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().

2044 {
2045  // TODO expiration time
2046  struct RequestHandle *handle = cls;
2047  char delimiter[] = " ";
2048  struct GNUNET_HashCode cache_key;
2049  char *authorization;
2050  char *authorization_type;
2051  char *authorization_access_token;
2052  struct GNUNET_RECLAIM_Ticket *ticket;
2053  const struct EgoEntry *ego_entry;
2054  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
2055 
2058  &cache_key);
2060  ->header_param_map,
2061  &cache_key))
2062  {
2064  handle->edesc = GNUNET_strdup ("No Access Token");
2065  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2067  return;
2068  }
2069  authorization =
2071  &cache_key);
2072 
2073  // split header in "Bearer" and access_token
2074  authorization = GNUNET_strdup (authorization);
2075  authorization_type = strtok (authorization, delimiter);
2076  if ((NULL == authorization_type) ||
2077  (0 != strcmp ("Bearer", authorization_type)))
2078  {
2080  handle->edesc = GNUNET_strdup ("No Access Token");
2081  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2083  GNUNET_free (authorization);
2084  return;
2085  }
2086  authorization_access_token = strtok (NULL, delimiter);
2087  if (NULL == authorization_access_token)
2088  {
2090  handle->edesc = GNUNET_strdup ("Access token missing");
2091  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2093  GNUNET_free (authorization);
2094  return;
2095  }
2096 
2097  GNUNET_CRYPTO_hash (authorization_access_token,
2098  strlen (authorization_access_token),
2099  &cache_key);
2100  if (GNUNET_NO ==
2102  &cache_key))
2103  {
2105  handle->edesc = GNUNET_strdup ("The access token expired");
2106  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2108  GNUNET_free (authorization);
2109  return;
2110  }
2111  ticket =
2113  GNUNET_assert (NULL != ticket);
2114  ego_entry = find_ego (handle, &ticket->audience);
2115  if (NULL == ego_entry)
2116  {
2118  handle->edesc = GNUNET_strdup ("The access token expired");
2119  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2121  GNUNET_free (authorization);
2122  return;
2123  }
2124 
2125  handle->idp = GNUNET_RECLAIM_connect (cfg);
2126  handle->oidc->response = json_object ();
2127  json_object_set_new (handle->oidc->response,
2128  "sub",
2129  json_string (ego_entry->keystring));
2130  privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
2131  handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
2132  privkey,
2133  ticket,
2135  handle);
2136  GNUNET_free (authorization);
2137 }
The authorization ticket.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:555
#define GNUNET_NO
Definition: gnunet_common.h:86
Private ECC key encoded for transmission.
#define OIDC_ERROR_KEY_INVALID_TOKEN
OIDC error key for invalid tokens.
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
The ego list.
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
int response_code
Response code.
char * keystring
Public key string.
struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
static void consume_ticket(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr, const struct GNUNET_RECLAIM_ATTESTATION_Claim *attest, const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference)
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:1505
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:1004
#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 2146 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().

2147 {
2149  static const struct GNUNET_REST_RequestHandler handlers[] =
2150  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
2151  { MHD_HTTP_METHOD_POST,
2153  &authorize_endpoint }, // url-encoded
2154  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
2155  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
2156  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2157  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2158  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
2160 
2161  if (GNUNET_NO ==
2162  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
2163  {
2164  handle->response_code = err.error_code;
2166  }
2167 }
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_REST_HANDLER_END
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
#define GNUNET_REST_API_NS_AUTHORIZE
Authorize endpoint.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
Definition: rest.c:77
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
int response_code
Response code.
static void login_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Combines an identity with a login time and responds OK to login request.
static void userinfo_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to userinfo GET and url-encoded POST request.
#define GNUNET_REST_API_NS_LOGIN
Login namespace.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static void authorize_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to authorization GET and url-encoded POST request.
static void do_error(void *cls)
Task run on error, sends error message.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void token_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to token url-encoded POST request.
#define GNUNET_REST_API_NS_USERINFO
UserInfo endpoint.
#define GNUNET_REST_API_NS_TOKEN
Token endpoint.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ list_ego()

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

If listing is enabled, prints information about the egos.

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

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

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

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

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

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

2208 {
2209  struct RequestHandle *handle = cls;
2210  struct EgoEntry *ego_entry;
2212 
2213  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
2214  {
2215  handle->state = ID_REST_STATE_POST_INIT;
2216  init_cont (handle);
2217  return;
2218  }
2219  GNUNET_assert (NULL != ego);
2220  if (ID_REST_STATE_INIT == handle->state)
2221 
2222  {
2223  ego_entry = GNUNET_new (struct EgoEntry);
2226  ego_entry->ego = ego;
2227  ego_entry->identifier = GNUNET_strdup (identifier);
2229  handle->ego_tail,
2230  ego_entry);
2231  return;
2232  }
2233  /* Ego renamed or added */
2234  if (identifier != NULL)
2235  {
2236  for (ego_entry = handle->ego_head; NULL != ego_entry;
2237  ego_entry = ego_entry->next)
2238  {
2239  if (ego_entry->ego == ego)
2240  {
2241  /* Rename */
2242  GNUNET_free (ego_entry->identifier);
2243  ego_entry->identifier = GNUNET_strdup (identifier);
2244  break;
2245  }
2246  }
2247  if (NULL == ego_entry)
2248  {
2249  /* Add */
2250  ego_entry = GNUNET_new (struct EgoEntry);
2253  ego_entry->ego = ego;
2254  ego_entry->identifier = GNUNET_strdup (identifier);
2256  handle->ego_tail,
2257  ego_entry);
2258  }
2259  }
2260  else
2261  {
2262  /* Delete */
2263  for (ego_entry = handle->ego_head; NULL != ego_entry;
2264  ego_entry = ego_entry->next)
2265  {
2266  if (ego_entry->ego == ego)
2267  break;
2268  }
2269  if (NULL != ego_entry)
2271  handle->ego_tail,
2272  ego_entry);
2273  }
2274 }
#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:223
char * keystring
Public key string.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GNUNET_IDENTITY_ego_get_public_key(const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:568
char * identifier
Ego Identifier.
struct EgoEntry * ego_head
Ego list.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define ID_REST_STATE_INIT
State while collecting all egos.
struct EgoEntry * next
DLL.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rest_identity_process_request()

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

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

2281 {
2282  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2283 
2284  handle->oidc = GNUNET_new (struct OIDC_Variables);
2285  if (NULL == OIDC_cookie_jar_map)
2287  if (NULL == OIDC_access_token_map)
2290  handle->response_code = 0;
2292  handle->proc_cls = proc_cls;
2293  handle->proc = proc;
2294  handle->state = ID_REST_STATE_INIT;
2295  handle->rest_handle = rest_handle;
2296 
2297  handle->url = GNUNET_strdup (rest_handle->url);
2298  if (handle->url[strlen (handle->url) - 1] == '/')
2299  handle->url[strlen (handle->url) - 1] = '\0';
2300  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
2301  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle);
2302  handle->gns_handle = GNUNET_GNS_connect (cfg);
2304  handle->timeout_task =
2305  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
2306  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
2307 }
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:527
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define GNUNET_NO
Definition: gnunet_common.h:86
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
The request handle.
OIDC needed variables.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
static void do_timeout(void *cls)
Task run on timeout, sends error message.
const char * url
The url as string.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:268
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
int response_code
Response code.
int state
The processing state.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
struct GNUNET_GNS_Handle * gns_handle
GNS handle.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define ID_REST_STATE_INIT
State while collecting all egos.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC Hash map that keeps track of issued cookies.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
struct GNUNET_NAMESTORE_Handle * namestore_handle
Handle to NAMESTORE.
char * url
The url.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_rest_openid_connect_init()

void* libgnunet_plugin_rest_openid_connect_init ( void *  cls)

Entry point for the plugin.

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

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

2318 {
2319  static struct Plugin plugin;
2320  struct GNUNET_REST_Plugin *api;
2321 
2322  cfg = cls;
2323  if (NULL != plugin.cfg)
2324  return NULL; /* can only initialize once! */
2325  memset (&plugin, 0, sizeof(struct Plugin));
2326  plugin.cfg = cfg;
2327  api = GNUNET_new (struct GNUNET_REST_Plugin);
2328  api->cls = &plugin;
2332  "%s, %s, %s, %s, %s",
2333  MHD_HTTP_METHOD_GET,
2334  MHD_HTTP_METHOD_POST,
2335  MHD_HTTP_METHOD_PUT,
2336  MHD_HTTP_METHOD_DELETE,
2337  MHD_HTTP_METHOD_OPTIONS);
2338 
2340  _ ("OpenID Connect REST API initialized\n"));
2341  return api;
2342 }
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:180
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * name
Plugin name.
static char * plugin
Solver plugin name as string.
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
Here is the call graph for this function:

◆ libgnunet_plugin_rest_openid_connect_done()

void* libgnunet_plugin_rest_openid_connect_done ( void *  cls)

Exit point from the plugin.

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

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

2353 {
2354  struct GNUNET_REST_Plugin *api = cls;
2355  struct Plugin *plugin = api->cls;
2356 
2357  plugin->cfg = NULL;
2358 
2359  struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it;
2360  void *value = NULL;
2361  hashmap_it =
2363  while (GNUNET_YES ==
2364  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2365  GNUNET_free_non_null (value);
2368 
2369  hashmap_it =
2371  while (GNUNET_YES ==
2372  GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value))
2373  GNUNET_free_non_null (value);
2377  GNUNET_free (api);
2379  "OpenID Connect REST plugin is finished\n");
2380  return NULL;
2381 }
void GNUNET_CONTAINER_multihashmap_iterator_destroy(struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
Destroy a multihashmap iterator.
int GNUNET_CONTAINER_multihashmap_iterator_next(struct GNUNET_CONTAINER_MultiHashMapIterator *iter, struct GNUNET_HashCode *key, const void **value)
Retrieve the next element from the hash map at the iterator&#39;s position.
struct GNUNET_CONTAINER_MultiHashMapIterator * GNUNET_CONTAINER_multihashmap_iterator_create(const struct GNUNET_CONTAINER_MultiHashMap *map)
Create an iterator for a multihashmap.
void * cls
The closure of the plugin.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct returned by the initialization function of the plugin
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static char * plugin
Solver plugin name as string.
struct GNUNET_CONTAINER_MultiHashMap * OIDC_access_token_map
Hash map that links the issued access token to the corresponding ticket and ego.
static char * allow_methods
HTTP methods allows for this plugin.
Handle for a plugin.
Definition: block.c:37
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:85
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 226 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 237 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 243 of file plugin_rest_openid_connect.c.

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg

The configuration handle.

Handle to our configuration.

Definition at line 248 of file plugin_rest_openid_connect.c.

◆ allow_methods

char* allow_methods
static

HTTP methods allows for this plugin.

Definition at line 253 of file plugin_rest_openid_connect.c.

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