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_buffer_lib.h"
#include "gnunet_strings_lib.h"
#include "gnunet_gns_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_identity_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_reclaim_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_OIDC_CONFIG   "/.well-known/openid-configuration"
 OIDC config. 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 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 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, const struct GNUNET_RECLAIM_PresentationList *pres)
 Issues ticket and redirects to relying party with the authorization code as parameter. More...
 
static struct GNUNET_RECLAIM_AttributeListattribute_list_merge (struct GNUNET_RECLAIM_AttributeList *list_a, struct GNUNET_RECLAIM_AttributeList *list_b)
 
static void oidc_cred_collect_finished_cb (void *cls)
 
static void oidc_cred_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred)
 Collects all attributes for an ego if in scope parameter. More...
 
static void oidc_attr_collect_finished_cb (void *cls)
 
static int attr_in_claims_request (struct RequestHandle *handle, const char *attr_name, const char *claims_parameter)
 
static int attr_in_idtoken_request (struct RequestHandle *handle, const char *attr_name)
 
static int attr_in_userinfo_request (struct RequestHandle *handle, const char *attr_name)
 
static void oidc_attr_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr)
 Collects all attributes for an ego if in scope parameter. More...
 
static void code_redirect (void *cls)
 Checks time and cookie and redirects accordingly. More...
 
static void build_redirect (void *cls)
 
static void lookup_redirect_uri_result (void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 
static void client_redirect (void *cls)
 Initiate redirect back to client. More...
 
static char * get_url_parameter_copy (const struct RequestHandle *handle, const char *key)
 
static void build_authz_response (void *cls)
 Iteration over all results finished, build final response. More...
 
static void tld_iter (void *cls, const char *section, const char *option, const char *value)
 Iterate over tlds in config. More...
 
static void authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Responds to authorization GET and url-encoded POST request. More...
 
static void login_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Combines an identity with a login time and responds OK to login request. More...
 
static int parse_credentials_basic_auth (struct RequestHandle *handle, char **client_id, char **client_secret)
 
static int parse_credentials_post_body (struct RequestHandle *handle, char **client_id, char **client_secret)
 
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 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 *attr, const struct GNUNET_RECLAIM_Presentation *pres)
 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 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 oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 
static void oidc_config_cors (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Respond to OPTIONS request. More...
 
static enum GNUNET_GenericReturnValue 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...
 
static int cleanup_hashmap (void *cls, const struct GNUNET_HashCode *key, void *value)
 
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...
 
const struct GNUNET_CONFIGURATION_Handlecfg
 The configuration handle. More...
 
static char * allow_methods
 HTTP methods allows for this plugin. More...
 
static struct EgoEntryego_head
 Ego list. More...
 
static struct EgoEntryego_tail
 Ego list. More...
 
static int state
 The processing state. More...
 
static struct GNUNET_IDENTITY_Handleidentity_handle
 Handle to Identity service. More...
 
static struct GNUNET_GNS_Handlegns_handle
 GNS handle. More...
 
static struct GNUNET_RECLAIM_Handleidp
 Identity Provider. More...
 
static struct RequestHandlerequests_head
 DLL. More...
 
static struct RequestHandlerequests_tail
 DLL. More...
 

Macro Definition Documentation

◆ GNUNET_REST_API_NS_OIDC

#define GNUNET_REST_API_NS_OIDC   "/openid"

REST root namespace.

Definition at line 48 of file plugin_rest_openid_connect.c.

Referenced by libgnunet_plugin_rest_openid_connect_init(), and rest_identity_process_request().

◆ GNUNET_REST_API_NS_OIDC_CONFIG

#define GNUNET_REST_API_NS_OIDC_CONFIG   "/.well-known/openid-configuration"

OIDC config.

Definition at line 53 of file plugin_rest_openid_connect.c.

Referenced by rest_identity_process_request().

◆ GNUNET_REST_API_NS_AUTHORIZE

#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"

Authorize endpoint.

Definition at line 58 of file plugin_rest_openid_connect.c.

Referenced by rest_identity_process_request().

◆ GNUNET_REST_API_NS_TOKEN

#define GNUNET_REST_API_NS_TOKEN   "/openid/token"

Token endpoint.

Definition at line 63 of file plugin_rest_openid_connect.c.

Referenced by rest_identity_process_request().

◆ GNUNET_REST_API_NS_USERINFO

#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"

UserInfo endpoint.

Definition at line 68 of file plugin_rest_openid_connect.c.

Referenced by rest_identity_process_request().

◆ GNUNET_REST_API_NS_LOGIN

#define GNUNET_REST_API_NS_LOGIN   "/openid/login"

Login namespace.

Definition at line 73 of file plugin_rest_openid_connect.c.

Referenced by rest_identity_process_request().

◆ ID_REST_STATE_INIT

#define ID_REST_STATE_INIT   0

State while collecting all egos.

Definition at line 78 of file plugin_rest_openid_connect.c.

Referenced by libgnunet_plugin_rest_openid_connect_init(), and list_ego().

◆ ID_REST_STATE_POST_INIT

#define ID_REST_STATE_POST_INIT   1

Done collecting egos.

Definition at line 83 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 88 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 93 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 98 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 103 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 108 of file plugin_rest_openid_connect.c.

Referenced by authorize_endpoint(), check_authorization(), and login_redirect().

◆ OIDC_SCOPE_KEY

#define OIDC_SCOPE_KEY   "scope"

OIDC scope key.

Definition at line 113 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 118 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 123 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 128 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 133 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 138 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 143 of file plugin_rest_openid_connect.c.

Referenced by check_authorization(), and token_endpoint().

◆ OIDC_COOKIE_EXPIRATION

#define OIDC_COOKIE_EXPIRATION   3

OIDC cookie expiration (in seconds)

Definition at line 148 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 153 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 158 of file plugin_rest_openid_connect.c.

Referenced by parse_credentials_basic_auth(), and userinfo_endpoint().

◆ OIDC_COOKIE_HEADER_INFORMATION_KEY

#define OIDC_COOKIE_HEADER_INFORMATION_KEY   "Identity="

OIDC cookie header information key.

Definition at line 163 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 168 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 173 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 178 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 183 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 188 of file plugin_rest_openid_connect.c.

Referenced by build_authz_response(), and oidc_attr_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 193 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 198 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 203 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 213 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 218 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 223 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 228 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 560 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, RequestHandle::attr_it, RequestHandle::attr_userinfo_list, OIDC_Variables::client_id, RequestHandle::cred_it, RequestHandle::credentials, RequestHandle::edesc, RequestHandle::emsg, RequestHandle::gns_op, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNS_lookup_cancel(), GNUNET_log, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_cancel(), GNUNET_RECLAIM_credential_list_destroy(), GNUNET_RECLAIM_get_attributes_stop(), GNUNET_RECLAIM_get_credentials_stop(), GNUNET_RECLAIM_presentation_list_destroy(), GNUNET_RECLAIM_ticket_iteration_stop(), GNUNET_SCHEDULER_cancel(), RequestHandle::idp_op, OIDC_Variables::login_identity, OIDC_Variables::nonce, RequestHandle::oidc, RequestHandle::presentations, RequestHandle::redirect_prefix, RequestHandle::redirect_suffix, OIDC_Variables::redirect_uri, OIDC_Variables::response_type, OIDC_Variables::scope, OIDC_Variables::state, RequestHandle::ticket_it, RequestHandle::timeout_task, RequestHandle::tld, and RequestHandle::url.

Referenced by build_redirect(), consume_ticket(), do_error(), do_redirect_error(), do_userinfo_error(), libgnunet_plugin_rest_openid_connect_done(), login_cont(), login_redirect(), oidc_config_cors(), oidc_config_endpoint(), oidc_ticket_issue_cb(), options_cont(), and token_endpoint().

561 {
562 
563  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
564  if (NULL != handle->timeout_task)
566  if (NULL != handle->attr_it)
568  if (NULL != handle->cred_it)
570  if (NULL != handle->ticket_it)
572  if (NULL != handle->idp_op)
573  GNUNET_RECLAIM_cancel (handle->idp_op);
574  GNUNET_free (handle->url);
575  GNUNET_free (handle->tld);
576  GNUNET_free (handle->redirect_prefix);
577  GNUNET_free (handle->redirect_suffix);
578  GNUNET_free (handle->emsg);
579  GNUNET_free (handle->edesc);
580  if (NULL != handle->gns_op)
582  if (NULL != handle->oidc)
583  {
584  GNUNET_free (handle->oidc->client_id);
585  GNUNET_free (handle->oidc->login_identity);
586  GNUNET_free (handle->oidc->nonce);
587  GNUNET_free (handle->oidc->redirect_uri);
588  GNUNET_free (handle->oidc->response_type);
589  GNUNET_free (handle->oidc->scope);
590  GNUNET_free (handle->oidc->state);
591  GNUNET_free (handle->oidc);
592  }
593  if (NULL!=handle->attr_idtoken_list)
595  if (NULL!=handle->attr_userinfo_list)
597  if (NULL!=handle->credentials)
599  if (NULL!=handle->presentations)
603  handle);
604  GNUNET_free (handle);
605 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
char * redirect_uri
The OIDC redirect uri.
char * scope
The list of oidc scopes.
void GNUNET_RECLAIM_get_credentials_stop(struct GNUNET_RECLAIM_CredentialIterator *ait)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1509
char * nonce
The OIDC nonce.
void GNUNET_RECLAIM_attribute_list_destroy(struct GNUNET_RECLAIM_AttributeList *attrs)
Destroy claim list.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
static struct RequestHandle * requests_tail
DLL.
struct GNUNET_GNS_LookupRequest * gns_op
GNS lookup op.
void GNUNET_RECLAIM_cancel(struct GNUNET_RECLAIM_Operation *op)
Cancel an identity provider operation.
Definition: reclaim_api.c:1089
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1701
static struct RequestHandle * requests_head
DLL.
char * edesc
Error response description.
struct OIDC_Variables * oidc
OIDC variables.
char * response_type
The OIDC response type.
struct GNUNET_RECLAIM_PresentationList * presentations
Presentations.
struct GNUNET_RECLAIM_CredentialList * credentials
Credentials.
char * emsg
Error response message.
char * client_id
The OIDC client id of the RP.
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
char * tld
The tld for redirect.
void GNUNET_RECLAIM_credential_list_destroy(struct GNUNET_RECLAIM_CredentialList *credentials)
Destroy claim list.
void GNUNET_RECLAIM_presentation_list_destroy(struct GNUNET_RECLAIM_PresentationList *presentations)
Destroy presentations list.
struct GNUNET_RECLAIM_CredentialIterator * cred_it
Credential iterator.
char * state
The OIDC state.
char * redirect_prefix
The redirect prefix.
void GNUNET_RECLAIM_get_attributes_stop(struct GNUNET_RECLAIM_AttributeIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1398
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,...)
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:314
#define GNUNET_free(ptr)
Wrapper around free.
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:972
char * url
The url.
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 614 of file plugin_rest_openid_connect.c.

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

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

615 {
616  struct RequestHandle *handle = cls;
617  struct MHD_Response *resp;
618  char *json_error;
619 
620  GNUNET_asprintf (&json_error,
621  "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
622  handle->emsg,
623  (NULL != handle->edesc) ? handle->edesc : "",
624  (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
625  (NULL != handle->oidc->state) ? handle->oidc->state : "",
626  (NULL != handle->oidc->state) ? "\"" : "");
627  if (0 == handle->response_code)
628  handle->response_code = MHD_HTTP_BAD_REQUEST;
629  resp = GNUNET_REST_create_response (json_error);
630  if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
631  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
632  MHD_add_response_header (resp,
633  MHD_HTTP_HEADER_CONTENT_TYPE,
634  "application/json");
635  handle->proc (handle->proc_cls, resp, handle->response_code);
636  cleanup_handle (handle);
637  GNUNET_free (json_error);
638 }
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.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
int response_code
Response code.
char * state
The OIDC state.
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 648 of file plugin_rest_openid_connect.c.

References cleanup_handle(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_REST_create_response(), handle, RequestHandle::proc, RequestHandle::proc_cls, and RequestHandle::response_code.

Referenced by userinfo_endpoint().

649 {
650  struct RequestHandle *handle = cls;
651  struct MHD_Response *resp;
652  char *error;
653 
655  "Error: %s\n", handle->edesc);
656  GNUNET_asprintf (&error,
657  "error=\"%s\", error_description=\"%s\"",
658  handle->emsg,
659  (NULL != handle->edesc) ? handle->edesc : "");
660  resp = GNUNET_REST_create_response ("");
661  MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
662  handle->proc (handle->proc_cls, resp, handle->response_code);
663  cleanup_handle (handle);
664  GNUNET_free (error);
665 }
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.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
int response_code
Response code.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
#define GNUNET_log(kind,...)
#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 674 of file plugin_rest_openid_connect.c.

References cleanup_handle(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_asprintf(), GNUNET_free, GNUNET_REST_create_response(), 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_attr_collect_finished_cb(), and oidc_ticket_issue_cb().

675 {
676  struct RequestHandle *handle = cls;
677  struct MHD_Response *resp;
678  char *redirect;
679 
680  GNUNET_asprintf (&redirect,
681  "%s?error=%s&error_description=%s%s%s",
682  handle->oidc->redirect_uri,
683  handle->emsg,
684  handle->edesc,
685  (NULL != handle->oidc->state) ? "&state=" : "",
686  (NULL != handle->oidc->state) ? handle->oidc->state : "");
687  resp = GNUNET_REST_create_response ("");
688  MHD_add_response_header (resp, "Location", redirect);
689  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
690  cleanup_handle (handle);
691  GNUNET_free (redirect);
692 }
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.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
char * state
The OIDC state.
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 701 of file plugin_rest_openid_connect.c.

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

Referenced by rest_identity_process_request().

702 {
703  struct RequestHandle *handle = cls;
704 
705  handle->timeout_task = NULL;
706  do_error (handle);
707 }
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:

◆ 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 718 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 rest_identity_process_request().

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

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

References OIDC_Variables::claims, cleanup_handle(), OIDC_Variables::client_id, OIDC_Variables::code_challenge, do_error(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_buffer_reap_str(), GNUNET_buffer_write_fstr(), GNUNET_buffer_write_str(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_free, GNUNET_OK, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_STRINGS_urlencode(), 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().

831 {
832  char *login_base_url;
833  char *new_redirect;
834  char *tmp;
835  struct MHD_Response *resp;
836  struct GNUNET_Buffer buf = { 0 };
837  struct RequestHandle *handle = cls;
838 
840  "reclaim-rest-plugin",
841  "address",
842  &login_base_url))
843  {
844  GNUNET_buffer_write_str (&buf, login_base_url);
846  "?%s=%s",
848  handle->oidc->response_type);
850  "&%s=%s",
852  handle->oidc->client_id);
854  strlen (handle->oidc->redirect_uri),
855  &tmp);
857  "&%s=%s",
859  tmp);
860  GNUNET_free (tmp);
862  strlen (handle->oidc->scope),
863  &tmp);
865  "&%s=%s",
867  tmp);
868  GNUNET_free (tmp);
869  if (NULL != handle->oidc->state)
870  {
872  strlen (handle->oidc->state),
873  &tmp);
875  "&%s=%s",
877  handle->oidc->state);
878  GNUNET_free (tmp);
879  }
880  if (NULL != handle->oidc->code_challenge)
881  {
883  "&%s=%s",
885  handle->oidc->code_challenge);
886  }
887  if (NULL != handle->oidc->nonce)
888  {
890  "&%s=%s",
892  handle->oidc->nonce);
893  }
894  if (NULL != handle->oidc->claims)
895  {
897  strlen (handle->oidc->claims),
898  &tmp);
900  "&%s=%s",
902  tmp);
903  GNUNET_free (tmp);
904  }
905  new_redirect = GNUNET_buffer_reap_str (&buf);
906  resp = GNUNET_REST_create_response ("");
907  MHD_add_response_header (resp, "Location", new_redirect);
908  GNUNET_free (login_base_url);
909  }
910  else
911  {
913  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
914  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
916  return;
917  }
918  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
919  GNUNET_free (new_redirect);
920  cleanup_handle (handle);
921 }
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.
char * GNUNET_buffer_reap_str(struct GNUNET_Buffer *buf)
Clear the buffer and return the string it contained.
Definition: buffer.c:123
#define OIDC_CLAIMS_KEY
OIDC claims key.
void GNUNET_buffer_write_fstr(struct GNUNET_Buffer *buf, const char *fmt,...)
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
Definition: buffer.c:209
#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.
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:1296
static char buf[2048]
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
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.
size_t GNUNET_STRINGS_urlencode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition: strings.c:2146
char * state
The OIDC state.
static void do_error(void *cls)
Task run on error, sends error message.
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.
Common buffer management functions.
void GNUNET_buffer_write_str(struct GNUNET_Buffer *buf, const char *str)
Write a 0-terminated string to a buffer, excluding the 0-terminator.
Definition: buffer.c:103
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 928 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(), and oidc_attr_collect_finished_cb().

