GNUnet 0.22.2
openid_plugin.c File Reference
#include "platform.h"
#include <inttypes.h>
#include <jansson.h>
#include <jose/jose.h>
#include "gnunet_util_lib.h"
#include "gnunet_gns_service.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_identity_service.h"
#include "gnunet_reclaim_lib.h"
#include "gnunet_reclaim_service.h"
#include "gnunet_rest_lib.h"
#include "gnunet_rest_plugin.h"
#include "microhttpd.h"
#include "oidc_helper.h"
#include "openid_plugin.h"
Include dependency graph for openid_plugin.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 default namestore ego. 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_JWKS   "/jwks.json"
 JSON Web Keys 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...
 
#define OIDC_JWK_RSA_FILENAME   "jwk_rsa.json"
 OIDC key store file name. More...
 
#define CONSUME_TIMEOUT
 How long to wait for a consume in userinfo endpoint. 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 json_t * read_jwk_from_file (const char *filename)
 Read the the JSON Web Key in the given file and return it. More...
 
static int write_jwk_to_file (const char *filename, json_t *jwk)
 Write the JWK to file. More...
 
static json_t * generate_jwk ()
 Generate a new RSA JSON Web Key. More...
 
static char * get_oidc_dir_path (void *cls)
 Return the path to the oidc directory path. More...
 
static char * get_oidc_jwk_path (void *cls)
 Return the path to the RSA JWK key file. 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 *presentation)
 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_PublicKey *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_PublicKey *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_PublicKey *cid)
 
static const struct EgoEntryfind_ego (struct RequestHandle *handle, struct GNUNET_CRYPTO_PublicKey *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_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *presentation)
 Collects claims and stores them in handle. More...
 
static void consume_fail (void *cls)
 
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 jwks_endpoint (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Responds to /jwks.json. 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...
 
enum GNUNET_GenericReturnValue REST_openid_process_request (void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
 Function processing the REST call. More...
 
void * REST_openid_init (const struct GNUNET_CONFIGURATION_Handle *c)
 Entry point for the plugin. More...
 
static int cleanup_hashmap (void *cls, const struct GNUNET_HashCode *key, void *value)
 
void REST_openid_done (struct GNUNET_REST_Plugin *api)
 Exit point from the plugin. More...
 

Variables

static const char * OIDC_ignored_parameter_array []
 OIDC ignored parameter array. More...
 
struct GNUNET_CONTAINER_MultiHashMapoidc_code_cache
 OIDC hashmap for cached access tokens and codes. More...
 
struct GNUNET_CONTAINER_MultiHashMapOIDC_cookie_jar_map
 OIDC hashmap that keeps track of issued cookies. More...
 
const struct GNUNET_CONFIGURATION_Handleoid_cfg
 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 GNUNET_TIME_Relative consume_timeout
 Timeout for consume call on userinfo. More...
 
json_t * oidc_jwk
 The RSA key used by the oidc endpoint. 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 openid_plugin.c.

◆ 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 openid_plugin.c.

◆ GNUNET_REST_API_NS_AUTHORIZE

#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"

Authorize endpoint.

Definition at line 58 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_TOKEN

#define GNUNET_REST_API_NS_TOKEN   "/openid/token"

Token endpoint.

Definition at line 63 of file openid_plugin.c.

◆ GNUNET_REST_API_JWKS

#define GNUNET_REST_API_JWKS   "/jwks.json"

JSON Web Keys endpoint.

Definition at line 68 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_USERINFO

#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"

UserInfo endpoint.

Definition at line 73 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_LOGIN

#define GNUNET_REST_API_NS_LOGIN   "/openid/login"

Login namespace.

Definition at line 78 of file openid_plugin.c.

◆ ID_REST_STATE_INIT

#define ID_REST_STATE_INIT   0

State while collecting all egos.

Definition at line 83 of file openid_plugin.c.

◆ ID_REST_STATE_POST_INIT

#define ID_REST_STATE_POST_INIT   1

Done collecting egos.

Definition at line 88 of file openid_plugin.c.

◆ OIDC_GRANT_TYPE_KEY

#define OIDC_GRANT_TYPE_KEY   "grant_type"

OIDC grant_type key.

Definition at line 93 of file openid_plugin.c.

◆ OIDC_GRANT_TYPE_VALUE

#define OIDC_GRANT_TYPE_VALUE   "authorization_code"

OIDC grant_type key.

Definition at line 98 of file openid_plugin.c.

◆ OIDC_CODE_KEY

#define OIDC_CODE_KEY   "code"

OIDC code key.

Definition at line 103 of file openid_plugin.c.

◆ OIDC_RESPONSE_TYPE_KEY

#define OIDC_RESPONSE_TYPE_KEY   "response_type"

OIDC response_type key.

Definition at line 108 of file openid_plugin.c.

◆ OIDC_CLIENT_ID_KEY

#define OIDC_CLIENT_ID_KEY   "client_id"

OIDC client_id key.

Definition at line 113 of file openid_plugin.c.

◆ OIDC_SCOPE_KEY

#define OIDC_SCOPE_KEY   "scope"

OIDC scope key.

Definition at line 118 of file openid_plugin.c.

◆ OIDC_REDIRECT_URI_KEY

#define OIDC_REDIRECT_URI_KEY   "redirect_uri"

OIDC redirect_uri key.

Definition at line 123 of file openid_plugin.c.

◆ OIDC_STATE_KEY

#define OIDC_STATE_KEY   "state"

OIDC state key.

Definition at line 128 of file openid_plugin.c.

◆ OIDC_NONCE_KEY

#define OIDC_NONCE_KEY   "nonce"

OIDC nonce key.

Definition at line 133 of file openid_plugin.c.

◆ OIDC_CLAIMS_KEY

#define OIDC_CLAIMS_KEY   "claims"

OIDC claims key.

Definition at line 138 of file openid_plugin.c.

◆ OIDC_CODE_CHALLENGE_KEY

#define OIDC_CODE_CHALLENGE_KEY   "code_challenge"

OIDC PKCE code challenge.

Definition at line 143 of file openid_plugin.c.

◆ OIDC_CODE_VERIFIER_KEY

#define OIDC_CODE_VERIFIER_KEY   "code_verifier"

OIDC PKCE code verifier.

Definition at line 148 of file openid_plugin.c.

◆ OIDC_COOKIE_EXPIRATION

#define OIDC_COOKIE_EXPIRATION   3

OIDC cookie expiration (in seconds)

Definition at line 153 of file openid_plugin.c.

◆ OIDC_COOKIE_HEADER_KEY

#define OIDC_COOKIE_HEADER_KEY   "cookie"

OIDC cookie header key.

Definition at line 158 of file openid_plugin.c.

◆ OIDC_AUTHORIZATION_HEADER_KEY

#define OIDC_AUTHORIZATION_HEADER_KEY   "authorization"

OIDC cookie header information key.

Definition at line 163 of file openid_plugin.c.

◆ OIDC_COOKIE_HEADER_INFORMATION_KEY

#define OIDC_COOKIE_HEADER_INFORMATION_KEY   "Identity="

OIDC cookie header information key.

Definition at line 168 of file openid_plugin.c.

◆ OIDC_COOKIE_HEADER_ACCESS_DENIED

#define OIDC_COOKIE_HEADER_ACCESS_DENIED   "Identity=Denied"

OIDC cookie header if user cancelled.

Definition at line 173 of file openid_plugin.c.

◆ OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE

#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE   "code"

OIDC expected response_type while authorizing.

Definition at line 178 of file openid_plugin.c.

◆ OIDC_EXPECTED_AUTHORIZATION_SCOPE

#define OIDC_EXPECTED_AUTHORIZATION_SCOPE   "openid"

OIDC expected scope part while authorizing.

Definition at line 183 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_INVALID_CLIENT

#define OIDC_ERROR_KEY_INVALID_CLIENT   "invalid_client"

OIDC error key for invalid client.

Definition at line 188 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_INVALID_SCOPE

#define OIDC_ERROR_KEY_INVALID_SCOPE   "invalid_scope"

OIDC error key for invalid scopes.

Definition at line 193 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_INVALID_REQUEST

#define OIDC_ERROR_KEY_INVALID_REQUEST   "invalid_request"

OIDC error key for invalid requests.

Definition at line 198 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_INVALID_TOKEN

#define OIDC_ERROR_KEY_INVALID_TOKEN   "invalid_token"

OIDC error key for invalid tokens.

Definition at line 203 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_INVALID_COOKIE

#define OIDC_ERROR_KEY_INVALID_COOKIE   "invalid_cookie"

OIDC error key for invalid cookies.

Definition at line 208 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_SERVER_ERROR

#define OIDC_ERROR_KEY_SERVER_ERROR   "server_error"

OIDC error key for generic server errors.

Definition at line 213 of file openid_plugin.c.

◆ 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 218 of file openid_plugin.c.

◆ 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 223 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT

#define OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT   "unauthorized_client"

OIDC error key for unauthorized clients.

Definition at line 228 of file openid_plugin.c.

◆ OIDC_ERROR_KEY_ACCESS_DENIED

#define OIDC_ERROR_KEY_ACCESS_DENIED   "access_denied"

OIDC error key for denied access.

Definition at line 233 of file openid_plugin.c.

◆ OIDC_JWK_RSA_FILENAME

#define OIDC_JWK_RSA_FILENAME   "jwk_rsa.json"

OIDC key store file name.

Definition at line 238 of file openid_plugin.c.

◆ CONSUME_TIMEOUT

#define CONSUME_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
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:486

How long to wait for a consume in userinfo endpoint.

Definition at line 243 of file openid_plugin.c.

Function Documentation

◆ cleanup_handle()

static void cleanup_handle ( struct RequestHandle handle)
static

Cleanup lookup handle.

Parameters
handleHandle to clean up

Definition at line 600 of file openid_plugin.c.

601{
602
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
604 if (NULL != handle->timeout_task)
605 GNUNET_SCHEDULER_cancel (handle->timeout_task);
606 if (NULL != handle->attr_it)
608 if (NULL != handle->cred_it)
610 if (NULL != handle->ticket_it)
612 if (NULL != handle->idp_op)
614 if (NULL != handle->consume_timeout_op)
615 GNUNET_SCHEDULER_cancel (handle->consume_timeout_op);
616 GNUNET_free (handle->url);
617 GNUNET_free (handle->tld);
618 GNUNET_free (handle->redirect_prefix);
619 GNUNET_free (handle->redirect_suffix);
620 GNUNET_free (handle->emsg);
621 GNUNET_free (handle->edesc);
622 if (NULL != handle->gns_op)
624 if (NULL != handle->oidc)
625 {
626 GNUNET_free (handle->oidc->client_id);
627 GNUNET_free (handle->oidc->login_identity);
628 GNUNET_free (handle->oidc->nonce);
629 GNUNET_free (handle->oidc->redirect_uri);
630 GNUNET_free (handle->oidc->response_type);
631 GNUNET_free (handle->oidc->scope);
632 GNUNET_free (handle->oidc->state);
633 if (NULL != handle->oidc->claims)
634 GNUNET_free (handle->oidc->claims);
635 if (NULL != handle->oidc->code_challenge)
636 GNUNET_free (handle->oidc->code_challenge);
637 GNUNET_free (handle->oidc);
638 }
639 if (NULL!=handle->attr_idtoken_list)
641 if (NULL!=handle->attr_userinfo_list)
642 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_userinfo_list);
643 if (NULL!=handle->credentials)
645 if (NULL!=handle->presentations)
649 handle);
650 if (NULL != handle->access_token)
651 GNUNET_free (handle->access_token);
653}
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition: gnunet-vpn.c:35
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:313
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_RECLAIM_attribute_list_destroy(struct GNUNET_RECLAIM_AttributeList *attrs)
Destroy claim list.
void GNUNET_RECLAIM_credential_list_destroy(struct GNUNET_RECLAIM_CredentialList *credentials)
Destroy credential list.
void GNUNET_RECLAIM_presentation_list_destroy(struct GNUNET_RECLAIM_PresentationList *presentations)
Destroy presentations list.
void GNUNET_RECLAIM_cancel(struct GNUNET_RECLAIM_Operation *op)
Cancel an identity provider operation.
Definition: reclaim_api.c:1135
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
void GNUNET_RECLAIM_get_credentials_stop(struct GNUNET_RECLAIM_CredentialIterator *ait)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1477
void GNUNET_RECLAIM_ticket_iteration_stop(struct GNUNET_RECLAIM_TicketIterator *it)
Stops iteration and releases the handle for further calls.
Definition: reclaim_api.c:1659
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
static struct RequestHandle * requests_head
DLL.
static struct RequestHandle * requests_tail
DLL.

References 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(), handle, requests_head, and requests_tail.

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

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 662 of file openid_plugin.c.

663{
664 struct RequestHandle *handle = cls;
665 struct MHD_Response *resp;
666 char *json_error;
667
668 GNUNET_asprintf (&json_error,
669 "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
670 handle->emsg,
671 (NULL != handle->edesc) ? handle->edesc : "",
672 (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
673 (NULL != handle->oidc->state) ? handle->oidc->state : "",
674 (NULL != handle->oidc->state) ? "\"" : "");
675 if (0 == handle->response_code)
676 handle->response_code = MHD_HTTP_BAD_REQUEST;
677 resp = GNUNET_REST_create_response (json_error);
678 if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
679 GNUNET_assert (MHD_NO !=
680 MHD_add_response_header (resp,
681 MHD_HTTP_HEADER_WWW_AUTHENTICATE,
682 "Basic"));
683 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
684 MHD_HTTP_HEADER_CONTENT_TYPE,
685 "application/json"));
686 handle->proc (handle->proc_cls, resp, handle->response_code);
688 GNUNET_free (json_error);
689}
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:44
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
The request handle.
Definition: config_plugin.c:47

References cleanup_handle(), GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_REST_create_response(), and handle.

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

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 699 of file openid_plugin.c.

700{
701 struct RequestHandle *handle = cls;
702 struct MHD_Response *resp;
703 char *error;
704
706 "Error: %s\n", handle->edesc);
707 GNUNET_asprintf (&error,
708 "error=\"%s\", error_description=\"%s\"",
709 handle->emsg,
710 (NULL != handle->edesc) ? handle->edesc : "");
711 resp = GNUNET_REST_create_response ("");
712 GNUNET_assert (MHD_NO !=
713 MHD_add_response_header (resp,
714 MHD_HTTP_HEADER_WWW_AUTHENTICATE,
715 "Bearer"));
716 handle->proc (handle->proc_cls, resp, handle->response_code);
718 GNUNET_free (error);
719}
@ GNUNET_ERROR_TYPE_ERROR

References cleanup_handle(), GNUNET_asprintf(), GNUNET_assert, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_REST_create_response(), and handle.

Referenced by consume_fail(), and userinfo_endpoint().

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 728 of file openid_plugin.c.

729{
730 struct RequestHandle *handle = cls;
731 struct MHD_Response *resp;
732 char *redirect;
733
734 GNUNET_asprintf (&redirect,
735 "%s?error=%s&error_description=%s%s%s",
736 handle->oidc->redirect_uri,
737 handle->emsg,
738 handle->edesc,
739 (NULL != handle->oidc->state) ? "&state=" : "",
740 (NULL != handle->oidc->state) ? handle->oidc->state : "");
741 resp = GNUNET_REST_create_response ("");
742 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
743 "Location", redirect));
744 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
746 GNUNET_free (redirect);
747}

References cleanup_handle(), GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_REST_create_response(), and handle.

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

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 756 of file openid_plugin.c.

757{
758 struct RequestHandle *handle = cls;
759
760 handle->timeout_task = NULL;
762}
static void do_error(void *cls)
Task run on error, sends error message.

References do_error(), and handle.

Referenced by REST_openid_process_request().

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 773 of file openid_plugin.c.

776{
777 struct MHD_Response *resp;
778 struct RequestHandle *handle = cls;
779
780 // For now, independent of path return all options
781 resp = GNUNET_REST_create_response (NULL);
782 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
783 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
785 return;
786}
static char * allow_methods
HTTP methods allows for this plugin.

References allow_methods, cleanup_handle(), GNUNET_REST_create_response(), and handle.

Referenced by REST_openid_process_request().

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 793 of file openid_plugin.c.

794{
795 struct GNUNET_HashCode cache_key;
796 char *cookies;
797 struct GNUNET_TIME_Absolute current_time, *relog_time;
798 char delimiter[] = "; ";
799 char *tmp_cookies;
800 char *token;
801 char *value;
802
803 // gets identity of login try with cookie
805 strlen (OIDC_COOKIE_HEADER_KEY),
806 &cache_key);
808 ->header_param_map,
809 &cache_key))
810 {
811 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
812 return;
813 }
814 // splits cookies and find 'Identity' cookie
815 tmp_cookies =
816 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
817 &cache_key);
818 cookies = GNUNET_strdup (tmp_cookies);
819 token = strtok (cookies, delimiter);
820 handle->oidc->user_cancelled = GNUNET_NO;
821 handle->oidc->login_identity = NULL;
822 if (NULL == token)
823 {
825 "Unable to parse cookie: %s\n",
826 cookies);
827 GNUNET_free (cookies);
828 return;
829 }
830
831 while (NULL != token)
832 {
833 if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
834 {
835 handle->oidc->user_cancelled = GNUNET_YES;
836 GNUNET_free (cookies);
837 return;
838 }
839 if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
840 break;
841 token = strtok (NULL, delimiter);
842 }
843 if (NULL == token)
844 {
846 "No cookie value to process: %s\n",
847 cookies);
848 GNUNET_free (cookies);
849 return;
850 }
851 GNUNET_CRYPTO_hash (token, strlen (token), &cache_key);
852 if (GNUNET_NO ==
854 {
855 GNUNET_log (
857 "Found cookie `%s', but no corresponding expiration entry present...\n",
858 token);
859 GNUNET_free (cookies);
860 return;
861 }
862 relog_time =
864 current_time = GNUNET_TIME_absolute_get ();
865 // 30 min after old login -> redirect to login
866 if (current_time.abs_value_us > relog_time->abs_value_us)
867 {
869 "Found cookie `%s', but it is expired.\n",
870 token);
871 GNUNET_free (cookies);
872 return;
873 }
875 GNUNET_assert (NULL != value);
876 handle->oidc->login_identity = GNUNET_strdup (value);
877 GNUNET_free (cookies);
878}
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:41
enum GNUNET_GenericReturnValue 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.
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_CONTAINER_MultiHashMap * OIDC_cookie_jar_map
OIDC hashmap that keeps track of issued cookies.
#define OIDC_COOKIE_HEADER_KEY
OIDC cookie header key.
#define OIDC_COOKIE_HEADER_ACCESS_DENIED
OIDC cookie header if user cancelled.
#define OIDC_COOKIE_HEADER_INFORMATION_KEY
OIDC cookie header information key.
A 512-bit hashcode.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.

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, handle, OIDC_COOKIE_HEADER_ACCESS_DENIED, OIDC_COOKIE_HEADER_INFORMATION_KEY, OIDC_COOKIE_HEADER_KEY, OIDC_cookie_jar_map, and value.

Referenced by authorize_endpoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_jwk_from_file()

static json_t * read_jwk_from_file ( const char *  filename)
static

Read the the JSON Web Key in the given file and return it.

Return NULL and emit warning if JSON can not be decoded or the key is invalid

Parameters
filenamethe file to read the JWK from
Returns
json_t* the reed JWK

Definition at line 890 of file openid_plugin.c.

891{
892 json_t *jwk;
893 json_error_t error;
894
895 jwk = json_load_file (filename, JSON_DECODE_ANY, &error);
896
897 if (! jwk)
898 {
900 ("Could not read OIDC RSA key from config file; %s\n"),
901 error.text);
902 }
903
904 return jwk;
905}
static char * filename

References filename, GNUNET_ERROR_TYPE_WARNING, and GNUNET_log.

Referenced by jwks_endpoint(), and token_endpoint().

Here is the caller graph for this function:

◆ write_jwk_to_file()

static int write_jwk_to_file ( const char *  filename,
json_t *  jwk 
)
static

Write the JWK to file.

If unsuccessful emit warning

Parameters
filenamethe name of the file the JWK is written to
jwkthe JWK that is going to be written
Returns
int Return GNUNET_OK if write is successful

Definition at line 916 of file openid_plugin.c.

918{
919 if (json_dump_file (jwk, filename, JSON_INDENT (2)))
920 {
922 ("Could not write OIDC RSA key to file %s\n"),
923 filename);
925 }
926 else
927 return GNUNET_OK;
928}
@ GNUNET_OK

References filename, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, and GNUNET_OK.

Referenced by jwks_endpoint(), and token_endpoint().

Here is the caller graph for this function:

◆ generate_jwk()

static json_t * generate_jwk ( )
static

Generate a new RSA JSON Web Key.

Returns
json_t* the generated JWK

Definition at line 937 of file openid_plugin.c.

938{
939 json_t *jwk;
940 jwk = json_pack ("{s:s,s:i}", "kty", "RSA", "bits", 2048);
941 jose_jwk_gen (NULL, jwk);
942 json_incref (jwk);
943 return jwk;
944}

Referenced by jwks_endpoint(), and token_endpoint().

Here is the caller graph for this function:

◆ get_oidc_dir_path()

static char * get_oidc_dir_path ( void *  cls)
static

Return the path to the oidc directory path.

Parameters
clsthe RequestHandle

Definition at line 953 of file openid_plugin.c.

954{
955 char *oidc_directory;
956 struct RequestHandle *handle = cls;
957
958 // Read OIDC directory from config
960 "reclaim-rest-plugin",
961 "oidc_dir",
962 &oidc_directory))
963 {
964 // Could not read Config file
966 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
967 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
969 return NULL;
970 }
971
972 return oidc_directory;
973}
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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:1304
#define OIDC_ERROR_KEY_SERVER_ERROR
OIDC error key for generic server errors.
const struct GNUNET_CONFIGURATION_Handle * oid_cfg
The configuration handle.