929 {
930  struct RequestHandle *handle = cls;
931 
933  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
935 }
#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:1296
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,
const struct GNUNET_RECLAIM_PresentationList pres 
)
static

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

Otherwise redirects with error

Definition at line 943 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, cleanup_handle(), 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_cred_collect_finished_cb().

946 {
947  struct RequestHandle *handle = cls;
948  struct MHD_Response *resp;
949  char *ticket_str;
950  char *redirect_uri;
951  char *code_string;
952 
953  handle->idp_op = NULL;
954  if (NULL == ticket)
955  {
957  handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
959  return;
960  }
961  handle->ticket = *ticket;
962  ticket_str =
964  sizeof(struct GNUNET_RECLAIM_Ticket));
965  code_string = OIDC_build_authz_code (&handle->priv_key,
966  &handle->ticket,
967  handle->attr_idtoken_list,
968  pres,
969  handle->oidc->nonce,
970  handle->oidc->code_challenge);
971  if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
972  (NULL != handle->tld))
973  {
974  GNUNET_asprintf (&redirect_uri,
975  "%s.%s/%s?%s=%s&state=%s",
976  handle->redirect_prefix,
977  handle->tld,
978  handle->redirect_suffix,
979  (NULL == strchr (handle->redirect_suffix, '?') ? "?" :
980  "&"),
981  handle->oidc->response_type,
982  code_string,
983  handle->oidc->state);
984  }
985  else
986  {
987  GNUNET_asprintf (&redirect_uri,
988  "%s%s%s=%s&state=%s",
989  handle->oidc->redirect_uri,
990  (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" :
991  "&"),
992  handle->oidc->response_type,
993  code_string,
994  handle->oidc->state);
995  }
996  resp = GNUNET_REST_create_response ("");
997  MHD_add_response_header (resp, "Location", redirect_uri);
998  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
999  cleanup_handle (handle);
1000  GNUNET_free (redirect_uri);
1001  GNUNET_free (ticket_str);
1002  GNUNET_free (code_string);
1003 }
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.
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const char *nonce_str, const char *code_challenge)
Builds an OIDC authorization code including a reclaim ticket and nonce.
Definition: oidc_helper.c:441
#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:1296
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
char * state
The OIDC state.
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_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
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:936
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:

◆ attribute_list_merge()

static struct GNUNET_RECLAIM_AttributeList* attribute_list_merge ( struct GNUNET_RECLAIM_AttributeList list_a,
struct GNUNET_RECLAIM_AttributeList list_b 
)
static

Attribute already in list

Attribute already in list

Definition at line 1007 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_AttributeListEntry::attribute, credential, GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_Attribute::data, GNUNET_RECLAIM_Attribute::data_size, GNUNET_RECLAIM_Attribute::flag, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_RECLAIM_attribute_new(), GNUNET_RECLAIM_id_is_equal, GNUNET_YES, GNUNET_RECLAIM_Attribute::id, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_AttributeList::list_tail, GNUNET_RECLAIM_Attribute::name, GNUNET_RECLAIM_AttributeListEntry::next, and GNUNET_RECLAIM_Attribute::type.