References do_error(), GNUNET_CONFIGURATION_get_value_filename(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, oid_cfg, and OIDC_ERROR_KEY_SERVER_ERROR.

Referenced by get_oidc_jwk_path(), jwks_endpoint(), and token_endpoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_oidc_jwk_path()

static char * get_oidc_jwk_path ( void *  cls)
static

Return the path to the RSA JWK key file.

Parameters
clsthe RequestHandle

Definition at line 982 of file openid_plugin.c.

983{
984 char *oidc_directory;
985 char *oidc_jwk_path;
986
987 oidc_directory = get_oidc_dir_path (cls);
988
989 // Create path to file
990 GNUNET_asprintf (&oidc_jwk_path, "%s/%s", oidc_directory,
992
993 return oidc_jwk_path;
994}
static char * get_oidc_dir_path(void *cls)
Return the path to the oidc directory path.
#define OIDC_JWK_RSA_FILENAME
OIDC key store file name.

References get_oidc_dir_path(), GNUNET_asprintf(), and OIDC_JWK_RSA_FILENAME.

Referenced by jwks_endpoint(), and token_endpoint().

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 1001 of file openid_plugin.c.

1002{
1003 char *login_base_url;
1004 char *new_redirect;
1005 char *tmp;
1006 struct MHD_Response *resp;
1007 struct GNUNET_Buffer buf = { 0 };
1008 struct RequestHandle *handle = cls;
1009
1011 "reclaim-rest-plugin",
1012 "address",
1013 &login_base_url))
1014 {
1015 GNUNET_buffer_write_str (&buf, login_base_url);
1017 "?%s=%s",
1019 handle->oidc->response_type);
1021 "&%s=%s",
1023 handle->oidc->client_id);
1024 GNUNET_STRINGS_urlencode (strlen (handle->oidc->redirect_uri),
1025 handle->oidc->redirect_uri,
1026 &tmp);
1028 "&%s=%s",
1030 tmp);
1031 GNUNET_free (tmp);
1032 GNUNET_STRINGS_urlencode (strlen (handle->oidc->scope),
1033 handle->oidc->scope,
1034 &tmp);
1036 "&%s=%s",
1038 tmp);
1039 GNUNET_free (tmp);
1040 if (NULL != handle->oidc->state)
1041 {
1042 GNUNET_STRINGS_urlencode (strlen (handle->oidc->state),
1043 handle->oidc->state,
1044 &tmp);
1046 "&%s=%s",
1048 handle->oidc->state);
1049 GNUNET_free (tmp);
1050 }
1051 if (NULL != handle->oidc->code_challenge)
1052 {
1054 "&%s=%s",
1056 handle->oidc->code_challenge);
1057 }
1058 if (NULL != handle->oidc->nonce)
1059 {
1061 "&%s=%s",
1063 handle->oidc->nonce);
1064 }
1065 if (NULL != handle->oidc->claims)
1066 {
1067 GNUNET_STRINGS_urlencode (strlen (handle->oidc->claims),
1068 handle->oidc->claims,
1069 &tmp);
1071 "&%s=%s",
1073 tmp);
1074 GNUNET_free (tmp);
1075 }
1076 new_redirect = GNUNET_buffer_reap_str (&buf);
1077 resp = GNUNET_REST_create_response ("");
1078 MHD_add_response_header (resp, "Location", new_redirect);
1079 GNUNET_free (login_base_url);
1080 }
1081 else
1082 {
1084 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1085 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1087 return;
1088 }
1089 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1090 GNUNET_free (new_redirect);
1092}
enum GNUNET_GenericReturnValue 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 * GNUNET_buffer_reap_str(struct GNUNET_Buffer *buf)
Clear the buffer and return the string it contained.
Definition: buffer.c:123
void GNUNET_buffer_write_fstr(struct GNUNET_Buffer *buf, const char *fmt,...) __attribute__((format(printf
Write a 0-terminated formatted string to a buffer, excluding the 0-terminator.
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
size_t GNUNET_STRINGS_urlencode(size_t len, const char data[static len], char **out)
url/percent encode (RFC3986).
Definition: strings.c:1863
#define OIDC_SCOPE_KEY
OIDC scope key.
#define OIDC_CLAIMS_KEY
OIDC claims key.
#define OIDC_REDIRECT_URI_KEY
OIDC redirect_uri key.
#define OIDC_NONCE_KEY
OIDC nonce key.
#define OIDC_CODE_CHALLENGE_KEY
OIDC PKCE code challenge.
#define OIDC_RESPONSE_TYPE_KEY
OIDC response_type key.
#define OIDC_STATE_KEY
OIDC state key.
#define OIDC_CLIENT_ID_KEY
OIDC client_id key.
Dynamically growing buffer.

References cleanup_handle(), do_error(), 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, oid_cfg, 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, and OIDC_STATE_KEY.

Referenced by build_authz_response(), and code_redirect().

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 1099 of file openid_plugin.c.

1100{
1101 struct RequestHandle *handle = cls;
1102
1104 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1106}

References do_error(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, and OIDC_ERROR_KEY_SERVER_ERROR.

Referenced by code_redirect(), and oidc_attr_collect_finished_cb().

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 presentation 
)
static

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

Otherwise redirects with error

Definition at line 1114 of file openid_plugin.c.

1118{
1119 struct RequestHandle *handle = cls;
1120 struct MHD_Response *resp;
1121 char *ticket_str;
1122 char *redirect_uri;
1123 char *code_string;
1124
1125 handle->idp_op = NULL;
1126 if (NULL == ticket)
1127 {
1129 handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
1131 return;
1132 }
1133 handle->ticket = *ticket;
1134 ticket_str =
1136 sizeof(struct GNUNET_RECLAIM_Ticket));
1137 code_string = OIDC_build_authz_code (&handle->priv_key,
1138 &handle->ticket,
1139 handle->attr_idtoken_list,
1140 presentation,
1141 handle->oidc->nonce,
1142 handle->oidc->code_challenge);
1143 if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
1144 (NULL != handle->tld))
1145 {
1146 GNUNET_asprintf (&redirect_uri,
1147 "%s.%s/%s%s%s=%s&state=%s",
1148 handle->redirect_prefix,
1149 handle->tld,
1150 handle->redirect_suffix,
1151 (NULL == strchr (handle->redirect_suffix, '?') ? "?" :
1152 "&"),
1153 handle->oidc->response_type,
1154 code_string,
1155 handle->oidc->state);
1156 }
1157 else
1158 {
1159 GNUNET_asprintf (&redirect_uri,
1160 "%s%s%s=%s&state=%s",
1161 handle->oidc->redirect_uri,
1162 (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" :
1163 "&"),
1164 handle->oidc->response_type,
1165 code_string,
1166 handle->oidc->state);
1167 }
1168 resp = GNUNET_REST_create_response ("");
1169 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1170 "Location", redirect_uri));
1171 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1173 GNUNET_free (redirect_uri);
1174 GNUNET_free (ticket_str);
1175 GNUNET_free (code_string);
1176}
static struct GNUNET_RECLAIM_Ticket ticket
Ticket to consume.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:787
char * OIDC_build_authz_code(const struct GNUNET_CRYPTO_PrivateKey *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:567
static void do_redirect_error(void *cls)
Task run on error, sends error message and redirects.
The authorization ticket.

References cleanup_handle(), do_redirect_error(), GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_STRINGS_data_to_string_alloc(), handle, OIDC_build_authz_code(), OIDC_ERROR_KEY_SERVER_ERROR, and ticket.

Referenced by oidc_cred_collect_finished_cb().

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 1180 of file openid_plugin.c.

1182{
1183 struct GNUNET_RECLAIM_AttributeList *merged_list;
1187
1188 merged_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1189 for (le_a = list_a->list_head; NULL != le_a; le_a = le_a->next)
1190 {
1193 &le_a->attribute->
1194 credential,
1195 le_a->attribute->type,
1196 le_a->attribute->data,
1197 le_a->attribute->data_size);
1198 le_m->attribute->id = le_a->attribute->id;
1199 le_m->attribute->flag = le_a->attribute->flag;
1200 le_m->attribute->credential = le_a->attribute->credential;
1202 merged_list->list_tail,
1203 le_m);
1204 }
1205 le_m = NULL;
1206 for (le_b = list_b->list_head; NULL != le_b; le_b = le_b->next)
1207 {
1208 for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1209 {
1211 &le_b->attribute->id))
1212 break;
1213 }
1214 if (NULL != le_m)
1215 continue;
1218 &le_b->attribute->
1219 credential,
1220 le_b->attribute->type,
1221 le_b->attribute->data,
1222 le_b->attribute->data_size);
1223 le_m->attribute->id = le_b->attribute->id;
1224 le_m->attribute->flag = le_b->attribute->flag;
1225 le_m->attribute->credential = le_b->attribute->credential;
1227 merged_list->list_tail,
1228 le_m);
1229 }
1230 return merged_list;
1231}
static struct GNUNET_RECLAIM_Identifier credential
Credential ID.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_RECLAIM_id_is_equal(a, b)
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.
struct GNUNET_RECLAIM_Attribute * attribute
The attribute claim.
struct GNUNET_RECLAIM_AttributeListEntry * next
DLL.
A list of GNUNET_RECLAIM_Attribute structures.
struct GNUNET_RECLAIM_AttributeListEntry * list_tail
List tail.
struct GNUNET_RECLAIM_AttributeListEntry * list_head
List head.
const char * name
The name of the attribute.
struct GNUNET_RECLAIM_Identifier credential
Referenced ID of credential (may be GNUNET_RECLAIM_ID_ZERO if self-creded)
struct GNUNET_RECLAIM_Identifier id
ID.
uint32_t type
Type of Claim.
const void * data
Binary value stored as attribute value.
size_t data_size
Number of bytes in data.

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().

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 1235 of file openid_plugin.c.

1236{
1237 struct RequestHandle *handle = cls;
1238 struct GNUNET_RECLAIM_AttributeList *merged_list;
1240
1241 handle->cred_it = NULL;
1242 merged_list = attribute_list_merge (handle->attr_idtoken_list,
1243 handle->attr_userinfo_list);
1244 for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1246 "List Attribute in ticket to issue: %s\n",
1247 le_m->attribute->name);
1249 &handle->priv_key,
1250 handle->oidc->client_id,
1251 merged_list,
1253 handle);
1255}
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *iss, const char *rp_uri, const struct GNUNET_RECLAIM_AttributeList *attrs, GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls)
Issues a ticket to a relying party.
Definition: reclaim_api.c:1497
static struct GNUNET_RECLAIM_Handle * idp
Identity Provider.
static void oidc_ticket_issue_cb(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket, const struct GNUNET_RECLAIM_PresentationList *presentation)
Issues ticket and redirects to relying party with the authorization code as parameter.
static struct GNUNET_RECLAIM_AttributeList * attribute_list_merge(struct GNUNET_RECLAIM_AttributeList *list_a, struct GNUNET_RECLAIM_AttributeList *list_b)

References GNUNET_RECLAIM_AttributeListEntry::attribute, attribute_list_merge(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_ticket_issue(), handle, idp, GNUNET_RECLAIM_AttributeList::list_head, GNUNET_RECLAIM_Attribute::name, GNUNET_RECLAIM_AttributeListEntry::next, and oidc_ticket_issue_cb().

Referenced by oidc_attr_collect_finished_cb().

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_PublicKey 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 1262 of file openid_plugin.c.

1265{
1266 struct RequestHandle *handle = cls;
1269
1270 for (ale = handle->credentials->list_head; NULL != ale; ale = ale->next)
1271 {
1273 &cred->id))
1274 continue;
1277 return;
1278 }
1279
1280 for (le = handle->attr_idtoken_list->list_head; NULL != le; le = le->next)
1281 {
1283 &cred->id))
1284 continue;
1288 cred->type,
1289 cred->data,
1290 cred->data_size);
1291 GNUNET_CONTAINER_DLL_insert (handle->credentials->list_head,
1292 handle->credentials->list_tail,
1293 ale);
1294 }
1296}
static gnutls_certificate_credentials_t cred
The credential.
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.
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:1462
struct GNUNET_RECLAIM_CredentialListEntry * next
DLL.
struct GNUNET_RECLAIM_Credential * credential
The credential.
struct GNUNET_RECLAIM_Identifier id
ID.

References GNUNET_RECLAIM_AttributeListEntry::attribute, cred, GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_CredentialListEntry::credential, 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_AttributeListEntry::next, and GNUNET_RECLAIM_CredentialListEntry::next.

Referenced by oidc_attr_collect_finished_cb().

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 1300 of file openid_plugin.c.

1301{
1302 struct RequestHandle *handle = cls;
1303
1304 handle->attr_it = NULL;
1305 handle->ticket_it = NULL;
1306 if (NULL == handle->attr_idtoken_list->list_head)
1307 {
1309 handle->edesc = GNUNET_strdup ("The requested scope is not available.");
1311 return;
1312 }
1313 handle->credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
1314 handle->cred_it =
1316 &handle->priv_key,
1318 handle,
1320 handle,
1322 handle);
1323
1324}
struct GNUNET_RECLAIM_CredentialIterator * GNUNET_RECLAIM_get_credentials_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *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:1416
static void oidc_cred_collect(void *cls, const struct GNUNET_CRYPTO_PublicKey *identity, const struct GNUNET_RECLAIM_Credential *cred)
Collects all attributes for an ego if in scope parameter.
static void oidc_cred_collect_finished_cb(void *cls)
#define OIDC_ERROR_KEY_INVALID_SCOPE
OIDC error key for invalid scopes.
static void oidc_iteration_error(void *cls)
Does internal server error when iteration failed.
A list of GNUNET_RECLAIM_Credential structures.

References do_redirect_error(), GNUNET_new, GNUNET_RECLAIM_get_credentials_start(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, idp, oidc_cred_collect(), oidc_cred_collect_finished_cb(), OIDC_ERROR_KEY_INVALID_SCOPE, and oidc_iteration_error().

Referenced by code_redirect().

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 1328 of file openid_plugin.c.

1331{
1332 int ret = GNUNET_NO;
1333 json_t *root;
1334 json_error_t error;
1335 json_t *claims_j;
1336 const char *key;
1337 json_t *value;
1338
1341 attr_name))
1342 return GNUNET_YES;
1343
1345 if (NULL != handle->oidc->claims)
1346 {
1347 root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error);
1348 claims_j = json_object_get (root, claims_parameter);
1349 /* obj is a JSON object */
1350 if (NULL != claims_j)
1351 {
1352 json_object_foreach (claims_j, key, value) {
1353 if (0 != strcmp (attr_name, key))
1354 continue;
1355 ret = GNUNET_YES;
1356 break;
1357 }
1358 }
1359 json_decref (root);
1360 }
1361 return ret;
1362}
static int ret
Final status code.
Definition: gnunet-arm.c:93
struct GNUNET_HashCode key
The key used in the DHT.
static char * attr_name
The attribute.
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:959

References attr_name, GNUNET_NO, GNUNET_YES, handle, key, OIDC_check_scopes_for_claim_request(), ret, and value.

Referenced by attr_in_idtoken_request(), and attr_in_userinfo_request().

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 1366 of file openid_plugin.c.

1368{
1369 return attr_in_claims_request (handle, attr_name, "id_token");
1370}
static int attr_in_claims_request(struct RequestHandle *handle, const char *attr_name, const char *claims_parameter)

References attr_in_claims_request(), attr_name, and handle.

Referenced by oidc_attr_collect().

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 1374 of file openid_plugin.c.

1376{
1377 return attr_in_claims_request (handle, attr_name, "userinfo");
1378}

References attr_in_claims_request(), attr_name, and handle.

Referenced by oidc_attr_collect().

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_PublicKey identity,
const struct GNUNET_RECLAIM_Attribute attr 
)
static

Collects all attributes for an ego if in scope parameter.

Definition at line 1385 of file openid_plugin.c.

1388{
1389 struct RequestHandle *handle = cls;
1392 {
1395 &attr->credential,
1396 attr->type,
1397 attr->data,
1398 attr->data_size);
1399 le->attribute->id = attr->id;
1400 le->attribute->flag = attr->flag;
1401 le->attribute->credential = attr->credential;
1402 GNUNET_CONTAINER_DLL_insert (handle->attr_idtoken_list->list_head,
1403 handle->attr_idtoken_list->list_tail,
1404 le);
1405 }
1407 {
1410 &attr->credential,
1411 attr->type,
1412 attr->data,
1413 attr->data_size);
1414 le->attribute->id = attr->id;
1415 le->attribute->flag = attr->flag;
1416 le->attribute->credential = attr->credential;
1417 GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head,
1418 handle->attr_userinfo_list->list_tail,
1419 le);
1420 }
1421
1423}
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:1384
static int attr_in_userinfo_request(struct RequestHandle *handle, const char *attr_name)
static int attr_in_idtoken_request(struct RequestHandle *handle, const char *attr_name)

References attr_in_idtoken_request(), attr_in_userinfo_request(), 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_Attribute::name, and GNUNET_RECLAIM_Attribute::type.

Referenced by code_redirect().

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 1430 of file openid_plugin.c.

1431{
1432 struct RequestHandle *handle = cls;
1433 struct GNUNET_TIME_Absolute current_time;
1434 struct GNUNET_TIME_Absolute *relog_time;
1436 struct GNUNET_CRYPTO_PublicKey ego_pkey;
1437 struct GNUNET_HashCode cache_key;
1438 char *identity_cookie;
1439
1440 GNUNET_asprintf (&identity_cookie,
1441 "Identity=%s",
1442 handle->oidc->login_identity);
1443 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1444 GNUNET_free (identity_cookie);
1445 // No login time for identity -> redirect to login
1446 if (GNUNET_YES ==
1448 {
1449 relog_time =
1451 current_time = GNUNET_TIME_absolute_get ();
1452 // 30 min after old login -> redirect to login
1453 if (current_time.abs_value_us <= relog_time->abs_value_us)
1454 {
1455 if (GNUNET_OK !=
1457 ->login_identity,
1458 &pubkey))
1459 {
1461 handle->edesc =
1462 GNUNET_strdup ("The cookie of a login identity is not valid");
1464 return;
1465 }
1466 // iterate over egos and compare their public key
1467 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1468 handle->ego_entry = handle->ego_entry->next)
1469 {
1470 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1471 if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1472 {
1473 handle->priv_key =
1475 handle->attr_idtoken_list =
1477 handle->attr_userinfo_list =
1479 handle->attr_it =
1481 &handle->priv_key,
1483 handle,
1485 handle,
1487 handle);
1488 return;
1489 }
1490 }
1492 return;
1493 }
1494 }
1495}
static struct GNUNET_CRYPTO_PublicKey pubkey
Public key of the zone to look in.
const struct GNUNET_CRYPTO_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:517
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:529
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string(const char *str, struct GNUNET_CRYPTO_PublicKey *key)
Parses a (Base32) string representation of the public key.
Definition: crypto_pkey.c:399
struct GNUNET_RECLAIM_AttributeIterator * GNUNET_RECLAIM_get_attributes_start(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *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:1339
static void oidc_attr_collect(void *cls, const struct GNUNET_CRYPTO_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr)
Collects all attributes for an ego if in scope parameter.
#define OIDC_ERROR_KEY_INVALID_COOKIE
OIDC error key for invalid cookies.
static struct EgoEntry * ego_head
Ego list.
static void oidc_attr_collect_finished_cb(void *cls)
static void login_redirect(void *cls)
Redirects to login page stored in configuration file.
An identity key as per LSD0001.

References GNUNET_TIME_Absolute::abs_value_us, do_redirect_error(), ego_head, GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_public_key_from_string(), 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, idp, login_redirect(), oidc_attr_collect(), oidc_attr_collect_finished_cb(), OIDC_cookie_jar_map, OIDC_ERROR_KEY_INVALID_COOKIE, oidc_iteration_error(), and pubkey.

Referenced by build_redirect().

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 1499 of file openid_plugin.c.

1500{
1501 struct RequestHandle *handle = cls;
1502 struct MHD_Response *resp;
1503 char *redirect_uri;
1504
1505 if (GNUNET_YES == handle->oidc->user_cancelled)
1506 {
1507 if ((NULL != handle->redirect_prefix) &&
1508 (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1509 {
1510 GNUNET_asprintf (&redirect_uri,
1511 "%s.%s/%s?error=%s&error_description=%s&state=%s",
1512 handle->redirect_prefix,
1513 handle->tld,
1514 handle->redirect_suffix,
1515 "access_denied",
1516 "User denied access",
1517 handle->oidc->state);
1518 }
1519 else
1520 {
1521 GNUNET_asprintf (&redirect_uri,
1522 "%s?error=%s&error_description=%s&state=%s",
1523 handle->oidc->redirect_uri,
1524 "access_denied",
1525 "User denied access",
1526 handle->oidc->state);
1527 }
1528 resp = GNUNET_REST_create_response ("");
1529 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1530 "Location",
1531 redirect_uri));
1532 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1534 GNUNET_free (redirect_uri);
1535 return;
1536 }
1538}
static void code_redirect(void *cls)
Checks time and cookie and redirects accordingly.

References cleanup_handle(), code_redirect(), GNUNET_asprintf(), GNUNET_assert, GNUNET_free, GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_YES, and handle.

Referenced by lookup_redirect_uri_result().

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 1542 of file openid_plugin.c.

1545{
1546 struct RequestHandle *handle = cls;
1547 char *tmp;
1548 char *tmp_key_str;
1549 char *pos;
1550 struct GNUNET_CRYPTO_PublicKey redirect_zone;
1551
1552 handle->gns_op = NULL;
1553 if (0 == rd_count)
1554 {
1556 handle->edesc =
1557 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1559 return;
1560 }
1561 for (int i = 0; i < rd_count; i++)
1562 {
1563 if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1564 continue;
1565 if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1566 continue;
1567 tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1568 if (NULL == strstr (tmp, handle->oidc->client_id))
1569 {
1571 "Redirect uri %s does not contain client_id %s\n",
1572 tmp,
1573 handle->oidc->client_id);
1574 }
1575 else
1576 {
1577 pos = strrchr (tmp, (unsigned char) '.');
1578 if (NULL == pos)
1579 {
1581 "Redirect uri %s contains client_id but is malformed\n",
1582 tmp);
1583 GNUNET_free (tmp);
1584 continue;
1585 }
1586 *pos = '\0';
1587 handle->redirect_prefix = GNUNET_strdup (tmp);
1588 tmp_key_str = pos + 1;
1589 pos = strchr (tmp_key_str, (unsigned char) '/');
1590 if (NULL == pos)
1591 {
1593 "Redirect uri %s contains client_id but is malformed\n",
1594 tmp);
1595 GNUNET_free (tmp);
1596 continue;
1597 }
1598 *pos = '\0';
1599 handle->redirect_suffix = GNUNET_strdup (pos + 1);
1600
1601 GNUNET_STRINGS_string_to_data (tmp_key_str,
1602 strlen (tmp_key_str),
1603 &redirect_zone,
1604 sizeof(redirect_zone));
1605 }
1607 GNUNET_free (tmp);
1608 return;
1609 }
1611 handle->edesc =
1612 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1614}
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Used reclaimID OIDC client redirect URIs.
static char * data
The data to insert into the dht.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static size_t data_size
Number of bytes in data.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
enum GNUNET_GenericReturnValue 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:812
static void build_redirect(void *cls)
size_t data_size
Number of bytes in data.

References build_redirect(), data, data_size, GNUNET_GNSRECORD_Data::data_size, do_redirect_error(), 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, OIDC_ERROR_KEY_SERVER_ERROR, rd, and rd_count.

Referenced by client_redirect().

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 1621 of file openid_plugin.c.

1622{
1623 struct RequestHandle *handle = cls;
1624
1625 /* Lookup client redirect uri to verify request */
1626 handle->gns_op =
1629 &handle->oidc->client_pkey,
1633 handle);
1634}
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_PublicKey *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:421
@ GNUNET_GNS_LO_DEFAULT
Defaults, look in cache, then in DHT.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
static struct GNUNET_GNS_Handle * gns_handle
GNS handle.
static void lookup_redirect_uri_result(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)

References gns_handle, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNS_LO_DEFAULT, GNUNET_GNS_lookup(), GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, handle, and lookup_redirect_uri_result().

Referenced by build_authz_response().

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 1638 of file openid_plugin.c.

1639{
1640 struct GNUNET_HashCode hc;
1641 char *value;
1642 char *res;
1643
1644 GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1646 ->url_param_map,
1647 &hc))
1648 return NULL;
1649 value =
1650 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc);
1651 if (NULL == value)
1652 return NULL;
1654 return res;
1655}
static char * res
Currently read line or NULL on EOF.
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition: strings.c:1808

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_STRINGS_urldecode(), GNUNET_YES, handle, key, res, and value.

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

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 1665 of file openid_plugin.c.

1666{
1667 struct RequestHandle *handle = cls;
1668 struct GNUNET_HashCode cache_key;
1669
1670 char *expected_scope;
1671 char delimiter[] = " ";
1672 char *test;
1673 int number_of_ignored_parameter, iterator;
1674
1675
1676 // REQUIRED value: redirect_uri
1677 handle->oidc->redirect_uri =
1679 if (NULL == handle->oidc->redirect_uri)
1680 {
1682 handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1684 return;
1685 }
1686
1687 // REQUIRED value: response_type
1688 handle->oidc->response_type =
1690 if (NULL == handle->oidc->response_type)
1691 {
1693 handle->edesc = GNUNET_strdup ("missing parameter response_type");
1695 return;
1696 }
1697
1698 // REQUIRED value: scope
1700 if (NULL == handle->oidc->scope)
1701 {
1703 handle->edesc = GNUNET_strdup ("missing parameter scope");
1705 return;
1706 }
1707
1708 // OPTIONAL value: nonce
1710
1711 // OPTIONAL value: claims
1713
1714 // TODO check other values if needed
1715 number_of_ignored_parameter =
1716 sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1717 for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1718 {
1720 strlen (OIDC_ignored_parameter_array[iterator]),
1721 &cache_key);
1722 if (GNUNET_YES ==
1724 ->url_param_map,
1725 &cache_key))
1726 {
1728 GNUNET_asprintf (&handle->edesc,
1729 "Server will not handle parameter: %s",
1732 return;
1733 }
1734 }
1735
1736 // We only support authorization code flows.
1737 if (0 != strcmp (handle->oidc->response_type,
1739 {
1741 handle->edesc = GNUNET_strdup ("The authorization server does not support "
1742 "obtaining this authorization code.");
1744 return;
1745 }
1746
1747 // Checks if scope contains 'openid'
1748 expected_scope = GNUNET_strdup (handle->oidc->scope);
1749 test = strtok (expected_scope, delimiter);
1750 while (NULL != test)
1751 {
1752 if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1753 break;
1754 test = strtok (NULL, delimiter);
1755 }
1756 if (NULL == test)
1757 {
1759 handle->edesc =
1760 GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1762 GNUNET_free (expected_scope);
1763 return;
1764 }
1765
1766 GNUNET_free (expected_scope);
1767 if ((NULL == handle->oidc->login_identity) &&
1768 (GNUNET_NO == handle->oidc->user_cancelled))
1770 else
1772}
static const char * OIDC_ignored_parameter_array[]
OIDC ignored parameter array.
#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)
#define OIDC_ERROR_KEY_ACCESS_DENIED
OIDC error key for denied access.
#define OIDC_EXPECTED_AUTHORIZATION_SCOPE
OIDC expected scope part while authorizing.
#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE
OIDC expected response_type while authorizing.
#define OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE
OIDC error key for unsupported response types.
static void client_redirect(void *cls)
Initiate redirect back to client.

References client_redirect(), do_error(), do_redirect_error(), 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, login_redirect(), 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, and OIDC_SCOPE_KEY.

Referenced by authorize_endpoint().

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 1779 of file openid_plugin.c.

1780{
1781 struct RequestHandle *handle = cls;
1783
1784 if (GNUNET_OK !=
1786 {
1787 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1788 return;
1789 }
1790 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1791 handle->tld = GNUNET_strdup (option + 1);
1792}
static char * pkey
Public key of the zone to look in, in ASCII.

References GNUNET_CRYPTO_public_key_from_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_strdup, handle, pkey, and value.

Referenced by authorize_endpoint().

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 1803 of file openid_plugin.c.

1806{
1807 struct RequestHandle *handle = cls;
1808 struct EgoEntry *tmp_ego;
1809 const struct GNUNET_CRYPTO_PrivateKey *priv_key;
1811
1813
1814 // RECOMMENDED value: state - REQUIRED for answers
1816
1817 // REQUIRED value: client_id
1819 if (NULL == handle->oidc->client_id)
1820 {
1822 handle->edesc = GNUNET_strdup ("missing parameter client_id");
1823 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1825 return;
1826 }
1827
1828 // OPTIONAL value: code_challenge
1829 handle->oidc->code_challenge = get_url_parameter_copy (handle,
1831 if (NULL == handle->oidc->code_challenge)
1832 {
1834 "OAuth authorization request does not contain PKCE parameters!\n");
1835 }
1836
1837 if (GNUNET_OK !=
1839 &handle->oidc->client_pkey))
1840 {
1842 handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1843 "authorization code using this method.");
1844 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1846 return;
1847 }
1848
1849 // If we know this identity, translated the corresponding TLD
1850 // TODO: We might want to have a reverse lookup functionality for TLDs?
1851 for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1852 {
1853 priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1855 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1856 {
1857 handle->tld = GNUNET_strdup (tmp_ego->identifier);
1858 handle->ego_entry = ego_tail;
1859 }
1860 }
1861 if (NULL == handle->tld)
1863 handle);
1864 if (NULL == handle->tld)
1865 handle->tld = GNUNET_strdup (handle->oidc->client_id);
1867}
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.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public(const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: crypto_pkey.c:430
static struct EgoEntry * ego_tail
Ego list.
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.
static void build_authz_response(void *cls)
Iteration over all results finished, build final response.
static void tld_iter(void *cls, const char *section, const char *option, const char *value)
Iterate over tlds in config.
The default namestore ego.
char * identifier
Ego Identifier.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
A private key for an identity as per LSD0001.

References build_authz_response(), cookie_identity_interpretation(), do_error(), EgoEntry::ego, ego_head, ego_tail, get_url_parameter_copy(), GNUNET_CONFIGURATION_iterate_section_values(), GNUNET_CRYPTO_key_get_public(), GNUNET_CRYPTO_public_key_from_string(), GNUNET_ERROR_TYPE_WARNING, GNUNET_IDENTITY_ego_get_private_key(), GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, EgoEntry::identifier, EgoEntry::next, oid_cfg, OIDC_CLIENT_ID_KEY, OIDC_CODE_CHALLENGE_KEY, OIDC_ERROR_KEY_INVALID_REQUEST, OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT, OIDC_STATE_KEY, pkey, and tld_iter().

Referenced by REST_openid_process_request().

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 1878 of file openid_plugin.c.

1881{
1882 struct MHD_Response *resp = GNUNET_REST_create_response ("");
1883 struct RequestHandle *handle = cls;
1884 struct GNUNET_HashCode cache_key;
1885 struct GNUNET_TIME_Absolute *current_time;
1886 struct GNUNET_TIME_Absolute *last_time;
1887 char *cookie;
1888 char *header_val;
1889 json_t *root;
1890 json_error_t error;
1891 json_t *identity;
1892 char term_data[handle->rest_handle->data_size + 1];
1893
1894 term_data[handle->rest_handle->data_size] = '\0';
1895 GNUNET_memcpy (term_data,
1896 handle->rest_handle->data,
1897 handle->rest_handle->data_size);
1898 root = json_loads (term_data, JSON_DECODE_ANY, &error);
1899 identity = json_object_get (root, "identity");
1900 if (! json_is_string (identity))
1901 {
1903 "Error parsing json string from %s\n",
1904 term_data);
1905 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1906 json_decref (root);
1908 return;
1909 }
1910 GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1911 GNUNET_asprintf (&header_val,
1912 "%s;Max-Age=%d",
1913 cookie,
1915 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1916 "Set-Cookie", header_val));
1917 GNUNET_assert (MHD_NO !=
1918 MHD_add_response_header (resp,
1919 "Access-Control-Allow-Methods",
1920 "POST"));
1921 GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1922
1923 if (0 != strcmp (json_string_value (identity), "Denied"))
1924 {
1925 current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1926 *current_time = GNUNET_TIME_relative_to_absolute (
1929 last_time =
1931 GNUNET_free (last_time);
1933 &cache_key,
1934 current_time,
1936 }
1937 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1938 GNUNET_free (cookie);
1939 GNUNET_free (header_val);
1940 json_decref (root);
1942}
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
If a value with the given key exists, replace it.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_second_(void)
Return relative time of 1s.
Definition: time.c:169
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:316
#define OIDC_COOKIE_EXPIRATION
OIDC cookie expiration (in seconds)