Referenced by oidc_cred_collect_finished_cb().

1009 {
1010  struct GNUNET_RECLAIM_AttributeList *merged_list;
1011  struct GNUNET_RECLAIM_AttributeListEntry *le_a;
1012  struct GNUNET_RECLAIM_AttributeListEntry *le_b;
1013  struct GNUNET_RECLAIM_AttributeListEntry *le_m;
1014 
1015  merged_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1016  for (le_a = list_a->list_head; NULL != le_a; le_a = le_a->next)
1017  {
1020  &le_a->attribute->
1021  credential,
1022  le_a->attribute->type,
1023  le_a->attribute->data,
1024  le_a->attribute->data_size);
1025  le_m->attribute->id = le_a->attribute->id;
1026  le_m->attribute->flag = le_a->attribute->flag;
1027  le_m->attribute->credential = le_a->attribute->credential;
1028  GNUNET_CONTAINER_DLL_insert (merged_list->list_head,
1029  merged_list->list_tail,
1030  le_m);
1031  }
1032  le_m = NULL;
1033  for (le_b = list_b->list_head; NULL != le_b; le_b = le_b->next)
1034  {
1035  for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1036  {
1038  &le_b->attribute->id))
1039  break;
1040  }
1041  if (NULL != le_m)
1042  continue;
1045  &le_b->attribute->
1046  credential,
1047  le_b->attribute->type,
1048  le_b->attribute->data,
1049  le_b->attribute->data_size);
1050  le_m->attribute->id = le_b->attribute->id;
1051  le_m->attribute->flag = le_b->attribute->flag;
1052  le_m->attribute->credential = le_b->attribute->credential;
1053  GNUNET_CONTAINER_DLL_insert (merged_list->list_head,
1054  merged_list->list_tail,
1055  le_m);
1056  }
1057  return merged_list;
1058 }
struct GNUNET_RECLAIM_Attribute * GNUNET_RECLAIM_attribute_new(const char *attr_name, const struct GNUNET_RECLAIM_Identifier *credential, uint32_t type, const void *data, size_t data_size)
Create a new attribute claim.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
const char * name
The name of the attribute.
A list of GNUNET_RECLAIM_Attribute structures.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
struct GNUNET_RECLAIM_AttributeListEntry * list_tail
List tail.
struct GNUNET_RECLAIM_Identifier id
ID.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
static struct GNUNET_RECLAIM_Identifier credential
Credential ID.
#define GNUNET_RECLAIM_id_is_equal(a, b)
const void * data
Binary value stored as attribute value.
uint32_t type
Type of Claim.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_cred_collect_finished_cb()

static void oidc_cred_collect_finished_cb ( void *  cls)
static

Definition at line 1062 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, RequestHandle::attr_userinfo_list, GNUNET_RECLAIM_AttributeListEntry::attribute, attribute_list_merge(), OIDC_Variables::client_pkey, RequestHandle::cred_it, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_ticket_issue(), handle, RequestHandle::idp_op, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_Attribute::name, GNUNET_RECLAIM_AttributeListEntry::next, RequestHandle::oidc, oidc_ticket_issue_cb(), and RequestHandle::priv_key.

Referenced by oidc_attr_collect_finished_cb().

1063 {
1064  struct RequestHandle *handle = cls;
1065  struct GNUNET_RECLAIM_AttributeList *merged_list;
1066  struct GNUNET_RECLAIM_AttributeListEntry *le_m;
1067 
1068  handle->cred_it = NULL;
1069  merged_list = attribute_list_merge (handle->attr_idtoken_list,
1070  handle->attr_userinfo_list);
1071  for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1073  "List Attibute in ticket to issue: %s\n",
1074  le_m->attribute->name);
1076  &handle->priv_key,
1077  &handle->oidc->client_pkey,
1078  merged_list,
1080  handle);
1082 }
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
static struct GNUNET_RECLAIM_AttributeList * attribute_list_merge(struct GNUNET_RECLAIM_AttributeList *list_a, struct GNUNET_RECLAIM_AttributeList *list_b)
void GNUNET_RECLAIM_attribute_list_destroy(struct GNUNET_RECLAIM_AttributeList *attrs)
Destroy claim list.
const char * name
The name of the attribute.
A list of GNUNET_RECLAIM_Attribute structures.
struct OIDC_Variables * oidc
OIDC variables.
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
The request handle.
struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey
The RP client public key.
static void oidc_ticket_issue_cb(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_PresentationList *pres)
Issues ticket and redirects to relying party with the authorization code as parameter.
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_AttributeList *attrs, GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls)
Issues a ticket to a relying party.
Definition: reclaim_api.c:1542
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
struct GNUNET_RECLAIM_CredentialIterator * cred_it
Credential iterator.
#define GNUNET_log(kind,...)
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key
Pointer to ego private key.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_cred_collect()

static void oidc_cred_collect ( void *  cls,
const struct GNUNET_CRYPTO_EcdsaPublicKey identity,
const struct GNUNET_RECLAIM_Credential cred 
)
static

Collects all attributes for an ego if in scope parameter.

Credential already in list

Credential matches for attribute, add

Definition at line 1089 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, GNUNET_RECLAIM_AttributeListEntry::attribute, RequestHandle::cred_it, GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_CredentialListEntry::credential, RequestHandle::credentials, GNUNET_RECLAIM_Credential::data, GNUNET_RECLAIM_Credential::data_size, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_NO, GNUNET_RECLAIM_credential_new(), GNUNET_RECLAIM_get_credentials_next(), GNUNET_RECLAIM_id_is_equal, handle, GNUNET_RECLAIM_Credential::id, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_CredentialList::list_head, GNUNET_RECLAIM_CredentialList::list_tail, GNUNET_RECLAIM_Credential::name, GNUNET_RECLAIM_AttributeListEntry::next, GNUNET_RECLAIM_CredentialListEntry::next, and GNUNET_RECLAIM_Credential::type.

Referenced by oidc_attr_collect_finished_cb().

1092 {
1093  struct RequestHandle *handle = cls;
1096 
1097  for (ale = handle->credentials->list_head; NULL != ale; ale = ale->next)
1098  {
1100  &cred->id))
1101  continue;
1104  return;
1105  }
1106 
1107  for (le = handle->attr_idtoken_list->list_head; NULL != le; le = le->next)
1108  {
1110  &cred->id))
1111  continue;
1115  cred->type,
1116  cred->data,
1117  cred->data_size);
1119  handle->credentials->list_tail,
1120  ale);
1121  }
1123 }
void GNUNET_RECLAIM_get_credentials_next(struct GNUNET_RECLAIM_CredentialIterator *ait)
Calls the record processor specified in GNUNET_RECLAIM_get_credentials_start for the next record...
Definition: reclaim_api.c:1487
struct GNUNET_RECLAIM_Identifier id
ID.
uint32_t type
Type/Format of Claim.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_RECLAIM_Credential * credential
The credential.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_CredentialListEntry * list_tail
List tail.
struct GNUNET_RECLAIM_CredentialListEntry * next
DLL.
const void * data
Binary value stored as credential value.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
The request handle.
struct GNUNET_RECLAIM_CredentialList * credentials
Credentials.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_CredentialListEntry * list_head
List head.
const char * name
The name of the credential.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
struct GNUNET_RECLAIM_CredentialIterator * cred_it
Credential iterator.
#define GNUNET_RECLAIM_id_is_equal(a, b)
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
struct GNUNET_RECLAIM_Credential * GNUNET_RECLAIM_credential_new(const char *name, uint32_t type, const void *data, size_t data_size)
Create a new credential.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ oidc_attr_collect_finished_cb()

static void oidc_attr_collect_finished_cb ( void *  cls)
static

Definition at line 1127 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, RequestHandle::attr_it, RequestHandle::cred_it, RequestHandle::credentials, do_redirect_error(), RequestHandle::edesc, RequestHandle::emsg, GNUNET_new, GNUNET_RECLAIM_get_credentials_start(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, GNUNET_RECLAIM_AttributeList::list_head, oidc_cred_collect(), oidc_cred_collect_finished_cb(), OIDC_ERROR_KEY_INVALID_SCOPE, oidc_iteration_error(), RequestHandle::priv_key, and RequestHandle::ticket_it.

Referenced by code_redirect().

1128 {
1129  struct RequestHandle *handle = cls;
1130 
1131  handle->attr_it = NULL;
1132  handle->ticket_it = NULL;
1133  if (NULL == handle->attr_idtoken_list->list_head)
1134  {
1136  handle->edesc = GNUNET_strdup ("The requested scope is not available.");
1138  return;
1139  }
1141  handle->cred_it =
1143  &handle->priv_key,
1145  handle,
1147  handle,
1149  handle);
1150 
1151 }
static void oidc_cred_collect_finished_cb(void *cls)
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_RECLAIM_CredentialIterator * GNUNET_RECLAIM_get_credentials_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_RECLAIM_CredentialResult proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
List all credentials for a local identity.
Definition: reclaim_api.c:1440
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
The request handle.
struct GNUNET_RECLAIM_CredentialList * credentials
Credentials.
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:1296
struct GNUNET_RECLAIM_TicketIterator * ticket_it
Ticket iterator.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
struct GNUNET_RECLAIM_CredentialIterator * cred_it
Credential iterator.
static void oidc_cred_collect(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred)
Collects all attributes for an ego if in scope parameter.
A list of GNUNET_RECLAIM_Credential structures.
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
static void oidc_iteration_error(void *cls)
Does internal server error when iteration failed.
struct GNUNET_RECLAIM_AttributeListEntry * 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:

◆ attr_in_claims_request()

static int attr_in_claims_request ( struct RequestHandle handle,
const char *  attr_name,
const char *  claims_parameter 
)
static

Check if attribute is requested through a scope

Try claims parameter if not in scope

Definition at line 1155 of file plugin_rest_openid_connect.c.

References OIDC_Variables::claims, GNUNET_NO, GNUNET_YES, Plugin::key, RequestHandle::oidc, OIDC_check_scopes_for_claim_request(), ret, OIDC_Variables::scope, and value.

Referenced by attr_in_idtoken_request(), and attr_in_userinfo_request().