References cleanup_handle(), GNUNET_asprintf(), GNUNET_assert, 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, and OIDC_cookie_jar_map.

Referenced by REST_openid_process_request().

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 1946 of file openid_plugin.c.

1949{
1950 struct GNUNET_HashCode cache_key;
1951 char *authorization;
1952 char *credentials;
1953 char *basic_authorization;
1954 char *client_id_tmp;
1955 char *pass;
1956
1959 &cache_key);
1961 ->header_param_map,
1962 &cache_key))
1963 return GNUNET_SYSERR;
1964 authorization =
1965 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
1966 &cache_key);
1967
1968 // split header in "Basic" and [content]
1969 credentials = strtok (authorization, " ");
1970 if ((NULL == credentials) || (0 != strcmp ("Basic", credentials)))
1971 return GNUNET_SYSERR;
1972 credentials = strtok (NULL, " ");
1973 if (NULL == credentials)
1974 return GNUNET_SYSERR;
1975 GNUNET_STRINGS_base64_decode (credentials,
1976 strlen (credentials),
1977 (void **) &basic_authorization);
1978
1979 if (NULL == basic_authorization)
1980 return GNUNET_SYSERR;
1981 client_id_tmp = strtok (basic_authorization, ":");
1982 if (NULL == client_id_tmp)
1983 {
1984 GNUNET_free (basic_authorization);
1985 return GNUNET_SYSERR;
1986 }
1987 pass = strtok (NULL, ":");
1988 if (NULL == pass)
1989 {
1990 GNUNET_free (basic_authorization);
1991 return GNUNET_SYSERR;
1992 }
1993 *client_id = strdup (client_id_tmp);
1994 *client_secret = strdup (pass);
1995 GNUNET_free (basic_authorization);
1996 return GNUNET_OK;
1997}
@ GNUNET_SYSERR
size_t GNUNET_STRINGS_base64_decode(const char *data, size_t len, void **output)
Decode from Base64.
Definition: strings.c:1701
#define OIDC_AUTHORIZATION_HEADER_KEY
OIDC cookie header information key.

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_STRINGS_base64_decode(), GNUNET_SYSERR, handle, and OIDC_AUTHORIZATION_HEADER_KEY.

Referenced by check_authorization().

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 2001 of file openid_plugin.c.

2004{
2005 struct GNUNET_HashCode cache_key;
2006 char *client_id_tmp;
2007 char *pass;
2008
2009 GNUNET_CRYPTO_hash ("client_id",
2010 strlen ("client_id"),
2011 &cache_key);
2013 ->url_param_map,
2014 &cache_key))
2015 return GNUNET_SYSERR;
2016 client_id_tmp = GNUNET_CONTAINER_multihashmap_get (
2017 handle->rest_handle->url_param_map,
2018 &cache_key);
2019 if (NULL == client_id_tmp)
2020 return GNUNET_SYSERR;
2021 *client_id = strdup (client_id_tmp);
2022 GNUNET_CRYPTO_hash ("client_secret",
2023 strlen ("client_secret"),
2024 &cache_key);
2026 ->url_param_map,
2027 &cache_key))
2028 {
2029 GNUNET_free (*client_id);
2030 *client_id = NULL;
2031 return GNUNET_SYSERR;
2032 }
2033 pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
2034 &cache_key);
2035 if (NULL == pass)
2036 {
2037 GNUNET_free (*client_id);
2038 *client_id = NULL;
2039 return GNUNET_SYSERR;
2040 }
2041 *client_secret = strdup (pass);
2042 return GNUNET_OK;
2043}

References GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, and handle.

Referenced by check_authorization().

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_PublicKey cid 
)
static

Allow public clients with PKCE

Definition at line 2047 of file openid_plugin.c.

2049{
2050 char *expected_pass;
2051 char *received_cid;
2052 char *received_cpw;
2053 char *pkce_cv;
2054
2056 &received_cid,
2057 &received_cpw))
2058 {
2060 "Received client credentials in HTTP AuthZ header\n");
2061 }
2063 &received_cid,
2064 &received_cpw))
2065 {
2067 "Received client credentials in POST body\n");
2068 }
2069 else
2070 {
2073 if (NULL == pkce_cv)
2074 {
2076 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2077 return GNUNET_SYSERR;
2078 }
2079 handle->public_client = GNUNET_YES;
2080 GNUNET_free (pkce_cv);
2082 GNUNET_STRINGS_string_to_data (received_cid,
2083 strlen (received_cid),
2084 cid,
2085 sizeof(struct GNUNET_CRYPTO_PublicKey));
2086 GNUNET_free (received_cid);
2087 return GNUNET_OK;
2088
2089 }
2090
2091 // check client password
2093 "reclaim-rest-plugin",
2094 "OIDC_CLIENT_HMAC_SECRET",
2095 &expected_pass))
2096 {
2097 if (0 != strcmp (expected_pass, received_cpw))
2098 {
2099 GNUNET_free (expected_pass);
2101 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2102 GNUNET_free (received_cpw);
2103 GNUNET_free (received_cid);
2104 return GNUNET_SYSERR;
2105 }
2106 GNUNET_free (expected_pass);
2107 }
2108 else
2109 {
2110 GNUNET_free (received_cpw);
2111 GNUNET_free (received_cid);
2113 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2114 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2115 return GNUNET_SYSERR;
2116 }
2117 // check client_id
2118 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
2119 handle->ego_entry = handle->ego_entry->next)
2120 {
2121 if (0 == strcmp (handle->ego_entry->keystring, received_cid))
2122 break;
2123 }
2124 if (NULL == handle->ego_entry)
2125 {
2126 GNUNET_free (received_cpw);
2127 GNUNET_free (received_cid);
2129 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2130 return GNUNET_SYSERR;
2131 }
2132 GNUNET_STRINGS_string_to_data (received_cid,
2133 strlen (received_cid),
2134 cid,
2135 sizeof(struct GNUNET_CRYPTO_PublicKey));
2136
2137 GNUNET_free (received_cpw);
2138 GNUNET_free (received_cid);
2139 return GNUNET_OK;
2140}
static int parse_credentials_post_body(struct RequestHandle *handle, char **client_id, char **client_secret)
#define OIDC_ERROR_KEY_INVALID_CLIENT
OIDC error key for invalid client.
static int parse_credentials_basic_auth(struct RequestHandle *handle, char **client_id, char **client_secret)
#define OIDC_CODE_VERIFIER_KEY
OIDC PKCE code verifier.

References ego_head, 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, handle, oid_cfg, OIDC_CLIENT_ID_KEY, OIDC_CODE_VERIFIER_KEY, OIDC_ERROR_KEY_INVALID_CLIENT, OIDC_ERROR_KEY_SERVER_ERROR, parse_credentials_basic_auth(), and parse_credentials_post_body().

Referenced by token_endpoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_ego()

static const struct EgoEntry * find_ego ( struct RequestHandle handle,
struct GNUNET_CRYPTO_PublicKey test_key 
)
static

Definition at line 2144 of file openid_plugin.c.

2146{
2147 struct EgoEntry *ego_entry;
2148 struct GNUNET_CRYPTO_PublicKey pub_key;
2149
2150 for (ego_entry = ego_head; NULL != ego_entry;
2151 ego_entry = ego_entry->next)
2152 {
2153 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key);
2154 if (0 == GNUNET_memcmp (&pub_key, test_key))
2155 return ego_entry;
2156 }
2157 return NULL;
2158}

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

Referenced by token_endpoint().

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

Store mapping from access token to code so we can later fall back on the provided attributes in userinfo one time.

Note to future self: This cache has the following purpose: Some OIDC plugins call the userendpoint right after receiving an ID token and access token. There are reasons why this would make sense. Others not so much. In any case, in order to smoothen out the user experience upon login (authorization), we speculatively cache the next userinfo response in case the actual resolution through reclaim/GNS takes too long.

Definition at line 2169 of file openid_plugin.c.

2172{
2173 struct RequestHandle *handle = cls;
2174 const struct EgoEntry *ego_entry = NULL;
2175 struct GNUNET_TIME_Relative expiration_time;
2176 struct GNUNET_RECLAIM_AttributeList *cl = NULL;
2177 struct GNUNET_RECLAIM_PresentationList *pl = NULL;
2179 struct GNUNET_CRYPTO_PublicKey cid;
2180 struct GNUNET_HashCode cache_key;
2181 struct MHD_Response *resp = NULL;
2182 struct GNUNET_CRYPTO_PublicKey issuer;
2183 char *grant_type = NULL;
2184 char *code = NULL;
2185 char *json_response = NULL;
2186 char *id_token = NULL;
2187 char *access_token = NULL;
2188 char *jwa = NULL;
2189 char *jwt_secret = NULL;
2190 char *nonce = NULL;
2191 char *code_verifier = NULL;
2192 json_t *oidc_jwk_tmp = NULL;
2193 char *oidc_jwk_path = NULL;
2194 char *oidc_directory = NULL;
2195 char *tmp_at = NULL;
2196 char *received_cid = NULL;
2197 char *emsg = NULL;
2198
2199 /*
2200 * Check Authorization
2201 */
2203 {
2205 "OIDC authorization for token endpoint failed\n");
2207 return;
2208 }
2210
2211 /*
2212 * Check parameter
2213 */
2214
2215 // TODO Do not allow multiple equal parameter names
2216 // REQUIRED grant_type
2218 strlen (OIDC_GRANT_TYPE_KEY),
2219 &cache_key);
2221 if (NULL == grant_type)
2222 {
2224 handle->edesc = GNUNET_strdup ("missing parameter grant_type");
2225 handle->response_code = MHD_HTTP_BAD_REQUEST;
2227 return;
2228 }
2229
2230 // Check parameter grant_type == "authorization_code"
2231 if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
2232 {
2234 handle->response_code = MHD_HTTP_BAD_REQUEST;
2235 GNUNET_free (grant_type);
2237 return;
2238 }
2239 GNUNET_free (grant_type);
2240 // REQUIRED code
2242 if (NULL == code)
2243 {
2245 handle->edesc = GNUNET_strdup ("missing parameter code");
2246 handle->response_code = MHD_HTTP_BAD_REQUEST;
2248 return;
2249 }
2250 ego_entry = find_ego (handle, &cid);
2251 if (NULL == ego_entry)
2252 {
2254 handle->edesc = GNUNET_strdup ("Unknown client");
2255 handle->response_code = MHD_HTTP_BAD_REQUEST;
2256 GNUNET_free (code);
2258 return;
2259 }
2260
2261 // REQUIRED code verifier
2263 if (NULL == code_verifier)
2264 {
2266 "OAuth authorization request does not contain PKCE parameters!\n");
2267
2268 }
2269
2270 // decode code
2271 if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, code,
2272 code_verifier,
2273 &ticket,
2274 &cl, &pl, &nonce,
2276 &emsg))
2277 {
2279 handle->edesc = emsg;
2280 handle->response_code = MHD_HTTP_BAD_REQUEST;
2281 GNUNET_free (code);
2282 if (NULL != code_verifier)
2283 GNUNET_free (code_verifier);
2285 return;
2286 }
2287 if (NULL != code_verifier)
2288 GNUNET_free (code_verifier);
2289
2290 // create jwt
2292 "reclaim-rest-plugin",
2293 "expiration_time",
2294 &expiration_time))
2295 {
2297 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2298 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2299 GNUNET_free (code);
2300 if (NULL != nonce)
2301 GNUNET_free (nonce);
2305 return;
2306 }
2307
2308 // Check if HMAC or RSA should be used
2310 "reclaim-rest-plugin",
2311 "oidc_json_web_algorithm",
2312 &jwa))
2313 {
2315 "Could not read OIDC JSON Web Algorithm config attribute."
2316 "Defaulting to RS256.");
2318 }
2319
2321
2322 if (! strcmp (jwa, JWT_ALG_VALUE_RSA))
2323 {
2324 // Replace for now
2325 oidc_jwk_path = get_oidc_jwk_path (cls);
2326 oidc_jwk_tmp = read_jwk_from_file (oidc_jwk_path);
2327
2328 // Check if secret JWK exists
2329 if (! oidc_jwk_tmp)
2330 {
2331 // Generate and save a new key
2332 oidc_jwk_tmp = generate_jwk ();
2333 oidc_directory = get_oidc_dir_path (cls);
2334
2335 // Create new oidc directory
2336 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
2337 {
2339 ("Failed to create directory `%s' for storing oidc data\n"),
2340 oidc_directory);
2341 }
2342 else
2343 {
2344 write_jwk_to_file (oidc_jwk_path, oidc_jwk_tmp);
2345 }
2346 }
2347
2348 // Generate oidc token
2349 id_token = OIDC_generate_id_token_rsa (received_cid,
2350 &issuer,
2351 cl,
2352 pl,
2353 &expiration_time,
2354 (NULL != nonce) ? nonce : NULL,
2355 oidc_jwk_tmp);
2356 }
2357 else if (! strcmp (jwa, JWT_ALG_VALUE_HMAC))
2358 {
2359 // TODO OPTIONAL acr,amr,azp
2361 "reclaim-rest-plugin",
2362 "jwt_secret",
2363 &jwt_secret))
2364 {
2366 handle->edesc = GNUNET_strdup ("No signing secret configured!");
2367 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2368 GNUNET_free (code);
2371 if (NULL != nonce)
2372 GNUNET_free (nonce);
2373 GNUNET_free (jwa);
2375 return;
2376 }
2377
2378 id_token = OIDC_generate_id_token_hmac (received_cid,
2379 &issuer,
2380 cl,
2381 pl,
2382 &expiration_time,
2383 (NULL != nonce) ? nonce : NULL,
2384 jwt_secret);
2385
2386 GNUNET_free (jwt_secret);
2387 }
2388 else
2389 {
2390 // TODO: OPTION NOT FOUND ERROR
2391 }
2392 GNUNET_free (jwa);
2393
2394 if (NULL != nonce)
2395 GNUNET_free (nonce);
2396 access_token = OIDC_access_token_new (&ticket, handle->oidc->redirect_uri);
2401 GNUNET_CRYPTO_hash (access_token,
2402 strlen (access_token),
2403 &cache_key);
2415 &cache_key);
2417 &cache_key,
2418 code,
2420 /* If there was a previous code in there, free the old value */
2421 if (NULL != tmp_at)
2422 {
2424 "OIDC access token already issued. Cleanup.\n");
2425 GNUNET_free (tmp_at);
2426 }
2427
2428 OIDC_build_token_response (access_token,
2429 id_token,
2430 &expiration_time,
2431 &json_response);
2432
2433 resp = GNUNET_REST_create_response (json_response);
2434 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2435 "Cache-Control",
2436 "no-store"));
2437 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2438 "Pragma", "no-cache"));
2439 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2440 "Content-Type",
2441 "application/json"));
2442 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2445 GNUNET_free (access_token);
2446 GNUNET_free (json_response);
2447 GNUNET_free (id_token);
2449}
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:534
enum GNUNET_GenericReturnValue GNUNET_GNS_parse_ztld(const char *name, struct GNUNET_CRYPTO_PublicKey *ztld_key)
Try to parse the zTLD into a public key.
Definition: gns_tld_api.c:228
char * OIDC_generate_id_token_rsa(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *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 json_t *secret_rsa_key)
Create a JWT using RSA256 algorithm from attributes.
Definition: oidc_helper.c:423
int OIDC_parse_authz_code(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *cid, 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, enum OIDC_VerificationOptions opts, char **emsg)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:754
char * OIDC_generate_id_token_hmac(const char *rp_uri, const struct GNUNET_CRYPTO_PublicKey *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 using HMAC (HS256) from attributes.
Definition: oidc_helper.c:475
char * OIDC_access_token_new(const struct GNUNET_RECLAIM_Ticket *ticket, const char *rp_uri)
Generate a new access token.
Definition: oidc_helper.c:901
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:873
#define JWT_ALG_VALUE_RSA
Definition: oidc_helper.h:37
@ OIDC_VERIFICATION_DEFAULT
Strict verification.
Definition: oidc_helper.h:46
#define JWT_ALG_VALUE_HMAC
Definition: oidc_helper.h:36
struct GNUNET_CONTAINER_MultiHashMap * oidc_code_cache
OIDC hashmap for cached access tokens and codes.
static int write_jwk_to_file(const char *filename, json_t *jwk)
Write the JWK to file.
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE
OIDC error key for unsupported grants.
static json_t * read_jwk_from_file(const char *filename)
Read the the JSON Web Key in the given file and return it.
#define OIDC_GRANT_TYPE_KEY
OIDC grant_type key.
Definition: openid_plugin.c:93
static const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_PublicKey *test_key)
static int check_authorization(struct RequestHandle *handle, struct GNUNET_CRYPTO_PublicKey *cid)
#define OIDC_CODE_KEY
OIDC code key.
static json_t * generate_jwk()
Generate a new RSA JSON Web Key.
#define OIDC_GRANT_TYPE_VALUE
OIDC grant_type key.
Definition: openid_plugin.c:98
static char * get_oidc_jwk_path(void *cls)
Return the path to the RSA JWK key file.
A list of GNUNET_RECLAIM_Presentation structures.
char gns_name[63 *2+2]
The ticket.
Time for relative time used by GNUnet, in microseconds.

References check_authorization(), cleanup_handle(), do_error(), find_ego(), generate_jwk(), get_oidc_dir_path(), get_oidc_jwk_path(), get_url_parameter_copy(), GNUNET_RECLAIM_Ticket::gns_name, GNUNET_assert, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE, GNUNET_CRYPTO_hash(), GNUNET_DISK_directory_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_GNS_parse_ztld(), 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, JWT_ALG_VALUE_HMAC, JWT_ALG_VALUE_RSA, oid_cfg, OIDC_access_token_new(), OIDC_build_token_response(), OIDC_CLIENT_ID_KEY, oidc_code_cache, 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_hmac(), OIDC_generate_id_token_rsa(), OIDC_GRANT_TYPE_KEY, OIDC_GRANT_TYPE_VALUE, OIDC_parse_authz_code(), OIDC_VERIFICATION_DEFAULT, read_jwk_from_file(), ticket, and write_jwk_to_file().

Referenced by REST_openid_process_request().

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_PublicKey identity,
const struct GNUNET_RECLAIM_Attribute attr,
const struct GNUNET_RECLAIM_Presentation presentation 
)
static

Collects claims and stores them in handle.

We received a reply. In any case clear the cache.

already in list

Credential matches for attribute, add

Definition at line 2456 of file openid_plugin.c.

2460{
2461 struct RequestHandle *handle = cls;
2464 struct MHD_Response *resp;
2465 struct GNUNET_HashCode cache_key;
2466 char *result_str;
2467 char *cached_code;
2468
2469 if (NULL != handle->consume_timeout_op)
2470 GNUNET_SCHEDULER_cancel (handle->consume_timeout_op);
2471 handle->consume_timeout_op = NULL;
2472 handle->idp_op = NULL;
2473
2477 GNUNET_CRYPTO_hash (handle->access_token,
2478 strlen (handle->access_token),
2479 &cache_key);
2481 &cache_key);
2482 if (NULL != cached_code)
2483 {
2486 &cache_key,
2487 cached_code));
2488 GNUNET_free (cached_code);
2489 }
2490
2491
2492 if (NULL == identity)
2493 {
2494 struct GNUNET_CRYPTO_PublicKey issuer;
2495 char *key;
2496 char *tmp = GNUNET_strdup (handle->ticket.gns_name);
2497 GNUNET_assert (NULL != strtok (tmp, "."));
2498 key = strtok (NULL, ".");
2499 GNUNET_assert (NULL != key);
2502 GNUNET_free (tmp);
2503 result_str = OIDC_generate_userinfo (&issuer,
2504 handle->attr_userinfo_list,
2505 handle->presentations);
2506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str);
2507 resp = GNUNET_REST_create_response (result_str);
2508 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2509 GNUNET_free (result_str);
2511 return;
2512 }
2515 &attr->credential,
2516 attr->type,
2517 attr->data,
2518 attr->data_size);
2519 ale->attribute->id = attr->id;
2520 ale->attribute->flag = attr->flag;
2521 ale->attribute->credential = attr->credential;
2522 GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head,
2523 handle->attr_userinfo_list->list_tail,
2524 ale);
2525 if (NULL == presentation)
2526 return;
2527 for (atle = handle->presentations->list_head;
2528 NULL != atle; atle = atle->next)
2529 {
2532 &presentation->credential_id))
2533 continue;
2534 break;
2535 }
2536 if (NULL == atle)
2537 {
2540 atle->presentation = GNUNET_RECLAIM_presentation_new (presentation->type,
2541 presentation->data,
2542 presentation->
2543 data_size);
2544 atle->presentation->credential_id = presentation->credential_id;
2545 GNUNET_CONTAINER_DLL_insert (handle->presentations->list_head,
2546 handle->presentations->list_tail,
2547 atle);
2548 }
2549}
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_RECLAIM_Presentation * GNUNET_RECLAIM_presentation_new(uint32_t type, const void *data, size_t data_size)
char * OIDC_generate_userinfo(const struct GNUNET_CRYPTO_PublicKey *sub_key, const struct GNUNET_RECLAIM_AttributeList *attrs, const struct GNUNET_RECLAIM_PresentationList *presentations)
Generate userinfo JSON as string.
Definition: oidc_helper.c:348
struct GNUNET_RECLAIM_Presentation * presentation
The credential.
struct GNUNET_RECLAIM_PresentationListEntry * next
DLL.
const void * data
Binary value stored as presentation value.
uint32_t type
Type/Format of Claim.
struct GNUNET_RECLAIM_Identifier credential_id
The credential id of which this is a presentation.