1158 {
1159  int ret = GNUNET_NO;
1160  json_t *root;
1161  json_error_t error;
1162  json_t *claims_j;
1163  const char *key;
1164  json_t *value;
1165 
1168  attr_name))
1169  return GNUNET_YES;
1170 
1172  if ((NULL != handle->oidc->claims) &&
1173  (GNUNET_YES != ret))
1174  {
1175  root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error);
1176  claims_j = json_object_get (root, claims_parameter);
1177  /* obj is a JSON object */
1178  if (NULL != claims_j)
1179  {
1180  json_object_foreach (claims_j, key, value) {
1181  if (0 != strcmp (attr_name, key))
1182  continue;
1183  ret = GNUNET_YES;
1184  break;
1185  }
1186  }
1187  json_decref (root);
1188  }
1189  return ret;
1190 }
char * scope
The list of oidc scopes.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct OIDC_Variables * oidc
OIDC variables.
enum GNUNET_GenericReturnValue OIDC_check_scopes_for_claim_request(const char *scopes, const char *attr)
Checks if a claim is implicitly requested through standard scope(s) or explicitly through non-standar...
Definition: oidc_helper.c:787
static char * value
Value of the record to add/remove.
static char * attr_name
The attribute.
char * claims
The OIDC claims.
struct GNUNET_HashCode key
The key used in the DHT.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ attr_in_idtoken_request()

static int attr_in_idtoken_request ( struct RequestHandle handle,
const char *  attr_name 
)
static

Definition at line 1194 of file plugin_rest_openid_connect.c.

References attr_in_claims_request().

Referenced by oidc_attr_collect().

1196 {
1197  return attr_in_claims_request (handle, attr_name, "id_token");
1198 }
static char * attr_name
The attribute.
static int attr_in_claims_request(struct RequestHandle *handle, const char *attr_name, const char *claims_parameter)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ attr_in_userinfo_request()

static int attr_in_userinfo_request ( struct RequestHandle handle,
const char *  attr_name 
)
static

Definition at line 1202 of file plugin_rest_openid_connect.c.

References attr_in_claims_request().

Referenced by oidc_attr_collect().

1204 {
1205  return attr_in_claims_request (handle, attr_name, "userinfo");
1206 }
static char * attr_name
The attribute.
static int attr_in_claims_request(struct RequestHandle *handle, const char *attr_name, const char *claims_parameter)
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 attr 
)
static

Collects all attributes for an ego if in scope parameter.

Definition at line 1213 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_idtoken_list, attr_in_idtoken_request(), attr_in_userinfo_request(), RequestHandle::attr_it, RequestHandle::attr_userinfo_list, GNUNET_RECLAIM_AttributeListEntry::attribute, GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_Attribute::data, GNUNET_RECLAIM_Attribute::data_size, GNUNET_RECLAIM_Attribute::flag, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_RECLAIM_attribute_new(), GNUNET_RECLAIM_get_attributes_next(), GNUNET_YES, handle, GNUNET_RECLAIM_Attribute::id, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_AttributeList::list_tail, GNUNET_RECLAIM_Attribute::name, and GNUNET_RECLAIM_Attribute::type.

Referenced by code_redirect().

1216 {
1217  struct RequestHandle *handle = cls;
1219  if (GNUNET_YES == attr_in_idtoken_request (handle, attr->name))
1220  {
1223  &attr->credential,
1224  attr->type,
1225  attr->data,
1226  attr->data_size);
1227  le->attribute->id = attr->id;
1228  le->attribute->flag = attr->flag;
1229  le->attribute->credential = attr->credential;
1231  handle->attr_idtoken_list->list_tail,
1232  le);
1233  }
1234  if (GNUNET_YES == attr_in_userinfo_request (handle, attr->name))
1235  {
1238  &attr->credential,
1239  attr->type,
1240  attr->data,
1241  attr->data_size);
1242  le->attribute->id = attr->id;
1243  le->attribute->flag = attr->flag;
1244  le->attribute->credential = attr->credential;
1246  handle->attr_userinfo_list->list_tail,
1247  le);
1248  }
1249 
1251 }
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
struct GNUNET_RECLAIM_Attribute * GNUNET_RECLAIM_attribute_new(const char *attr_name, const struct GNUNET_RECLAIM_Identifier *credential, uint32_t type, const void *data, size_t data_size)
Create a new attribute claim.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
const char * name
The name of the attribute.
#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:1377
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
The request handle.
struct GNUNET_RECLAIM_AttributeListEntry * list_tail
List tail.
static int attr_in_userinfo_request(struct RequestHandle *handle, const char *attr_name)
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_Identifier id
ID.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
const void * data
Binary value stored as attribute value.
static int attr_in_idtoken_request(struct RequestHandle *handle, const char *attr_name)
uint32_t type
Type of Claim.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
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 1258 of file plugin_rest_openid_connect.c.

References GNUNET_TIME_Absolute::abs_value_us, RequestHandle::attr_idtoken_list, RequestHandle::attr_it, RequestHandle::attr_userinfo_list, do_redirect_error(), RequestHandle::edesc, EgoEntry::ego, RequestHandle::ego_entry, 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_get_attributes_start(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_TIME_absolute_get(), GNUNET_YES, handle, OIDC_Variables::login_identity, login_redirect(), EgoEntry::next, RequestHandle::oidc, oidc_attr_collect(), oidc_attr_collect_finished_cb(), OIDC_ERROR_KEY_INVALID_COOKIE, oidc_iteration_error(), and RequestHandle::priv_key.

Referenced by build_redirect().

1259 {
1260  struct RequestHandle *handle = cls;
1261  struct GNUNET_TIME_Absolute current_time;
1262  struct GNUNET_TIME_Absolute *relog_time;
1264  struct GNUNET_CRYPTO_EcdsaPublicKey ego_pkey;
1265  struct GNUNET_HashCode cache_key;
1266  char *identity_cookie;
1267 
1268  GNUNET_asprintf (&identity_cookie,
1269  "Identity=%s",
1270  handle->oidc->login_identity);
1271  GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1272  GNUNET_free (identity_cookie);
1273  // No login time for identity -> redirect to login
1274  if (GNUNET_YES ==
1276  {
1277  relog_time =
1279  current_time = GNUNET_TIME_absolute_get ();
1280  // 30 min after old login -> redirect to login
1281  if (current_time.abs_value_us <= relog_time->abs_value_us)
1282  {
1283  if (GNUNET_OK !=
1285  ->login_identity,
1286  strlen (
1287  handle->oidc
1288  ->login_identity),
1289  &pubkey))
1290  {
1292  handle->edesc =
1293  GNUNET_strdup ("The cookie of a login identity is not valid");
1295  return;
1296  }
1297  // iterate over egos and compare their public key
1298  for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1299  handle->ego_entry = handle->ego_entry->next)
1300  {
1301  GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1302  if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1303  {
1304  handle->priv_key =
1306  handle->attr_idtoken_list =
1308  handle->attr_userinfo_list =
1310  handle->attr_it =
1312  &handle->priv_key,
1314  handle,
1316  handle,
1318  handle);
1319  return;
1320  }
1321  }
1323  return;
1324  }
1325  }
1326 }
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
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:1331
static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey
Public key of the zone to look in.
struct GNUNET_RECLAIM_AttributeIterator * attr_it
Attribute iterator.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:595
A list of GNUNET_RECLAIM_Attribute structures.
#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.
static void oidc_attr_collect(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr)
Collects all attributes for an ego if in scope parameter.
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:1296
#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
static struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
#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:366
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
struct GNUNET_RECLAIM_AttributeList * attr_idtoken_list
Attribute claim list for id_token.
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.
struct EgoEntry * ego_entry
IDENTITY Operation.
static void oidc_iteration_error(void *cls)
Does internal server error when iteration failed.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:608
struct EgoEntry * next
DLL.
static struct EgoEntry * ego_head
Ego list.
#define GNUNET_free(ptr)
Wrapper around free.
static void oidc_attr_collect_finished_cb(void *cls)
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 1330 of file plugin_rest_openid_connect.c.

References cleanup_handle(), 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().

1331 {
1332  struct RequestHandle *handle = cls;
1333  struct MHD_Response *resp;
1334  char *redirect_uri;
1335 
1336  if (GNUNET_YES == handle->oidc->user_cancelled)
1337  {
1338  if ((NULL != handle->redirect_prefix) &&
1339  (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1340  {
1341  GNUNET_asprintf (&redirect_uri,
1342  "%s.%s/%s?error=%s&error_description=%s&state=%s",
1343  handle->redirect_prefix,
1344  handle->tld,
1345  handle->redirect_suffix,
1346  "access_denied",
1347  "User denied access",
1348  handle->oidc->state);
1349  }
1350  else
1351  {
1352  GNUNET_asprintf (&redirect_uri,
1353  "%s?error=%s&error_description=%s&state=%s",
1354  handle->oidc->redirect_uri,
1355  "access_denied",
1356  "User denied access",
1357  handle->oidc->state);
1358  }
1359  resp = GNUNET_REST_create_response ("");
1360  MHD_add_response_header (resp, "Location", redirect_uri);
1361  handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1362  cleanup_handle (handle);
1363  GNUNET_free (redirect_uri);
1364  return;
1365  }
1367 }
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:1296
char * tld
The tld for redirect.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
static void code_redirect(void *cls)
Checks time and cookie and redirects accordingly.
char * state
The OIDC state.
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_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 1371 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().

1374 {
1375  struct RequestHandle *handle = cls;
1376  char *tmp;
1377  char *tmp_key_str;
1378  char *pos;
1379  struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1380 
1381  handle->gns_op = NULL;
1382  if (0 == rd_count)
1383  {
1385  handle->edesc =
1386  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1388  return;
1389  }
1390  for (int i = 0; i < rd_count; i++)
1391  {
1392  if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1393  continue;
1394  if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1395  continue;
1396  tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1397  if (NULL == strstr (tmp, handle->oidc->client_id))
1398  {
1400  "Redirect uri %s does not contain client_id %s\n",
1401  tmp,
1402  handle->oidc->client_id);
1403  }
1404  else
1405  {
1406  pos = strrchr (tmp, (unsigned char) '.');
1407  if (NULL == pos)
1408  {
1410  "Redirect uri %s contains client_id but is malformed\n",
1411  tmp);
1412  GNUNET_free (tmp);
1413  continue;
1414  }
1415  *pos = '\0';
1416  handle->redirect_prefix = GNUNET_strdup (tmp);
1417  tmp_key_str = pos + 1;
1418  pos = strchr (tmp_key_str, (unsigned char) '/');
1419  if (NULL == pos)
1420  {
1422  "Redirect uri %s contains client_id but is malformed\n",
1423  tmp);
1424  GNUNET_free (tmp);
1425  continue;
1426  }
1427  *pos = '\0';
1428  handle->redirect_suffix = GNUNET_strdup (pos + 1);
1429 
1430  GNUNET_STRINGS_string_to_data (tmp_key_str,
1431  strlen (tmp_key_str),
1432  &redirect_zone,
1433  sizeof(redirect_zone));
1434  }
1436  GNUNET_free (tmp);
1437  return;
1438  }
1440  handle->edesc =
1441  GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1443 }
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:1296
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:971
#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 1450 of file plugin_rest_openid_connect.c.

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