References GNUNET_RECLAIM_AttributeListEntry::attribute, cleanup_handle(), GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_Presentation::credential_id, GNUNET_RECLAIM_Attribute::data, GNUNET_RECLAIM_Presentation::data, data_size, GNUNET_RECLAIM_Attribute::data_size, GNUNET_RECLAIM_Attribute::flag, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_public_key_from_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_RECLAIM_attribute_new(), GNUNET_RECLAIM_id_is_equal, GNUNET_RECLAIM_presentation_new(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_cancel(), GNUNET_strdup, GNUNET_YES, handle, GNUNET_RECLAIM_Attribute::id, identity, key, GNUNET_RECLAIM_Attribute::name, GNUNET_RECLAIM_PresentationListEntry::next, oidc_code_cache, OIDC_generate_userinfo(), GNUNET_RECLAIM_PresentationListEntry::presentation, GNUNET_RECLAIM_Attribute::type, and GNUNET_RECLAIM_Presentation::type.

Referenced by userinfo_endpoint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consume_fail()

static void consume_fail ( void *  cls)
static

Remove the cached item

Definition at line 2553 of file openid_plugin.c.

2554{
2555 struct RequestHandle *handle = cls;
2556 struct GNUNET_HashCode cache_key;
2557 struct GNUNET_RECLAIM_AttributeList *cl = NULL;
2558 struct GNUNET_RECLAIM_PresentationList *pl = NULL;
2560 struct GNUNET_CRYPTO_PublicKey cid;
2561 struct MHD_Response *resp;
2562 struct GNUNET_CRYPTO_PublicKey issuer;
2563 char *nonce;
2564 char *cached_code;
2565 char *result_str;
2566 char *received_cid;
2567 char *emsg;
2568 char *tmp;
2569 char *key;
2570
2571 handle->consume_timeout_op = NULL;
2572 if (NULL != handle->idp_op)
2573 GNUNET_RECLAIM_cancel (handle->idp_op);
2574 handle->idp_op = NULL;
2575
2577 "Ticket consumptioned timed out. Using cache...\n");
2578 GNUNET_CRYPTO_hash (handle->access_token,
2579 strlen (handle->access_token),
2580 &cache_key);
2582 &cache_key);
2583 if (NULL == cached_code)
2584 {
2586 handle->edesc = GNUNET_strdup ("No Access Token in cache!");
2587 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2589 return;
2590 }
2596 &cache_key,
2597 cached_code));
2599 GNUNET_STRINGS_string_to_data (received_cid,
2600 strlen (received_cid),
2601 &cid,
2602 sizeof(struct GNUNET_CRYPTO_PublicKey));
2603
2604 // decode code
2605 if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid,
2606 cached_code, NULL, &ticket,
2607 &cl, &pl, &nonce,
2609 emsg))
2610 {
2612 handle->edesc = emsg;
2613 handle->response_code = MHD_HTTP_BAD_REQUEST;
2614 GNUNET_free (cached_code);
2615 if (NULL != nonce)
2616 GNUNET_free (nonce);
2618 return;
2619 }
2620
2621 GNUNET_free (cached_code);
2622
2623 tmp = GNUNET_strdup (handle->ticket.gns_name);
2624 GNUNET_assert (NULL != strtok (tmp, "."));
2625 key = strtok (NULL, ".");
2626 GNUNET_assert (NULL != key);
2629 GNUNET_free (tmp);
2630 result_str = OIDC_generate_userinfo (&issuer,
2631 cl,
2632 pl);
2633 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str);
2634 resp = GNUNET_REST_create_response (result_str);
2635 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2636 GNUNET_free (result_str);
2637 GNUNET_free (nonce);
2641}
@ OIDC_VERIFICATION_NO_CODE_VERIFIER
Do not check code verifier even if expected.
Definition: oidc_helper.h:51
#define OIDC_ERROR_KEY_INVALID_TOKEN
OIDC error key for invalid tokens.
static void do_userinfo_error(void *cls)
Task run on error in userinfo endpoint, sends error header.

References cleanup_handle(), do_error(), do_userinfo_error(), get_url_parameter_copy(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_public_key_from_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_cancel(), GNUNET_RECLAIM_presentation_list_destroy(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_YES, handle, key, OIDC_CLIENT_ID_KEY, oidc_code_cache, OIDC_ERROR_KEY_INVALID_REQUEST, OIDC_ERROR_KEY_INVALID_TOKEN, OIDC_generate_userinfo(), OIDC_parse_authz_code(), OIDC_VERIFICATION_NO_CODE_VERIFIER, and ticket.

Referenced by userinfo_endpoint().

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 2652 of file openid_plugin.c.

2655{
2656 // TODO expiration time
2657 struct RequestHandle *handle = cls;
2659 char delimiter[] = " ";
2660 struct GNUNET_HashCode cache_key;
2661 char *authorization;
2662 char *authorization_type;
2663 char *authorization_access_token;
2664
2665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n");
2668 &cache_key);
2670 ->header_param_map,
2671 &cache_key))
2672 {
2674 handle->edesc = GNUNET_strdup ("No Access Token");
2675 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2677 return;
2678 }
2679 authorization =
2680 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
2681 &cache_key);
2682
2683 // split header in "Bearer" and access_token
2684 authorization = GNUNET_strdup (authorization);
2685 authorization_type = strtok (authorization, delimiter);
2686 if ((NULL == authorization_type) ||
2687 (0 != strcmp ("Bearer", authorization_type)))
2688 {
2690 handle->edesc = GNUNET_strdup ("No Access Token");
2691 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2693 GNUNET_free (authorization);
2694 return;
2695 }
2696 authorization_access_token = strtok (NULL, delimiter);
2697 if (NULL == authorization_access_token)
2698 {
2700 handle->edesc = GNUNET_strdup ("Access token missing");
2701 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2703 GNUNET_free (authorization);
2704 return;
2705 }
2706
2707 {
2708 char *rp_uri;
2709 if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token,
2710 &ticket, &rp_uri))
2711 {
2713 handle->edesc = GNUNET_strdup ("The access token is invalid");
2714 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2716 GNUNET_free (authorization);
2717 return;
2718
2719 }
2720 GNUNET_assert (NULL != ticket);
2721 handle->ticket = *ticket;
2723 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n");
2724 handle->attr_userinfo_list =
2726 handle->presentations =
2728
2729 /* If the consume takes too long, we use values from the cache */
2730 handle->access_token = GNUNET_strdup (authorization_access_token);
2732 &consume_fail,
2733 handle);
2735 &handle->ticket,
2736 rp_uri,
2738 handle);
2739 GNUNET_free (authorization);
2740 GNUNET_free (rp_uri);
2741 }
2742}
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_RECLAIM_Ticket *ticket, const char *rp_uri, GNUNET_RECLAIM_AttributeTicketResult cb, void *cb_cls)
Consumes an issued ticket.
Definition: reclaim_api.c:1546
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:1277
int OIDC_access_token_parse(const char *token, struct GNUNET_RECLAIM_Ticket **ticket, char **rp_uri)
Parse an access token.
Definition: oidc_helper.c:920
static void consume_fail(void *cls)
static struct GNUNET_TIME_Relative consume_timeout
Timeout for consume call on userinfo.
static void consume_ticket(void *cls, const struct GNUNET_CRYPTO_PublicKey *identity, const struct GNUNET_RECLAIM_Attribute *attr, const struct GNUNET_RECLAIM_Presentation *presentation)
Collects claims and stores them in handle.

References consume_fail(), consume_ticket(), consume_timeout, do_userinfo_error(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_RECLAIM_ticket_consume(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, idp, OIDC_access_token_parse(), OIDC_AUTHORIZATION_HEADER_KEY, OIDC_ERROR_KEY_INVALID_TOKEN, and ticket.

Referenced by REST_openid_process_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ jwks_endpoint()

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

Responds to /jwks.json.

Parameters
con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 2753 of file openid_plugin.c.

2756{
2757 char *oidc_directory;
2758 char *oidc_jwk_path;
2759 char *oidc_jwk_pub_str;
2760 json_t *oidc_jwk_tmp;
2761 struct MHD_Response *resp;
2762 struct RequestHandle *handle = cls;
2763
2764 oidc_jwk_path = get_oidc_jwk_path (cls);
2765 oidc_jwk_tmp = read_jwk_from_file (oidc_jwk_path);
2766
2767 // Check if secret JWK exists
2768 if (! oidc_jwk_tmp)
2769 {
2770 // Generate and save a new key
2771 oidc_jwk_tmp = generate_jwk ();
2772 oidc_directory = get_oidc_dir_path (cls);
2773
2774 // Create new oidc directory
2775 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
2776 {
2778 ("Failed to create directory `%s' for storing oidc data\n"),
2779 oidc_directory);
2780 }
2781 else
2782 {
2783 write_jwk_to_file (oidc_jwk_path, oidc_jwk_tmp);
2784 }
2785 }
2786
2787 // Convert secret JWK to public JWK
2788 jose_jwk_pub (NULL, oidc_jwk_tmp);
2789
2790 // Encode JWK as string and return to API endpoint
2791 oidc_jwk_pub_str = json_dumps (oidc_jwk_tmp, JSON_INDENT (1));
2792 resp = GNUNET_REST_create_response (oidc_jwk_pub_str);
2793 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2794 json_decref (oidc_jwk_tmp);
2795 GNUNET_free (oidc_jwk_pub_str);
2796 GNUNET_free (oidc_jwk_pub_str);
2798}

References cleanup_handle(), generate_jwk(), get_oidc_dir_path(), get_oidc_jwk_path(), GNUNET_DISK_directory_create(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_REST_create_response(), handle, read_jwk_from_file(), and write_jwk_to_file().

Referenced by REST_openid_process_request().

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 (for example because 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 2834 of file openid_plugin.c.

2838{
2839 struct EgoEntry *ego_entry;
2841
2842 if (NULL == ego)
2843 {
2845 return;
2846 }
2848
2849 {
2850 ego_entry = GNUNET_new (struct EgoEntry);
2853 ego_entry->ego = ego;
2854 ego_entry->identifier = GNUNET_strdup (identifier);
2856 ego_tail,
2857 ego_entry);
2858 return;
2859 }
2860 /* Ego renamed or added */
2861 if (identifier != NULL)
2862 {
2863 for (ego_entry = ego_head; NULL != ego_entry;
2864 ego_entry = ego_entry->next)
2865 {
2866 if (ego_entry->ego == ego)
2867 {
2868 /* Rename */
2869 GNUNET_free (ego_entry->identifier);
2870 ego_entry->identifier = GNUNET_strdup (identifier);
2871 break;
2872 }
2873 }
2874 if (NULL == ego_entry)
2875 {
2876 /* Add */
2877 ego_entry = GNUNET_new (struct EgoEntry);
2880 ego_entry->ego = ego;
2881 ego_entry->identifier = GNUNET_strdup (identifier);
2883 ego_tail,
2884 ego_entry);
2885 }
2886 }
2887 else
2888 {
2889 /* Delete */
2890 for (ego_entry = ego_head; NULL != ego_entry;
2891 ego_entry = ego_entry->next)
2892 {
2893 if (ego_entry->ego == ego)
2894 break;
2895 }
2896 if (NULL == ego_entry)
2897 return; /* Not found */
2898
2900 ego_tail,
2901 ego_entry);
2902 GNUNET_free (ego_entry->identifier);
2903 GNUNET_free (ego_entry->keystring);
2904 GNUNET_free (ego_entry);
2905 return;
2906 }
2907}
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
Definition: crypto_pkey.c:379
#define ID_REST_STATE_INIT
State while collecting all egos.
Definition: openid_plugin.c:83
static int state
The processing state.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
Definition: openid_plugin.c:88
char * keystring
Public key string.

References EgoEntry::ego, ego_head, ego_tail, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_CRYPTO_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, pk, and state.

Referenced by REST_openid_init().

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 2911 of file openid_plugin.c.

2914{
2915 json_t *oidc_config;
2916 json_t *auth_methods;
2917 json_t *sig_algs;
2918 json_t *scopes;
2919 json_t *response_types;
2920 json_t *sub_types;
2921 json_t *claim_types;
2922 char *oidc_config_str;
2923 struct MHD_Response *resp;
2924 struct RequestHandle *handle = cls;
2925
2926 oidc_config = json_object ();
2927 // FIXME get from config?
2928 json_object_set_new (oidc_config,
2929 "issuer", json_string ("http://localhost:7776"));
2930 json_object_set_new (oidc_config,
2931 "authorization_endpoint",
2932 json_string ("https://api.reclaim/openid/authorize"));
2933 json_object_set_new (oidc_config,
2934 "token_endpoint",
2935 json_string ("http://localhost:7776/openid/token"));
2936 auth_methods = json_array ();
2937 json_array_append_new (auth_methods,
2938 json_string ("client_secret_basic"));
2939 json_array_append_new (auth_methods,
2940 json_string ("client_secret_post"));
2941 json_object_set_new (oidc_config,
2942 "token_endpoint_auth_methods_supported",
2943 auth_methods);
2944 sig_algs = json_array ();
2945 json_array_append_new (sig_algs,
2946 json_string ("HS512"));
2947 json_array_append_new (sig_algs,
2948 json_string ("RS256"));
2949 json_object_set_new (oidc_config,
2950 "id_token_signing_alg_values_supported",
2951 sig_algs);
2952 json_object_set_new (oidc_config,
2953 "jwks_uri",
2954 json_string ("http://localhost:7776/jwks.json"));
2955 json_object_set_new (oidc_config,
2956 "userinfo_endpoint",
2957 json_string ("http://localhost:7776/openid/userinfo"));
2958 scopes = json_array ();
2959 json_array_append_new (scopes,
2960 json_string ("openid"));
2961 json_array_append_new (scopes,
2962 json_string ("profile"));
2963 json_array_append_new (scopes,
2964 json_string ("email"));
2965 json_array_append_new (scopes,
2966 json_string ("address"));
2967 json_array_append_new (scopes,
2968 json_string ("phone"));
2969 json_object_set_new (oidc_config,
2970 "scopes_supported",
2971 scopes);
2972 response_types = json_array ();
2973 json_array_append_new (response_types,
2974 json_string ("code"));
2975 json_object_set_new (oidc_config,
2976 "response_types_supported",
2977 response_types);
2978 sub_types = json_array ();
2979 json_array_append_new (sub_types,
2980 json_string ("public")); /* no pairwise support */
2981 json_object_set_new (oidc_config,
2982 "subject_types_supported",
2983 sub_types);
2984 claim_types = json_array ();
2985 json_array_append_new (claim_types,
2986 json_string ("normal"));
2987 json_array_append_new (claim_types,
2988 json_string ("aggregated"));
2989 json_object_set_new (oidc_config,
2990 "claim_types_supported",
2991 claim_types);
2992 json_object_set_new (oidc_config,
2993 "claims_parameter_supported",
2994 json_boolean (1));
2995 oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1));
2996 resp = GNUNET_REST_create_response (oidc_config_str);
2997 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2998 json_decref (oidc_config);
2999 GNUNET_free (oidc_config_str);
3001}

References cleanup_handle(), GNUNET_free, GNUNET_REST_create_response(), and handle.

Referenced by REST_openid_process_request().

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 3012 of file openid_plugin.c.

3015{
3016 struct MHD_Response *resp;
3017 struct RequestHandle *handle = cls;
3018
3019 // For now, independent of path return all options
3020 resp = GNUNET_REST_create_response (NULL);
3021 GNUNET_assert (MHD_NO !=
3022 MHD_add_response_header (resp,
3023 "Access-Control-Allow-Methods",
3024 allow_methods));
3025 GNUNET_assert (MHD_NO !=
3026 MHD_add_response_header (resp,
3027 "Access-Control-Allow-Origin",
3028 "*"));
3029 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
3031 return;
3032}

References allow_methods, cleanup_handle(), GNUNET_assert, GNUNET_REST_create_response(), and handle.

Referenced by REST_openid_process_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ REST_openid_process_request()

enum GNUNET_GenericReturnValue REST_openid_process_request ( void *  plugin,
struct GNUNET_REST_RequestHandle conndata_handle,
GNUNET_REST_ResultProcessor  proc,
void *  proc_cls 
)

Function processing the REST call.

Parameters
methodHTTP method
urlURL of the HTTP request
databody of the HTTP request (optional)
data_sizelength of the body
proccallback function for the result
proc_clsclosure for proc
Returns
GNUNET_OK if request accepted

Definition at line 3036 of file openid_plugin.c.

3040{
3041 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
3043 static const struct GNUNET_REST_RequestHandler handlers[] =
3044 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
3045 { MHD_HTTP_METHOD_POST,
3047 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
3048 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
3049 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
3050 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
3051 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_JWKS, &jwks_endpoint },
3052 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG,
3054 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG,
3056 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
3058
3059 handle->oidc = GNUNET_new (struct OIDC_Variables);
3060 if (NULL == OIDC_cookie_jar_map)
3062 GNUNET_NO);
3063 if (NULL == oidc_code_cache)
3065 GNUNET_NO);
3066
3067 handle->response_code = 0;
3069 handle->proc_cls = proc_cls;
3070 handle->proc = proc;
3071 handle->rest_handle = rest_handle;
3072 handle->url = GNUNET_strdup (rest_handle->url);
3073 handle->timeout_task =
3077 handle);
3078 if (handle->url[strlen (handle->url) - 1] == '/')
3079 handle->url[strlen (handle->url) - 1] = '\0';
3080 if (GNUNET_NO ==
3081 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
3082 return GNUNET_NO;
3083
3084 return GNUNET_YES;
3085}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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:64
#define GNUNET_REST_HANDLER_END
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_REST_API_NS_OIDC_CONFIG
OIDC config.
Definition: openid_plugin.c:53
#define GNUNET_REST_API_NS_LOGIN
Login namespace.
Definition: openid_plugin.c:78
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
Definition: openid_plugin.c:48
static void do_timeout(void *cls)
Task run on timeout, sends error message.
static void token_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to token url-encoded POST request.
static void userinfo_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to userinfo GET and url-encoded POST request.
static void jwks_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to /jwks.json.
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.
#define GNUNET_REST_API_JWKS
JSON Web Keys endpoint.
Definition: openid_plugin.c:68
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void oidc_config_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
#define GNUNET_REST_API_NS_TOKEN
Token endpoint.
Definition: openid_plugin.c:63
#define GNUNET_REST_API_NS_USERINFO
UserInfo endpoint.
Definition: openid_plugin.c:73
#define GNUNET_REST_API_NS_AUTHORIZE
Authorize endpoint.
Definition: openid_plugin.c:58
static void oidc_config_cors(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void authorize_endpoint(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Responds to authorization GET and url-encoded POST request.
const char * url
The url as string.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.
OIDC needed variables.

References authorize_endpoint(), do_timeout(), GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multihashmap_create(), GNUNET_new, GNUNET_NO, GNUNET_REST_API_JWKS, 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, handlers, jwks_endpoint(), login_cont(), oidc_code_cache, oidc_config_cors(), oidc_config_endpoint(), OIDC_cookie_jar_map, options_cont(), GNUNET_REST_RequestHandler::proc, requests_head, requests_tail, token_endpoint(), GNUNET_REST_RequestHandle::url, and userinfo_endpoint().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ REST_openid_init()

void * REST_openid_init ( const struct GNUNET_CONFIGURATION_Handle c)

Entry point for the plugin.

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

Definition at line 3095 of file openid_plugin.c.

3096{
3097 static struct Plugin plugin;
3098 struct GNUNET_REST_Plugin *api;
3099
3100 oid_cfg = c;
3101 if (NULL != plugin.cfg)
3102 return NULL; /* can only initialize once! */
3103 memset (&plugin, 0, sizeof(struct Plugin));
3104 plugin.cfg = oid_cfg;
3105 api = GNUNET_new (struct GNUNET_REST_Plugin);
3106 api->cls = &plugin;
3112 "reclaim-rest-plugin",
3113 "OIDC_USERINFO_CONSUME_TIMEOUT",
3115 {
3117 }
3118
3119
3122 "%s, %s, %s, %s, %s",
3123 MHD_HTTP_METHOD_GET,
3124 MHD_HTTP_METHOD_POST,
3125 MHD_HTTP_METHOD_PUT,
3126 MHD_HTTP_METHOD_DELETE,
3127 MHD_HTTP_METHOD_OPTIONS);
3128
3130 _ ("OpenID Connect REST API initialized\n"));
3131 return api;
3132}
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:267
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:487
struct GNUNET_RECLAIM_Handle * GNUNET_RECLAIM_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the re:claimID service.
Definition: reclaim_api.c:1118
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
#define CONSUME_TIMEOUT
How long to wait for a consume in userinfo endpoint.
static struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
#define _(String)
GNU gettext support macro.
Definition: platform.h:179
struct returned by the initialization function of the plugin
void * cls
The closure of the plugin.
const char * name
Plugin name.
Handle for a plugin.
Definition: block.c:38

References _, allow_methods, GNUNET_REST_Plugin::cls, CONSUME_TIMEOUT, consume_timeout, gns_handle, GNUNET_asprintf(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNS_connect(), GNUNET_IDENTITY_connect(), GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_RECLAIM_connect(), GNUNET_REST_API_NS_OIDC, ID_REST_STATE_INIT, identity_handle, idp, list_ego(), GNUNET_REST_Plugin::name, oid_cfg, plugin, and state.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup_hashmap()

static int cleanup_hashmap ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 3136 of file openid_plugin.c.

3137{
3139 return GNUNET_YES;
3140}

References GNUNET_free, GNUNET_YES, and value.

Referenced by REST_openid_done().

Here is the caller graph for this function:

◆ REST_openid_done()

void REST_openid_done ( struct GNUNET_REST_Plugin api)

Exit point from the plugin.

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

Definition at line 3144 of file openid_plugin.c.

3145{
3146 struct Plugin *plugin = api->cls;
3147 struct EgoEntry *ego_entry;
3148
3149 plugin->cfg = NULL;
3150 while (NULL != requests_head)
3152 if (NULL != OIDC_cookie_jar_map)
3153 {
3156 NULL);
3158 }
3159 if (NULL != oidc_code_cache)
3160 {
3163 NULL);
3165 }
3166
3168 if (NULL != gns_handle)
3170 if (NULL != identity_handle)
3172 if (NULL != idp)
3174 while (NULL != (ego_entry = ego_head))
3175 {
3177 ego_tail,
3178 ego_entry);
3179 GNUNET_free (ego_entry->identifier);
3180 GNUNET_free (ego_entry->keystring);
3181 GNUNET_free (ego_entry);
3182 }
3183 GNUNET_free (api);
3185 "OpenID Connect REST plugin is finished\n");
3186}
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:289
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:732
void GNUNET_RECLAIM_disconnect(struct GNUNET_RECLAIM_Handle *h)
Disconnect from identity provider service.
Definition: reclaim_api.c:1150
static int cleanup_hashmap(void *cls, const struct GNUNET_HashCode *key, void *value)
void * cls
Closure for all of the callbacks.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

References allow_methods, Plugin::api, cleanup_handle(), cleanup_hashmap(), GNUNET_BLOCK_PluginFunctions::cls, ego_head, ego_tail, gns_handle, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNS_disconnect(), GNUNET_IDENTITY_disconnect(), GNUNET_log, GNUNET_RECLAIM_disconnect(), EgoEntry::identifier, identity_handle, idp, EgoEntry::keystring, oidc_code_cache, OIDC_cookie_jar_map, plugin, and requests_head.

Referenced by do_shutdown().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ OIDC_ignored_parameter_array

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

OIDC ignored parameter array.

Definition at line 249 of file openid_plugin.c.

Referenced by build_authz_response().

◆ oidc_code_cache

struct GNUNET_CONTAINER_MultiHashMap* oidc_code_cache

OIDC hashmap for cached access tokens and codes.

Definition at line 260 of file openid_plugin.c.

Referenced by consume_fail(), consume_ticket(), REST_openid_done(), REST_openid_process_request(), and token_endpoint().

◆ OIDC_cookie_jar_map

struct GNUNET_CONTAINER_MultiHashMap* OIDC_cookie_jar_map

OIDC hashmap that keeps track of issued cookies.

Definition at line 265 of file openid_plugin.c.

Referenced by code_redirect(), cookie_identity_interpretation(), login_cont(), REST_openid_done(), and REST_openid_process_request().

◆ oid_cfg

const struct GNUNET_CONFIGURATION_Handle* oid_cfg

The configuration handle.

Definition at line 270 of file openid_plugin.c.

Referenced by authorize_endpoint(), check_authorization(), get_oidc_dir_path(), login_redirect(), REST_openid_init(), and token_endpoint().

◆ allow_methods

char* allow_methods
static

HTTP methods allows for this plugin.

Definition at line 275 of file openid_plugin.c.

Referenced by oidc_config_cors(), options_cont(), REST_openid_done(), and REST_openid_init().

◆ ego_head

struct EgoEntry* ego_head
static

◆ ego_tail

struct EgoEntry* ego_tail
static

Ego list.

Definition at line 285 of file openid_plugin.c.

Referenced by authorize_endpoint(), list_ego(), and REST_openid_done().

◆ state

int state
static

The processing state.

Definition at line 290 of file openid_plugin.c.

Referenced by list_ego(), and REST_openid_init().

◆ identity_handle

struct GNUNET_IDENTITY_Handle* identity_handle
static

Handle to Identity service.

Definition at line 295 of file openid_plugin.c.

Referenced by REST_openid_done(), and REST_openid_init().

◆ gns_handle

struct GNUNET_GNS_Handle* gns_handle
static

GNS handle.

Definition at line 300 of file openid_plugin.c.

Referenced by client_redirect(), REST_openid_done(), and REST_openid_init().

◆ idp

◆ consume_timeout

struct GNUNET_TIME_Relative consume_timeout
static

Timeout for consume call on userinfo.

Definition at line 310 of file openid_plugin.c.

Referenced by REST_openid_init(), and userinfo_endpoint().

◆ oidc_jwk

json_t* oidc_jwk

The RSA key used by the oidc endpoint.

Definition at line 323 of file openid_plugin.c.

◆ requests_head

struct RequestHandle* requests_head
static

DLL.

Definition at line 587 of file openid_plugin.c.

Referenced by cleanup_handle(), REST_openid_done(), and REST_openid_process_request().

◆ requests_tail

struct RequestHandle* requests_tail
static

DLL.

Definition at line 592 of file openid_plugin.c.

Referenced by cleanup_handle(), and REST_openid_process_request().