1451 {
1452  struct RequestHandle *handle = cls;
1453 
1454  /* Lookup client redirect uri to verify request */
1455  handle->gns_op =
1458  &handle->oidc->client_pkey,
1462  handle);
1463 }
static struct GNUNET_GNS_Handle * gns_handle
GNS handle.
#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.
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 1467 of file plugin_rest_openid_connect.c.

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

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

1468 {
1469  struct GNUNET_HashCode hc;
1470  char *value;
1471  char *res;
1472 
1473  GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1475  ->url_param_map,
1476  &hc))
1477  return NULL;
1478  value =
1480  if (NULL == value)
1481  return NULL;
1482  GNUNET_STRINGS_urldecode (value, strlen (value), &res);
1483  return res;
1484 }
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition: strings.c:2102
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)...
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.
static int res
struct GNUNET_HashCode key
The key used in the DHT.
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 1494 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().

1495 {
1496  struct RequestHandle *handle = cls;
1497  struct GNUNET_HashCode cache_key;
1498 
1499  char *expected_scope;
1500  char delimiter[] = " ";
1501  int number_of_ignored_parameter, iterator;
1502 
1503 
1504  // REQUIRED value: redirect_uri
1505  handle->oidc->redirect_uri =
1507  if (NULL == handle->oidc->redirect_uri)
1508  {
1510  handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1512  return;
1513  }
1514 
1515  // REQUIRED value: response_type
1516  handle->oidc->response_type =
1518  if (NULL == handle->oidc->response_type)
1519  {
1521  handle->edesc = GNUNET_strdup ("missing parameter response_type");
1523  return;
1524  }
1525 
1526  // REQUIRED value: scope
1527  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1528  if (NULL == handle->oidc->scope)
1529  {
1531  handle->edesc = GNUNET_strdup ("missing parameter scope");
1533  return;
1534  }
1535 
1536  // OPTIONAL value: nonce
1537  handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY);
1538 
1539  // OPTIONAL value: claims
1540  handle->oidc->claims = get_url_parameter_copy (handle, OIDC_CLAIMS_KEY);
1541 
1542  // TODO check other values if needed
1543  number_of_ignored_parameter =
1544  sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1545  for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1546  {
1548  strlen (OIDC_ignored_parameter_array[iterator]),
1549  &cache_key);
1550  if (GNUNET_YES ==
1552  ->url_param_map,
1553  &cache_key))
1554  {
1556  GNUNET_asprintf (&handle->edesc,
1557  "Server will not handle parameter: %s",
1558  OIDC_ignored_parameter_array[iterator]);
1560  return;
1561  }
1562  }
1563 
1564  // We only support authorization code flows.
1565  if (0 != strcmp (handle->oidc->response_type,
1567  {
1569  handle->edesc = GNUNET_strdup ("The authorization server does not support "
1570  "obtaining this authorization code.");
1572  return;
1573  }
1574 
1575  // Checks if scope contains 'openid'
1576  expected_scope = GNUNET_strdup (handle->oidc->scope);
1577  char *test;
1578  test = strtok (expected_scope, delimiter);
1579  while (NULL != test)
1580  {
1581  if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1582  break;
1583  test = strtok (NULL, delimiter);
1584  }
1585  if (NULL == test)
1586  {
1588  handle->edesc =
1589  GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1591  GNUNET_free (expected_scope);
1592  return;
1593  }
1594 
1595  GNUNET_free (expected_scope);
1596  if ((NULL == handle->oidc->login_identity) &&
1597  (GNUNET_NO == handle->oidc->user_cancelled))
1599  else
1601 }
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.
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:1296
#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_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 1608 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().

1609 {
1610  struct RequestHandle *handle = cls;
1612 
1613  if (GNUNET_OK !=
1615  {
1616  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1617  return;
1618  }
1619  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1620  handle->tld = GNUNET_strdup (option + 1);
1621 }
static char * pkey
Public key of the zone to look in, in ASCII.
#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:366
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 1632 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, 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 rest_identity_process_request().

1635 {
1636  struct RequestHandle *handle = cls;
1637  struct EgoEntry *tmp_ego;
1638  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1640 
1642 
1643  // RECOMMENDED value: state - REQUIRED for answers
1644  handle->oidc->state = get_url_parameter_copy (handle, OIDC_STATE_KEY);
1645 
1646  // REQUIRED value: client_id
1648  if (NULL == handle->oidc->client_id)
1649  {
1651  handle->edesc = GNUNET_strdup ("missing parameter client_id");
1652  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1654  return;
1655  }
1656 
1657  // OPTIONAL value: code_challenge
1658  handle->oidc->code_challenge = get_url_parameter_copy (handle,
1660  if (NULL == handle->oidc->code_challenge)
1661  {
1663  "OAuth authorization request does not contain PKCE parameters!\n");
1664  }
1665 
1666  if (GNUNET_OK !=
1668  strlen (
1669  handle->oidc->client_id),
1670  &handle->oidc->client_pkey))
1671  {
1673  handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1674  "authorization code using this method.");
1675  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1677  return;
1678  }
1679 
1680  // If we know this identity, translated the corresponding TLD
1681  // TODO: We might want to have a reverse lookup functionality for TLDs?
1682  for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1683  {
1684  priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1686  if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1687  {
1688  handle->tld = GNUNET_strdup (tmp_ego->identifier);
1689  handle->ego_entry = ego_tail;
1690  }
1691  }
1692  handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
1693  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n", handle->oidc->scope);
1694  if (NULL == handle->tld)
1696  if (NULL == handle->tld)
1697  handle->tld = GNUNET_strdup (handle->oidc->client_id);
1699 }
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.
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:595
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.
static struct EgoEntry * ego_tail
Ego list.
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:1296
#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:176
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:366
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.
static struct EgoEntry * ego_head
Ego list.
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 1710 of file plugin_rest_openid_connect.c.

References cleanup_handle(), 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_log, GNUNET_memcpy, GNUNET_new, GNUNET_REST_create_response(), 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 rest_identity_process_request().

1713 {
1714  struct MHD_Response *resp = GNUNET_REST_create_response ("");
1715  struct RequestHandle *handle = cls;
1716  struct GNUNET_HashCode cache_key;
1717  struct GNUNET_TIME_Absolute *current_time;
1718  struct GNUNET_TIME_Absolute *last_time;
1719  char *cookie;
1720  char *header_val;
1721  json_t *root;
1722  json_error_t error;
1723  json_t *identity;
1724  char term_data[handle->rest_handle->data_size + 1];
1725 
1726  term_data[handle->rest_handle->data_size] = '\0';
1727  GNUNET_memcpy (term_data,
1728  handle->rest_handle->data,
1729  handle->rest_handle->data_size);
1730  root = json_loads (term_data, JSON_DECODE_ANY, &error);
1731  identity = json_object_get (root, "identity");
1732  if (! json_is_string (identity))
1733  {
1735  "Error parsing json string from %s\n",
1736  term_data);
1737  handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1738  json_decref (root);
1739  cleanup_handle (handle);
1740  return;
1741  }
1742  GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1743  GNUNET_asprintf (&header_val,
1744  "%s;Max-Age=%d",
1745  cookie,
1747  MHD_add_response_header (resp, "Set-Cookie", header_val);
1748  MHD_add_response_header (resp, "Access-Control-Allow-Methods", "POST");
1749  GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1750 
1751  if (0 != strcmp (json_string_value (identity), "Denied"))
1752  {
1753  current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1754  *current_time = GNUNET_TIME_relative_to_absolute (
1757  last_time =
1759  GNUNET_free (last_time);
1761  &cache_key,
1762  current_time,
1764  }
1765  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1766  GNUNET_free (cookie);
1767  GNUNET_free (header_val);
1768  json_decref (root);
1769  cleanup_handle (handle);
1770 }
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_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
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
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
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.
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:

◆ parse_credentials_basic_auth()

static int parse_credentials_basic_auth ( struct RequestHandle handle,
char **  client_id,
char **  client_secret 
)
static

Definition at line 1774 of file plugin_rest_openid_connect.c.

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_STRINGS_base64_decode(), GNUNET_SYSERR, GNUNET_REST_RequestHandle::header_param_map, OIDC_AUTHORIZATION_HEADER_KEY, and RequestHandle::rest_handle.

Referenced by check_authorization().

1777 {
1778  struct GNUNET_HashCode cache_key;
1779  char *authorization;
1780  char *credentials;
1781  char *basic_authorization;
1782  char *client_id_tmp;
1783  char *pass;
1784 
1787  &cache_key);
1789  ->header_param_map,
1790  &cache_key))
1791  return GNUNET_SYSERR;
1792  authorization =
1794  &cache_key);
1795 
1796  // split header in "Basic" and [content]
1797  credentials = strtok (authorization, " ");
1798  if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1799  return GNUNET_SYSERR;
1800  credentials = strtok (NULL, " ");
1801  if (NULL == credentials)
1802  return GNUNET_SYSERR;
1803  GNUNET_STRINGS_base64_decode (credentials,
1804  strlen (credentials),
1805  (void **) &basic_authorization);
1806 
1807  if (NULL == basic_authorization)
1808  return GNUNET_SYSERR;
1809  client_id_tmp = strtok (basic_authorization, ":");
1810  if (NULL == client_id_tmp)
1811  {
1812  GNUNET_free (basic_authorization);
1813  return GNUNET_SYSERR;
1814  }
1815  pass = strtok (NULL, ":");
1816  if (NULL == pass)
1817  {
1818  GNUNET_free (basic_authorization);
1819  return GNUNET_SYSERR;
1820  }
1821  *client_id = strdup (client_id_tmp);
1822  *client_secret = strdup (pass);
1823  GNUNET_free (basic_authorization);
1824  return GNUNET_OK;
1825 }
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)...
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.
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.
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1977
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_credentials_post_body()

static int parse_credentials_post_body ( struct RequestHandle handle,
char **  client_id,
char **  client_secret 
)
static

Definition at line 1829 of file plugin_rest_openid_connect.c.

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, RequestHandle::rest_handle, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by check_authorization().

1832 {
1833  struct GNUNET_HashCode cache_key;
1834  char *client_id_tmp;
1835  char *pass;
1836 
1837  GNUNET_CRYPTO_hash ("client_id",
1838  strlen ("client_id"),
1839  &cache_key);
1841  ->url_param_map,
1842  &cache_key))
1843  return GNUNET_SYSERR;
1844  client_id_tmp = GNUNET_CONTAINER_multihashmap_get (
1845  handle->rest_handle->url_param_map,
1846  &cache_key);
1847  if (NULL == client_id_tmp)
1848  return GNUNET_SYSERR;
1849  *client_id = strdup (client_id_tmp);
1850  GNUNET_CRYPTO_hash ("client_secret",
1851  strlen ("client_secret"),
1852  &cache_key);
1854  ->url_param_map,
1855  &cache_key))
1856  return GNUNET_SYSERR;
1858  &cache_key);
1859  if (NULL == pass)
1860  return GNUNET_SYSERR;
1861  *client_secret = strdup (pass);
1862  return GNUNET_OK;
1863 }
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)...
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_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.
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

Allow public clients with PKCE

Definition at line 1867 of file plugin_rest_openid_connect.c.

References RequestHandle::edesc, RequestHandle::ego_entry, RequestHandle::emsg, get_url_parameter_copy(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_SYSERR, GNUNET_YES, EgoEntry::keystring, EgoEntry::next, OIDC_CLIENT_ID_KEY, OIDC_CODE_VERIFIER_KEY, OIDC_ERROR_KEY_INVALID_CLIENT, OIDC_ERROR_KEY_SERVER_ERROR, parse_credentials_basic_auth(), parse_credentials_post_body(), RequestHandle::public_client, and RequestHandle::response_code.

Referenced by token_endpoint().

1869 {
1870  char *expected_pass;
1871  char *received_cid;
1872  char *received_cpw;
1873  char *pkce_cv;
1874 
1875  if (GNUNET_OK == parse_credentials_basic_auth (handle,
1876  &received_cid,
1877  &received_cpw))
1878  {
1880  "Received client credentials in HTTP AuthZ header\n");
1881  }
1882  else if (GNUNET_OK == parse_credentials_post_body (handle,
1883  &received_cid,
1884  &received_cpw))
1885  {
1887  "Received client credentials in POST body\n");
1888  }
1889  else
1890  {
1892  pkce_cv = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY);
1893  if (NULL == pkce_cv)
1894  {
1896  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1897  return GNUNET_SYSERR;
1898  }
1899  handle->public_client = GNUNET_YES;
1900  GNUNET_free (pkce_cv);
1901  received_cid = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY);
1902  GNUNET_STRINGS_string_to_data (received_cid,
1903  strlen (received_cid),
1904  cid,
1905  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1906  GNUNET_free (received_cid);
1907  return GNUNET_OK;
1908 
1909  }
1910 
1911  // check client password
1913  "reclaim-rest-plugin",
1914  "OIDC_CLIENT_SECRET",
1915  &expected_pass))
1916  {
1917  if (0 != strcmp (expected_pass, received_cpw))
1918  {
1919  GNUNET_free (expected_pass);
1921  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1922  return GNUNET_SYSERR;
1923  }
1924  GNUNET_free (expected_pass);
1925  }
1926  else
1927  {
1929  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1930  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1931  return GNUNET_SYSERR;
1932  }
1933  // check client_id
1934  for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1935  handle->ego_entry = handle->ego_entry->next)
1936  {
1937  if (0 == strcmp (handle->ego_entry->keystring, received_cid))
1938  break;
1939  }
1940  if (NULL == handle->ego_entry)
1941  {
1942  GNUNET_free (received_cpw);
1943  GNUNET_free (received_cid);
1945  handle->response_code = MHD_HTTP_UNAUTHORIZED;
1946  return GNUNET_SYSERR;
1947  }
1948  GNUNET_STRINGS_string_to_data (received_cid,
1949  strlen (received_cid),
1950  cid,
1951  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1952 
1953  GNUNET_free (received_cpw);
1954  GNUNET_free (received_cid);
1955  return GNUNET_OK;
1956 }
static int parse_credentials_basic_auth(struct RequestHandle *handle, char **client_id, char **client_secret)
static int parse_credentials_post_body(struct RequestHandle *handle, char **client_id, char **client_secret)
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
char * edesc
Error response description.
char * emsg
Error response message.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
#define OIDC_CODE_VERIFIER_KEY
OIDC PKCE code verifier.
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 * keystring
Public key string.
#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...
#define GNUNET_log(kind,...)
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
struct EgoEntry * ego_entry
IDENTITY Operation.
int public_client
Public client.
struct EgoEntry * next
DLL.
static struct EgoEntry * ego_head
Ego list.
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:971
#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 1960 of file plugin_rest_openid_connect.c.

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

Referenced by token_endpoint(), and userinfo_endpoint().

1962 {
1963  struct EgoEntry *ego_entry;
1964  struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1965 
1966  for (ego_entry = ego_head; NULL != ego_entry;
1967  ego_entry = ego_entry->next)
1968  {
1969  GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
1970  if (0 == GNUNET_memcmp (&pub_key, test_key))
1971  return ego_entry;
1972  }
1973  return NULL;
1974 }
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:608
struct EgoEntry * next
DLL.
static struct EgoEntry * ego_head
Ego list.
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 1985 of file plugin_rest_openid_connect.c.

References GNUNET_RECLAIM_Ticket::audience, check_authorization(), cleanup_handle(), do_error(), RequestHandle::edesc, 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_log, GNUNET_OK, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_presentation_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_generate_id_token(), OIDC_GRANT_TYPE_KEY, OIDC_GRANT_TYPE_VALUE, OIDC_parse_authz_code(), RequestHandle::proc, RequestHandle::proc_cls, and RequestHandle::response_code.

Referenced by rest_identity_process_request().

1988 {
1989  struct RequestHandle *handle = cls;
1990  const struct EgoEntry *ego_entry;
1991  struct GNUNET_TIME_Relative expiration_time;
1992  struct GNUNET_RECLAIM_AttributeList *cl = NULL;
1993  struct GNUNET_RECLAIM_PresentationList *pl = NULL;
1995  struct GNUNET_CRYPTO_EcdsaPublicKey cid;
1996  struct GNUNET_HashCode cache_key;
1997  struct MHD_Response *resp;
1998  char *grant_type;
1999  char *code;
2000  char *json_response;
2001  char *id_token;
2002  char *access_token;
2003  char *jwt_secret;
2004  char *nonce;
2005  char *code_verifier;
2006 
2007  /*
2008  * Check Authorization
2009  */
2010  if (GNUNET_SYSERR == check_authorization (handle, &cid))
2011  {
2013  "OIDC authorization for token endpoint failed\n");
2015  return;
2016  }
2017 
2018  /*
2019  * Check parameter
2020  */
2021 
2022  // TODO Do not allow multiple equal parameter names
2023  // REQUIRED grant_type
2025  strlen (OIDC_GRANT_TYPE_KEY),
2026  &cache_key);
2027  grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY);
2028  if (NULL == grant_type)
2029  {
2031  handle->edesc = GNUNET_strdup ("missing parameter grant_type");
2032  handle->response_code = MHD_HTTP_BAD_REQUEST;
2034  return;
2035  }
2036 
2037  // Check parameter grant_type == "authorization_code"
2038  if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
2039  {
2041  handle->response_code = MHD_HTTP_BAD_REQUEST;
2042  GNUNET_free (grant_type);
2044  return;
2045  }
2046  GNUNET_free (grant_type);
2047  // REQUIRED code
2048  code = get_url_parameter_copy (handle, OIDC_CODE_KEY);
2049  if (NULL == code)
2050  {
2052  handle->edesc = GNUNET_strdup ("missing parameter code");
2053  handle->response_code = MHD_HTTP_BAD_REQUEST;
2055  return;
2056  }
2057  ego_entry = find_ego (handle, &cid);
2058  if (NULL == ego_entry)
2059  {
2061  handle->edesc = GNUNET_strdup ("Unknown client");
2062  handle->response_code = MHD_HTTP_BAD_REQUEST;
2063  GNUNET_free (code);
2065  return;
2066  }
2067 
2068  // REQUIRED code verifier
2069  code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY);
2070  if (NULL == code_verifier)
2071  {
2073  "OAuth authorization request does not contain PKCE parameters!\n");
2074 
2075  }
2076 
2077  // decode code
2078  if (GNUNET_OK != OIDC_parse_authz_code (&cid, code, code_verifier, &ticket,
2079  &cl, &pl, &nonce))
2080  {
2082  handle->edesc = GNUNET_strdup ("invalid code");
2083  handle->response_code = MHD_HTTP_BAD_REQUEST;
2084  GNUNET_free (code);
2086  return;
2087  }
2088  GNUNET_free (code);
2089 
2090  // create jwt
2092  "reclaim-rest-plugin",
2093  "expiration_time",
2094  &expiration_time))
2095  {
2097  handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2098  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2100  return;
2101  }
2102 
2103 
2104  // TODO OPTIONAL acr,amr,azp
2106  "reclaim-rest-plugin",
2107  "jwt_secret",
2108  &jwt_secret))
2109  {
2111  handle->edesc = GNUNET_strdup ("No signing secret configured!");
2112  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2114  return;
2115  }
2116  id_token = OIDC_generate_id_token (&ticket.audience,
2117  &ticket.identity,
2118  cl,
2119  pl,
2120  &expiration_time,
2121  (NULL != nonce) ? nonce : NULL,
2122  jwt_secret);
2123  access_token = OIDC_access_token_new (&ticket);
2124  OIDC_build_token_response (access_token,
2125  id_token,
2126  &expiration_time,
2127  &json_response);
2128 
2129  resp = GNUNET_REST_create_response (json_response);
2130  MHD_add_response_header (resp, "Cache-Control", "no-store");
2131  MHD_add_response_header (resp, "Pragma", "no-cache");
2132  MHD_add_response_header (resp, "Content-Type", "application/json");
2133  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2136  GNUNET_free (access_token);
2137  GNUNET_free (json_response);
2138  GNUNET_free (id_token);
2139  cleanup_handle (handle);
2140 }
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.
void GNUNET_RECLAIM_attribute_list_destroy(struct GNUNET_RECLAIM_AttributeList *attrs)
Destroy claim list.
#define OIDC_GRANT_TYPE_KEY
OIDC grant_type key.
#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.
A list of GNUNET_RECLAIM_Attribute structures.
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:723
#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.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
char * emsg
Error response message.
char * OIDC_generate_id_token(const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations, const struct GNUNET_TIME_Relative *expiration_time, const char *nonce, const char *secret_key)
Create a JWT from attributes.
Definition: oidc_helper.c:324
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:1296
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
char * OIDC_access_token_new(const struct GNUNET_RECLAIM_Ticket *ticket)
Generate a new access token.
Definition: oidc_helper.c:751
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.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
A 512-bit hashcode.
int response_code
Response code.
int OIDC_parse_authz_code(const struct GNUNET_CRYPTO_EcdsaPublicKey *audience, const char *code, const char *code_verifier, struct GNUNET_RECLAIM_Ticket *ticket, struct GNUNET_RECLAIM_AttributeList **attrs, struct GNUNET_RECLAIM_PresentationList **presentations, char **nonce_str)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:579
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)
void GNUNET_RECLAIM_presentation_list_destroy(struct GNUNET_RECLAIM_PresentationList *presentations)
Destroy presentations list.
static int check_authorization(struct RequestHandle *handle, struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
static void do_error(void *cls)
Task run on error, sends error message.
A list of GNUNET_RECLAIM_Presentation structures.
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...
#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 attr,
const struct GNUNET_RECLAIM_Presentation pres 
)
static

Collects claims and stores them in handle.

already in list

Credential matches for attribute, add

Definition at line 2147 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_userinfo_list, GNUNET_RECLAIM_AttributeListEntry::attribute, cleanup_handle(), GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_Presentation::credential_id, GNUNET_RECLAIM_Attribute::data, GNUNET_RECLAIM_Presentation::data, GNUNET_RECLAIM_Attribute::data_size, GNUNET_RECLAIM_Presentation::data_size, GNUNET_RECLAIM_Attribute::flag, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_RECLAIM_attribute_new(), GNUNET_RECLAIM_id_is_equal, GNUNET_RECLAIM_presentation_new(), GNUNET_REST_create_response(), handle, GNUNET_RECLAIM_Attribute::id, GNUNET_RECLAIM_Ticket::identity, RequestHandle::idp_op, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_PresentationList::list_head, GNUNET_RECLAIM_AttributeList::list_tail, GNUNET_RECLAIM_PresentationList::list_tail, GNUNET_RECLAIM_Attribute::name, GNUNET_RECLAIM_PresentationListEntry::next, OIDC_generate_userinfo(), GNUNET_RECLAIM_PresentationListEntry::presentation, RequestHandle::presentations, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::ticket, GNUNET_RECLAIM_Attribute::type, and GNUNET_RECLAIM_Presentation::type.

Referenced by userinfo_endpoint().

2151 {
2152  struct RequestHandle *handle = cls;
2155  struct MHD_Response *resp;
2156  char *result_str;
2157  handle->idp_op = NULL;
2158 
2159  if (NULL == identity)
2160  {
2161  result_str = OIDC_generate_userinfo (&handle->ticket.identity,
2162  handle->attr_userinfo_list,
2163  handle->presentations);
2164  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str);
2165  resp = GNUNET_REST_create_response (result_str);
2166  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2167  GNUNET_free (result_str);
2168  cleanup_handle (handle);
2169  return;
2170  }
2173  &attr->credential,
2174  attr->type,
2175  attr->data,
2176  attr->data_size);
2177  ale->attribute->id = attr->id;
2178  ale->attribute->flag = attr->flag;
2179  ale->attribute->credential = attr->credential;
2181  handle->attr_userinfo_list->list_tail,
2182  ale);
2183  if (NULL == pres)
2184  return;
2185  for (atle = handle->presentations->list_head;
2186  NULL != atle; atle = atle->next)
2187  {
2189  &pres->credential_id))
2190  continue;
2191  break;
2192  }
2193  if (NULL == atle)
2194  {
2198  pres->data,
2199  pres->data_size);
2201  handle->presentations->list_tail,
2202  atle);
2203  }
2204 }
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
struct GNUNET_RECLAIM_Attribute * GNUNET_RECLAIM_attribute_new(const char *attr_name, const struct GNUNET_RECLAIM_Identifier *credential, uint32_t type, const void *data, size_t data_size)
Create a new attribute claim.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint32_t type
Type/Format of Claim.
const char * name
The name of the attribute.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
struct GNUNET_RECLAIM_PresentationListEntry * next
DLL.
struct GNUNET_RECLAIM_PresentationListEntry * list_head
List head.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
void * proc_cls
The closure of the result processor.
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
The request handle.
struct GNUNET_RECLAIM_PresentationList * presentations
Presentations.
struct GNUNET_RECLAIM_AttributeListEntry * list_tail
List tail.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct GNUNET_RECLAIM_Identifier credential_id
The credential id of which this is a presentation.
const void * data
Binary value stored as presentation value.
struct GNUNET_RECLAIM_Identifier id
ID.
size_t data_size
Number of bytes in data.
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
struct GNUNET_CRYPTO_EcdsaPublicKey identity
The ticket issuer (= the user)
size_t data_size
Number of bytes in data.
char * OIDC_generate_userinfo(const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
Generate userinfo JSON as string.
Definition: oidc_helper.c:298
struct GNUNET_RECLAIM_Presentation * presentation
The credential.
struct GNUNET_RECLAIM_Ticket ticket
A ticket.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
struct GNUNET_RECLAIM_Presentation * GNUNET_RECLAIM_presentation_new(uint32_t type, const void *data, size_t data_size)
#define GNUNET_RECLAIM_id_is_equal(a, b)
#define GNUNET_log(kind,...)
const void * data
Binary value stored as attribute value.
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
uint32_t type
Type of Claim.
struct GNUNET_RECLAIM_PresentationListEntry * list_tail
List tail.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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 2215 of file plugin_rest_openid_connect.c.

References RequestHandle::attr_userinfo_list, 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_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_RECLAIM_ticket_consume(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, GNUNET_REST_RequestHandle::header_param_map, RequestHandle::idp_op, OIDC_access_token_parse(), OIDC_AUTHORIZATION_HEADER_KEY, OIDC_ERROR_KEY_INVALID_TOKEN, RequestHandle::presentations, RequestHandle::response_code, RequestHandle::rest_handle, ticket, and RequestHandle::ticket.

Referenced by rest_identity_process_request().

2218 {
2219  // TODO expiration time
2220  struct RequestHandle *handle = cls;
2221  struct GNUNET_RECLAIM_Ticket *ticket;
2222  char delimiter[] = " ";
2223  struct GNUNET_HashCode cache_key;
2224  char *authorization;
2225  char *authorization_type;
2226  char *authorization_access_token;
2227  const struct EgoEntry *aud_ego;
2228  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
2229 
2230  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n");
2233  &cache_key);
2235  ->header_param_map,
2236  &cache_key))
2237  {
2239  handle->edesc = GNUNET_strdup ("No Access Token");
2240  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2242  return;
2243  }
2244  authorization =
2246  &cache_key);
2247 
2248  // split header in "Bearer" and access_token
2249  authorization = GNUNET_strdup (authorization);
2250  authorization_type = strtok (authorization, delimiter);
2251  if ((NULL == authorization_type) ||
2252  (0 != strcmp ("Bearer", authorization_type)))
2253  {
2255  handle->edesc = GNUNET_strdup ("No Access Token");
2256  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2258  GNUNET_free (authorization);
2259  return;
2260  }
2261  authorization_access_token = strtok (NULL, delimiter);
2262  if (NULL == authorization_access_token)
2263  {
2265  handle->edesc = GNUNET_strdup ("Access token missing");
2266  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2268  GNUNET_free (authorization);
2269  return;
2270  }
2271 
2272  if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token,
2273  &ticket))
2274  {
2276  handle->edesc = GNUNET_strdup ("The access token is invalid");
2277  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2279  GNUNET_free (authorization);
2280  return;
2281 
2282  }
2283  GNUNET_assert (NULL != ticket);
2284  handle->ticket = *ticket;
2285  GNUNET_free (ticket);
2286  aud_ego = find_ego (handle, &handle->ticket.audience);
2287  if (NULL == aud_ego)
2288  {
2290  handle->edesc = GNUNET_strdup ("The access token expired");
2291  handle->response_code = MHD_HTTP_UNAUTHORIZED;
2293  GNUNET_free (authorization);
2294  return;
2295  }
2296  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n");
2297  privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego);
2298  handle->attr_userinfo_list =
2300  handle->presentations =
2302 
2304  privkey,
2305  &handle->ticket,
2306  &consume_ticket,
2307  handle);
2308  GNUNET_free (authorization);
2309 }
struct GNUNET_RECLAIM_AttributeList * attr_userinfo_list
Attribute claim list for userinfo.
The authorization ticket.
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_AttributeTicketResult cb, void *cb_cls)
Consumes an issued ticket.
Definition: reclaim_api.c:1591
#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:595
A list of GNUNET_RECLAIM_Attribute structures.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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.
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.
struct GNUNET_RECLAIM_PresentationList * presentations
Presentations.
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:1296
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.
static struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.
struct GNUNET_RECLAIM_Ticket ticket
A ticket.
A list of GNUNET_RECLAIM_Presentation structures.
struct GNUNET_CRYPTO_EcdsaPublicKey audience
The ticket audience (= relying party)
#define GNUNET_log(kind,...)
struct GNUNET_RECLAIM_Operation * idp_op
Idp Operation.
int OIDC_access_token_parse(const char *token, struct GNUNET_RECLAIM_Ticket **ticket)
Parse an access token.
Definition: oidc_helper.c:766
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
static void consume_ticket(void *cls, const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *pres)
Collects claims and stores them in handle.
#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:

◆ 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 2346 of file plugin_rest_openid_connect.c.

References EgoEntry::ego, 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, ID_REST_STATE_INIT, ID_REST_STATE_POST_INIT, EgoEntry::identifier, EgoEntry::keystring, EgoEntry::next, and state.

Referenced by libgnunet_plugin_rest_openid_connect_init().

2350 {
2351  struct EgoEntry *ego_entry;
2353 
2354  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
2355  {
2357  return;
2358  }
2359  GNUNET_assert (NULL != ego);
2360  if (ID_REST_STATE_INIT == state)
2361 
2362  {
2363  ego_entry = GNUNET_new (struct EgoEntry);
2366  ego_entry->ego = ego;
2367  ego_entry->identifier = GNUNET_strdup (identifier);
2369  ego_tail,
2370  ego_entry);
2371  return;
2372  }
2373  /* Ego renamed or added */
2374  if (identifier != NULL)
2375  {
2376  for (ego_entry = ego_head; NULL != ego_entry;
2377  ego_entry = ego_entry->next)
2378  {
2379  if (ego_entry->ego == ego)
2380  {
2381  /* Rename */
2382  GNUNET_free (ego_entry->identifier);
2383  ego_entry->identifier = GNUNET_strdup (identifier);
2384  break;
2385  }
2386  }
2387  if (NULL == ego_entry)
2388  {
2389  /* Add */
2390  ego_entry = GNUNET_new (struct EgoEntry);
2393  ego_entry->ego = ego;
2394  ego_entry->identifier = GNUNET_strdup (identifier);
2396  ego_tail,
2397  ego_entry);
2398  }
2399  }
2400  else
2401  {
2402  /* Delete */
2403  for (ego_entry = ego_head; NULL != ego_entry;
2404  ego_entry = ego_entry->next)
2405  {
2406  if (ego_entry->ego == ego)
2407  break;
2408  }
2409  if (NULL == ego_entry)
2410  return; /* Not found */
2411 
2413  ego_tail,
2414  ego_entry);
2415  GNUNET_free (ego_entry->identifier);
2416  GNUNET_free (ego_entry->keystring);
2417  GNUNET_free (ego_entry);
2418  return;
2419  }
2420 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_CRYPTO_EcdsaPrivateKey pk
Private key from command line option, or NULL.
#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 int state
The processing state.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct EgoEntry * ego_tail
Ego list.
The ego list.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
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:232
char * keystring
Public key string.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
char * identifier
Ego Identifier.
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.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:608
struct EgoEntry * next
DLL.
static struct EgoEntry * ego_head
Ego list.
#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:

◆ oidc_config_endpoint()

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

Definition at line 2424 of file plugin_rest_openid_connect.c.

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

Referenced by rest_identity_process_request().

2427 {
2428  json_t *oidc_config;
2429  json_t *auth_methods;
2430  json_t *sig_algs;
2431  json_t *scopes;
2432  json_t *response_types;
2433  json_t *sub_types;
2434  json_t *claim_types;
2435  char *oidc_config_str;
2436  struct MHD_Response *resp;
2437  struct RequestHandle *handle = cls;
2438 
2439  oidc_config = json_object ();
2440  // FIXME get from config?
2441  json_object_set_new (oidc_config,
2442  "issuer", json_string ("http://localhost:7776"));
2443  json_object_set_new (oidc_config,
2444  "authorization_endpoint",
2445  json_string ("https://api.reclaim/openid/authorize"));
2446  json_object_set_new (oidc_config,
2447  "token_endpoint",
2448  json_string ("http://localhost:7776/openid/token"));
2449  auth_methods = json_array ();
2450  json_array_append_new (auth_methods,
2451  json_string ("client_secret_basic"));
2452  json_array_append_new (auth_methods,
2453  json_string ("client_secret_post"));
2454  json_object_set_new (oidc_config,
2455  "token_endpoint_auth_methods_supported",
2456  auth_methods);
2457  sig_algs = json_array ();
2458  json_array_append_new (sig_algs,
2459  json_string ("HS512"));
2460  json_object_set_new (oidc_config,
2461  "id_token_signing_alg_values_supported",
2462  sig_algs);
2463  json_object_set_new (oidc_config,
2464  "userinfo_endpoint",
2465  json_string ("http://localhost:7776/openid/userinfo"));
2466  scopes = json_array ();
2467  json_array_append_new (scopes,
2468  json_string ("openid"));
2469  json_array_append_new (scopes,
2470  json_string ("profile"));
2471  json_array_append_new (scopes,
2472  json_string ("email"));
2473  json_array_append_new (scopes,
2474  json_string ("address"));
2475  json_array_append_new (scopes,
2476  json_string ("phone"));
2477  json_object_set_new (oidc_config,
2478  "scopes_supported",
2479  scopes);
2480  response_types = json_array ();
2481  json_array_append_new (response_types,
2482  json_string ("code"));
2483  json_object_set_new (oidc_config,
2484  "response_types_supported",
2485  response_types);
2486  sub_types = json_array ();
2487  json_array_append_new (sub_types,
2488  json_string ("public")); /* no pairwise suppport */
2489  json_object_set_new (oidc_config,
2490  "subject_types_supported",
2491  sub_types);
2492  claim_types = json_array ();
2493  json_array_append_new (claim_types,
2494  json_string ("normal"));
2495  json_array_append_new (claim_types,
2496  json_string ("aggregated"));
2497  json_object_set_new (oidc_config,
2498  "claim_types_supported",
2499  claim_types);
2500  json_object_set_new (oidc_config,
2501  "claims_parameter_supported",
2502  json_boolean (1));
2503  oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1));
2504  resp = GNUNET_REST_create_response (oidc_config_str);
2505  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2506  GNUNET_free (oidc_config_str);
2507  cleanup_handle (handle);
2508 }
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.
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:

◆ oidc_config_cors()

static void oidc_config_cors ( 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 2519 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 rest_identity_process_request().

2522 {
2523  struct MHD_Response *resp;
2524  struct RequestHandle *handle = cls;
2525 
2526  // For now, independent of path return all options
2527  resp = GNUNET_REST_create_response (NULL);
2528  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
2529  MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*");
2530  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2531  cleanup_handle (handle);
2532  return;
2533 }
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:

◆ rest_identity_process_request()

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

Definition at line 2537 of file plugin_rest_openid_connect.c.

References authorize_endpoint(), do_timeout(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_create(), GNUNET_new, GNUNET_NO, GNUNET_REST_API_NS_AUTHORIZE, GNUNET_REST_API_NS_LOGIN, GNUNET_REST_API_NS_OIDC, GNUNET_REST_API_NS_OIDC_CONFIG, GNUNET_REST_API_NS_TOKEN, GNUNET_REST_API_NS_USERINFO, GNUNET_REST_handle_request(), GNUNET_REST_HANDLER_END, GNUNET_SCHEDULER_add_delayed(), GNUNET_strdup, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, handle, login_cont(), RequestHandle::oidc, oidc_config_cors(), oidc_config_endpoint(), options_cont(), GNUNET_REST_RequestHandler::proc, RequestHandle::proc, RequestHandle::proc_cls, RequestHandle::response_code, RequestHandle::rest_handle, RequestHandle::timeout, RequestHandle::timeout_task, token_endpoint(), GNUNET_REST_RequestHandle::url, RequestHandle::url, and userinfo_endpoint().

Referenced by libgnunet_plugin_rest_openid_connect_init().

2540 {
2541  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2543  static const struct GNUNET_REST_RequestHandler handlers[] =
2544  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
2545  { MHD_HTTP_METHOD_POST,
2546  GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint }, // url-encoded
2547  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
2548  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
2549  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2550  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
2551  { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG,
2553  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG,
2554  &oidc_config_cors },
2555  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
2557 
2558  handle->oidc = GNUNET_new (struct OIDC_Variables);
2559  if (NULL == OIDC_cookie_jar_map)
2561  GNUNET_NO);
2562  handle->response_code = 0;
2564  handle->proc_cls = proc_cls;
2565  handle->proc = proc;
2566  handle->rest_handle = rest_handle;
2567  handle->url = GNUNET_strdup (rest_handle->url);
2568  handle->timeout_task =
2569  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle);
2571  requests_tail,
2572  handle);
2573  if (handle->url[strlen (handle->url) - 1] == '/')
2574  handle->url[strlen (handle->url) - 1] = '\0';
2575  if (GNUNET_NO ==
2576  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
2577  return GNUNET_NO;
2578 
2579  return GNUNET_YES;
2580 }
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static struct RequestHandle * requests_tail
DLL.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.
static struct RequestHandle * requests_head
DLL.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
struct OIDC_Variables * oidc
OIDC variables.
#define GNUNET_REST_HANDLER_END
The request handle.
#define GNUNET_REST_API_NS_OIDC_CONFIG
OIDC config.
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:1269
static void do_timeout(void *cls)
Task run on timeout, sends error message.
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
const char * url
The url as string.
static void oidc_config_cors(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
static void oidc_config_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
#define GNUNET_REST_API_NS_AUTHORIZE
Authorize endpoint.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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.