GNUnet 0.21.1
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 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...
 
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...
 
json_t * generate_jwk ()
 Generate a new RSA JSON Web Key. More...
 
char * get_oidc_dir_path (void *cls)
 Return the path to the oidc directory path. More...
 
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)
 
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 (void *cls)
 Exit point from the plugin. More...
 

Variables

static 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 enpoint. 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 47 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 52 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_AUTHORIZE

#define GNUNET_REST_API_NS_AUTHORIZE   "/openid/authorize"

Authorize endpoint.

Definition at line 57 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_TOKEN

#define GNUNET_REST_API_NS_TOKEN   "/openid/token"

Token endpoint.

Definition at line 62 of file openid_plugin.c.

◆ GNUNET_REST_API_JWKS

#define GNUNET_REST_API_JWKS   "/jwks.json"

JSON Web Keys endpoint.

Definition at line 67 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_USERINFO

#define GNUNET_REST_API_NS_USERINFO   "/openid/userinfo"

UserInfo endpoint.

Definition at line 72 of file openid_plugin.c.

◆ GNUNET_REST_API_NS_LOGIN

#define GNUNET_REST_API_NS_LOGIN   "/openid/login"

Login namespace.

Definition at line 77 of file openid_plugin.c.

◆ ID_REST_STATE_INIT

#define ID_REST_STATE_INIT   0

State while collecting all egos.

Definition at line 82 of file openid_plugin.c.

◆ ID_REST_STATE_POST_INIT

#define ID_REST_STATE_POST_INIT   1

Done collecting egos.

Definition at line 87 of file openid_plugin.c.

◆ OIDC_GRANT_TYPE_KEY

#define OIDC_GRANT_TYPE_KEY   "grant_type"

OIDC grant_type key.

Definition at line 92 of file openid_plugin.c.

◆ OIDC_GRANT_TYPE_VALUE

#define OIDC_GRANT_TYPE_VALUE   "authorization_code"

OIDC grant_type key.

Definition at line 97 of file openid_plugin.c.

◆ OIDC_CODE_KEY

#define OIDC_CODE_KEY   "code"

OIDC code key.

Definition at line 102 of file openid_plugin.c.

◆ OIDC_RESPONSE_TYPE_KEY

#define OIDC_RESPONSE_TYPE_KEY   "response_type"

OIDC response_type key.

Definition at line 107 of file openid_plugin.c.

◆ OIDC_CLIENT_ID_KEY

#define OIDC_CLIENT_ID_KEY   "client_id"

OIDC client_id key.

Definition at line 112 of file openid_plugin.c.

◆ OIDC_SCOPE_KEY

#define OIDC_SCOPE_KEY   "scope"

OIDC scope key.

Definition at line 117 of file openid_plugin.c.

◆ OIDC_REDIRECT_URI_KEY

#define OIDC_REDIRECT_URI_KEY   "redirect_uri"

OIDC redirect_uri key.

Definition at line 122 of file openid_plugin.c.

◆ OIDC_STATE_KEY

#define OIDC_STATE_KEY   "state"

OIDC state key.

Definition at line 127 of file openid_plugin.c.

◆ OIDC_NONCE_KEY

#define OIDC_NONCE_KEY   "nonce"

OIDC nonce key.

Definition at line 132 of file openid_plugin.c.

◆ OIDC_CLAIMS_KEY

#define OIDC_CLAIMS_KEY   "claims"

OIDC claims key.

Definition at line 137 of file openid_plugin.c.

◆ OIDC_CODE_CHALLENGE_KEY

#define OIDC_CODE_CHALLENGE_KEY   "code_challenge"

OIDC PKCE code challenge.

Definition at line 142 of file openid_plugin.c.

◆ OIDC_CODE_VERIFIER_KEY

#define OIDC_CODE_VERIFIER_KEY   "code_verifier"

OIDC PKCE code verifier.

Definition at line 147 of file openid_plugin.c.

◆ OIDC_COOKIE_EXPIRATION

#define OIDC_COOKIE_EXPIRATION   3

OIDC cookie expiration (in seconds)

Definition at line 152 of file openid_plugin.c.

◆ OIDC_COOKIE_HEADER_KEY

#define OIDC_COOKIE_HEADER_KEY   "cookie"

OIDC cookie header key.

Definition at line 157 of file openid_plugin.c.

◆ OIDC_AUTHORIZATION_HEADER_KEY

#define OIDC_AUTHORIZATION_HEADER_KEY   "authorization"

OIDC cookie header information key.

Definition at line 162 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 167 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 172 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 177 of file openid_plugin.c.

◆ OIDC_EXPECTED_AUTHORIZATION_SCOPE

#define OIDC_EXPECTED_AUTHORIZATION_SCOPE   "openid"

OIDC expected scope part while authorizing.

Definition at line 182 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 187 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 192 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 197 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 202 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 207 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 212 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 217 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 222 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 227 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 232 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 237 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:484

How long to wait for a consume in userinfo endpoint.

Definition at line 242 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 599 of file openid_plugin.c.

600{
601
602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
603 if (NULL != handle->timeout_task)
604 GNUNET_SCHEDULER_cancel (handle->timeout_task);
605 if (NULL != handle->attr_it)
607 if (NULL != handle->cred_it)
609 if (NULL != handle->ticket_it)
611 if (NULL != handle->idp_op)
613 if (NULL != handle->consume_timeout_op)
614 GNUNET_SCHEDULER_cancel (handle->consume_timeout_op);
615 GNUNET_free (handle->url);
616 GNUNET_free (handle->tld);
617 GNUNET_free (handle->redirect_prefix);
618 GNUNET_free (handle->redirect_suffix);
619 GNUNET_free (handle->emsg);
620 GNUNET_free (handle->edesc);
621 if (NULL != handle->gns_op)
623 if (NULL != handle->oidc)
624 {
625 GNUNET_free (handle->oidc->client_id);
626 GNUNET_free (handle->oidc->login_identity);
627 GNUNET_free (handle->oidc->nonce);
628 GNUNET_free (handle->oidc->redirect_uri);
629 GNUNET_free (handle->oidc->response_type);
630 GNUNET_free (handle->oidc->scope);
631 GNUNET_free (handle->oidc->state);
632 if (NULL != handle->oidc->claims)
633 GNUNET_free (handle->oidc->claims);
634 if (NULL != handle->oidc->code_challenge)
635 GNUNET_free (handle->oidc->code_challenge);
636 GNUNET_free (handle->oidc);
637 }
638 if (NULL!=handle->attr_idtoken_list)
640 if (NULL!=handle->attr_userinfo_list)
641 GNUNET_RECLAIM_attribute_list_destroy (handle->attr_userinfo_list);
642 if (NULL!=handle->credentials)
644 if (NULL!=handle->presentations)
648 handle);
649 if (NULL != handle->access_token)
650 GNUNET_free (handle->access_token);
652}
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:1653
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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 661 of file openid_plugin.c.

662{
663 struct RequestHandle *handle = cls;
664 struct MHD_Response *resp;
665 char *json_error;
666
667 GNUNET_asprintf (&json_error,
668 "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
669 handle->emsg,
670 (NULL != handle->edesc) ? handle->edesc : "",
671 (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
672 (NULL != handle->oidc->state) ? handle->oidc->state : "",
673 (NULL != handle->oidc->state) ? "\"" : "");
674 if (0 == handle->response_code)
675 handle->response_code = MHD_HTTP_BAD_REQUEST;
676 resp = GNUNET_REST_create_response (json_error);
677 if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
678 GNUNET_assert (MHD_NO !=
679 MHD_add_response_header (resp,
680 MHD_HTTP_HEADER_WWW_AUTHENTICATE,
681 "Basic"));
682 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
683 MHD_HTTP_HEADER_CONTENT_TYPE,
684 "application/json"));
685 handle->proc (handle->proc_cls, resp, handle->response_code);
687 GNUNET_free (json_error);
688}
#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
@ MHD_HTTP_BAD_REQUEST
Bad Request [RFC7231, Section 6.5.1].
@ MHD_HTTP_UNAUTHORIZED
Unauthorized [RFC7235, Section 3.1].
static void cleanup_handle(struct RequestHandle *handle)
Cleanup lookup handle.
The request handle.
Definition: config_plugin.c:46

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

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

699{
700 struct RequestHandle *handle = cls;
701 struct MHD_Response *resp;
702 char *error;
703
705 "Error: %s\n", handle->edesc);
706 GNUNET_asprintf (&error,
707 "error=\"%s\", error_description=\"%s\"",
708 handle->emsg,
709 (NULL != handle->edesc) ? handle->edesc : "");
710 resp = GNUNET_REST_create_response ("");
711 GNUNET_assert (MHD_NO !=
712 MHD_add_response_header (resp,
713 MHD_HTTP_HEADER_WWW_AUTHENTICATE,
714 "Bearer"));
715 handle->proc (handle->proc_cls, resp, handle->response_code);
717 GNUNET_free (error);
718}
@ 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 727 of file openid_plugin.c.

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

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

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

756{
757 struct RequestHandle *handle = cls;
758
759 handle->timeout_task = NULL;
761}
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 772 of file openid_plugin.c.

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

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

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

793{
794 struct GNUNET_HashCode cache_key;
795 char *cookies;
796 struct GNUNET_TIME_Absolute current_time, *relog_time;
797 char delimiter[] = "; ";
798 char *tmp_cookies;
799 char *token;
800 char *value;
801
802 // gets identity of login try with cookie
804 strlen (OIDC_COOKIE_HEADER_KEY),
805 &cache_key);
807 ->header_param_map,
808 &cache_key))
809 {
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
811 return;
812 }
813 // splits cookies and find 'Identity' cookie
814 tmp_cookies =
815 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
816 &cache_key);
817 cookies = GNUNET_strdup (tmp_cookies);
818 token = strtok (cookies, delimiter);
819 handle->oidc->user_cancelled = GNUNET_NO;
820 handle->oidc->login_identity = NULL;
821 if (NULL == token)
822 {
824 "Unable to parse cookie: %s\n",
825 cookies);
826 GNUNET_free (cookies);
827 return;
828 }
829
830 while (NULL != token)
831 {
832 if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
833 {
834 handle->oidc->user_cancelled = GNUNET_YES;
835 GNUNET_free (cookies);
836 return;
837 }
838 if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
839 break;
840 token = strtok (NULL, delimiter);
841 }
842 if (NULL == token)
843 {
845 "No cookie value to process: %s\n",
846 cookies);
847 GNUNET_free (cookies);
848 return;
849 }
850 GNUNET_CRYPTO_hash (token, strlen (token), &cache_key);
851 if (GNUNET_NO ==
853 {
854 GNUNET_log (
856 "Found cookie `%s', but no corresponding expiration entry present...\n",
857 token);
858 GNUNET_free (cookies);
859 return;
860 }
861 relog_time =
863 current_time = GNUNET_TIME_absolute_get ();
864 // 30 min after old login -> redirect to login
865 if (current_time.abs_value_us > relog_time->abs_value_us)
866 {
868 "Found cookie `%s', but it is expired.\n",
869 token);
870 GNUNET_free (cookies);
871 return;
872 }
874 GNUNET_assert (NULL != value);
875 handle->oidc->login_identity = GNUNET_strdup (value);
876 GNUNET_free (cookies);
877}
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()

json_t * read_jwk_from_file ( const char *  filename)

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

890{
891 json_t *jwk;
892 json_error_t error;
893
894 jwk = json_load_file (filename, JSON_DECODE_ANY, &error);
895
896 if (! jwk)
897 {
899 ("Could not read OIDC RSA key from config file; %s\n"),
900 error.text);
901 }
902
903 return jwk;
904}
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 writen to
jwkthe JWK that is going to be written
Returns
int Return GNUNET_OK if write is sucessfull

Definition at line 915 of file openid_plugin.c.

917{
918 if (json_dump_file (jwk, filename, JSON_INDENT (2)))
919 {
921 ("Could not write OIDC RSA key to file %s\n"),
922 filename);
924 }
925 else
926 return GNUNET_OK;
927}
@ 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()

json_t * generate_jwk ( )

Generate a new RSA JSON Web Key.

Returns
json_t* the generated JWK

Definition at line 936 of file openid_plugin.c.

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

Referenced by jwks_endpoint(), and token_endpoint().

Here is the caller graph for this function:

◆ get_oidc_dir_path()

char * get_oidc_dir_path ( void *  cls)

Return the path to the oidc directory path.

Parameters
clsthe RequestHandle

Definition at line 952 of file openid_plugin.c.

953{
954 char *oidc_directory;
955 struct RequestHandle *handle = cls;
956
957 // Read OIDC directory from config
959 "reclaim-rest-plugin",
960 "oidc_dir",
961 &oidc_directory))
962 {
963 // Could not read Config file
965 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
966 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
968 return NULL;
969 }
970
971 return oidc_directory;
972}
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:1305
@ MHD_HTTP_INTERNAL_SERVER_ERROR
Internal Server Error [RFC7231, Section 6.6.1].
#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, MHD_HTTP_INTERNAL_SERVER_ERROR, 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()

char * get_oidc_jwk_path ( void *  cls)

Return the path to the RSA JWK key file.

Parameters
clsthe RequestHandle

Definition at line 981 of file openid_plugin.c.

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

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

1001{
1002 char *login_base_url;
1003 char *new_redirect;
1004 char *tmp;
1005 struct MHD_Response *resp;
1006 struct GNUNET_Buffer buf = { 0 };
1007 struct RequestHandle *handle = cls;
1008
1010 "reclaim-rest-plugin",
1011 "address",
1012 &login_base_url))
1013 {
1014 GNUNET_buffer_write_str (&buf, login_base_url);
1016 "?%s=%s",
1018 handle->oidc->response_type);
1020 "&%s=%s",
1022 handle->oidc->client_id);
1023 GNUNET_STRINGS_urlencode (strlen (handle->oidc->redirect_uri),
1024 handle->oidc->redirect_uri,
1025 &tmp);
1027 "&%s=%s",
1029 tmp);
1030 GNUNET_free (tmp);
1031 GNUNET_STRINGS_urlencode (strlen (handle->oidc->scope),
1032 handle->oidc->scope,
1033 &tmp);
1035 "&%s=%s",
1037 tmp);
1038 GNUNET_free (tmp);
1039 if (NULL != handle->oidc->state)
1040 {
1041 GNUNET_STRINGS_urlencode (strlen (handle->oidc->state),
1042 handle->oidc->state,
1043 &tmp);
1045 "&%s=%s",
1047 handle->oidc->state);
1048 GNUNET_free (tmp);
1049 }
1050 if (NULL != handle->oidc->code_challenge)
1051 {
1053 "&%s=%s",
1055 handle->oidc->code_challenge);
1056 }
1057 if (NULL != handle->oidc->nonce)
1058 {
1060 "&%s=%s",
1062 handle->oidc->nonce);
1063 }
1064 if (NULL != handle->oidc->claims)
1065 {
1066 GNUNET_STRINGS_urlencode (strlen (handle->oidc->claims),
1067 handle->oidc->claims,
1068 &tmp);
1070 "&%s=%s",
1072 tmp);
1073 GNUNET_free (tmp);
1074 }
1075 new_redirect = GNUNET_buffer_reap_str (&buf);
1076 resp = GNUNET_REST_create_response ("");
1077 MHD_add_response_header (resp, "Location", new_redirect);
1078 GNUNET_free (login_base_url);
1079 }
1080 else
1081 {
1083 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
1084 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1086 return;
1087 }
1088 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1089 GNUNET_free (new_redirect);
1091}
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:1885
#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, MHD_HTTP_FOUND, MHD_HTTP_INTERNAL_SERVER_ERROR, 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 1098 of file openid_plugin.c.

1099{
1100 struct RequestHandle *handle = cls;
1101
1103 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1105}

References do_error(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, MHD_HTTP_INTERNAL_SERVER_ERROR, 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 1113 of file openid_plugin.c.

1117{
1118 struct RequestHandle *handle = cls;
1119 struct MHD_Response *resp;
1120 char *ticket_str;
1121 char *redirect_uri;
1122 char *code_string;
1123
1124 handle->idp_op = NULL;
1125 if (NULL == ticket)
1126 {
1128 handle->edesc = GNUNET_strdup ("Server cannot generate ticket.");
1130 return;
1131 }
1132 handle->ticket = *ticket;
1133 ticket_str =
1135 sizeof(struct GNUNET_RECLAIM_Ticket));
1136 code_string = OIDC_build_authz_code (&handle->priv_key,
1137 &handle->ticket,
1138 handle->attr_idtoken_list,
1139 presentation,
1140 handle->oidc->nonce,
1141 handle->oidc->code_challenge);
1142 if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
1143 (NULL != handle->tld))
1144 {
1145 GNUNET_asprintf (&redirect_uri,
1146 "%s.%s/%s%s%s=%s&state=%s",
1147 handle->redirect_prefix,
1148 handle->tld,
1149 handle->redirect_suffix,
1150 (NULL == strchr (handle->redirect_suffix, '?') ? "?" :
1151 "&"),
1152 handle->oidc->response_type,
1153 code_string,
1154 handle->oidc->state);
1155 }
1156 else
1157 {
1158 GNUNET_asprintf (&redirect_uri,
1159 "%s%s%s=%s&state=%s",
1160 handle->oidc->redirect_uri,
1161 (NULL == strchr (handle->oidc->redirect_uri, '?') ? "?" :
1162 "&"),
1163 handle->oidc->response_type,
1164 code_string,
1165 handle->oidc->state);
1166 }
1167 resp = GNUNET_REST_create_response ("");
1168 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1169 "Location", redirect_uri));
1170 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1172 GNUNET_free (redirect_uri);
1173 GNUNET_free (ticket_str);
1174 GNUNET_free (code_string);
1175}
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:764
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:565
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, MHD_HTTP_FOUND, 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 1179 of file openid_plugin.c.

1181{
1182 struct GNUNET_RECLAIM_AttributeList *merged_list;
1186
1187 merged_list = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1188 for (le_a = list_a->list_head; NULL != le_a; le_a = le_a->next)
1189 {
1192 &le_a->attribute->
1193 credential,
1194 le_a->attribute->type,
1195 le_a->attribute->data,
1196 le_a->attribute->data_size);
1197 le_m->attribute->id = le_a->attribute->id;
1198 le_m->attribute->flag = le_a->attribute->flag;
1199 le_m->attribute->credential = le_a->attribute->credential;
1201 merged_list->list_tail,
1202 le_m);
1203 }
1204 le_m = NULL;
1205 for (le_b = list_b->list_head; NULL != le_b; le_b = le_b->next)
1206 {
1207 for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1208 {
1210 &le_b->attribute->id))
1211 break;
1212 }
1213 if (NULL != le_m)
1214 continue;
1217 &le_b->attribute->
1218 credential,
1219 le_b->attribute->type,
1220 le_b->attribute->data,
1221 le_b->attribute->data_size);
1222 le_m->attribute->id = le_b->attribute->id;
1223 le_m->attribute->flag = le_b->attribute->flag;
1224 le_m->attribute->credential = le_b->attribute->credential;
1226 merged_list->list_tail,
1227 le_m);
1228 }
1229 return merged_list;
1230}
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 1234 of file openid_plugin.c.

1235{
1236 struct RequestHandle *handle = cls;
1237 struct GNUNET_RECLAIM_AttributeList *merged_list;
1239
1240 handle->cred_it = NULL;
1241 merged_list = attribute_list_merge (handle->attr_idtoken_list,
1242 handle->attr_userinfo_list);
1243 for (le_m = merged_list->list_head; NULL != le_m; le_m = le_m->next)
1245 "List Attribute in ticket to issue: %s\n",
1246 le_m->attribute->name);
1248 &handle->priv_key,
1249 handle->oidc->client_id,
1250 merged_list,
1252 handle);
1254}
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_issue(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *iss, const char *rp, const struct GNUNET_RECLAIM_AttributeList *attrs, GNUNET_RECLAIM_IssueTicketCallback cb, void *cb_cls)
Issues a ticket to a relying party.
Definition: reclaim_api.c: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 1261 of file openid_plugin.c.

1264{
1265 struct RequestHandle *handle = cls;
1268
1269 for (ale = handle->credentials->list_head; NULL != ale; ale = ale->next)
1270 {
1272 &cred->id))
1273 continue;
1276 return;
1277 }
1278
1279 for (le = handle->attr_idtoken_list->list_head; NULL != le; le = le->next)
1280 {
1282 &cred->id))
1283 continue;
1287 cred->type,
1288 cred->data,
1289 cred->data_size);
1290 GNUNET_CONTAINER_DLL_insert (handle->credentials->list_head,
1291 handle->credentials->list_tail,
1292 ale);
1293 }
1295}
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.
uint32_t type
Type/Format of Claim.
const char * name
The name of the credential.
const void * data
Binary value stored as credential value.
size_t data_size
Number of bytes in data.
struct GNUNET_RECLAIM_Identifier id
ID.

References GNUNET_RECLAIM_AttributeListEntry::attribute, GNUNET_RECLAIM_Attribute::credential, GNUNET_RECLAIM_CredentialListEntry::credential, GNUNET_RECLAIM_Credential::data, GNUNET_RECLAIM_Credential::data_size, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_NO, GNUNET_RECLAIM_credential_new(), GNUNET_RECLAIM_get_credentials_next(), GNUNET_RECLAIM_id_is_equal, handle, GNUNET_RECLAIM_Credential::id, GNUNET_RECLAIM_Credential::name, GNUNET_RECLAIM_AttributeListEntry::next, GNUNET_RECLAIM_CredentialListEntry::next, and GNUNET_RECLAIM_Credential::type.

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

1300{
1301 struct RequestHandle *handle = cls;
1302
1303 handle->attr_it = NULL;
1304 handle->ticket_it = NULL;
1305 if (NULL == handle->attr_idtoken_list->list_head)
1306 {
1308 handle->edesc = GNUNET_strdup ("The requested scope is not available.");
1310 return;
1311 }
1312 handle->credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
1313 handle->cred_it =
1315 &handle->priv_key,
1317 handle,
1319 handle,
1321 handle);
1322
1323}
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 1327 of file openid_plugin.c.

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

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

1367{
1368 return attr_in_claims_request (handle, attr_name, "id_token");
1369}
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 1373 of file openid_plugin.c.

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

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

1387{
1388 struct RequestHandle *handle = cls;
1391 {
1394 &attr->credential,
1395 attr->type,
1396 attr->data,
1397 attr->data_size);
1398 le->attribute->id = attr->id;
1399 le->attribute->flag = attr->flag;
1400 le->attribute->credential = attr->credential;
1401 GNUNET_CONTAINER_DLL_insert (handle->attr_idtoken_list->list_head,
1402 handle->attr_idtoken_list->list_tail,
1403 le);
1404 }
1406 {
1409 &attr->credential,
1410 attr->type,
1411 attr->data,
1412 attr->data_size);
1413 le->attribute->id = attr->id;
1414 le->attribute->flag = attr->flag;
1415 le->attribute->credential = attr->credential;
1416 GNUNET_CONTAINER_DLL_insert (handle->attr_userinfo_list->list_head,
1417 handle->attr_userinfo_list->list_tail,
1418 le);
1419 }
1420
1422}
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 1429 of file openid_plugin.c.

1430{
1431 struct RequestHandle *handle = cls;
1432 struct GNUNET_TIME_Absolute current_time;
1433 struct GNUNET_TIME_Absolute *relog_time;
1435 struct GNUNET_CRYPTO_PublicKey ego_pkey;
1436 struct GNUNET_HashCode cache_key;
1437 char *identity_cookie;
1438
1439 GNUNET_asprintf (&identity_cookie,
1440 "Identity=%s",
1441 handle->oidc->login_identity);
1442 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1443 GNUNET_free (identity_cookie);
1444 // No login time for identity -> redirect to login
1445 if (GNUNET_YES ==
1447 {
1448 relog_time =
1450 current_time = GNUNET_TIME_absolute_get ();
1451 // 30 min after old login -> redirect to login
1452 if (current_time.abs_value_us <= relog_time->abs_value_us)
1453 {
1454 if (GNUNET_OK !=
1456 ->login_identity,
1457 &pubkey))
1458 {
1460 handle->edesc =
1461 GNUNET_strdup ("The cookie of a login identity is not valid");
1463 return;
1464 }
1465 // iterate over egos and compare their public key
1466 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
1467 handle->ego_entry = handle->ego_entry->next)
1468 {
1469 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1470 if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1471 {
1472 handle->priv_key =
1474 handle->attr_idtoken_list =
1476 handle->attr_userinfo_list =
1478 handle->attr_it =
1480 &handle->priv_key,
1482 handle,
1484 handle,
1486 handle);
1487 return;
1488 }
1489 }
1491 return;
1492 }
1493 }
1494}
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:571
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 1498 of file openid_plugin.c.

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

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

1544{
1545 struct RequestHandle *handle = cls;
1546 char *tmp;
1547 char *tmp_key_str;
1548 char *pos;
1549 struct GNUNET_CRYPTO_PublicKey redirect_zone;
1550
1551 handle->gns_op = NULL;
1552 if (0 == rd_count)
1553 {
1555 handle->edesc =
1556 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1558 return;
1559 }
1560 for (int i = 0; i < rd_count; i++)
1561 {
1562 if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1563 continue;
1564 if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1565 continue;
1566 tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1567 if (NULL == strstr (tmp, handle->oidc->client_id))
1568 {
1570 "Redirect uri %s does not contain client_id %s\n",
1571 tmp,
1572 handle->oidc->client_id);
1573 }
1574 else
1575 {
1576 pos = strrchr (tmp, (unsigned char) '.');
1577 if (NULL == pos)
1578 {
1580 "Redirect uri %s contains client_id but is malformed\n",
1581 tmp);
1582 GNUNET_free (tmp);
1583 continue;
1584 }
1585 *pos = '\0';
1586 handle->redirect_prefix = GNUNET_strdup (tmp);
1587 tmp_key_str = pos + 1;
1588 pos = strchr (tmp_key_str, (unsigned char) '/');
1589 if (NULL == pos)
1590 {
1592 "Redirect uri %s contains client_id but is malformed\n",
1593 tmp);
1594 GNUNET_free (tmp);
1595 continue;
1596 }
1597 *pos = '\0';
1598 handle->redirect_suffix = GNUNET_strdup (pos + 1);
1599
1600 GNUNET_STRINGS_string_to_data (tmp_key_str,
1601 strlen (tmp_key_str),
1602 &redirect_zone,
1603 sizeof(redirect_zone));
1604 }
1606 GNUNET_free (tmp);
1607 return;
1608 }
1610 handle->edesc =
1611 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found.");
1613}
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:789
static void build_redirect(void *cls)
#define GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT
Used reclaimID OIDC client redirect URIs.
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 1620 of file openid_plugin.c.

1621{
1622 struct RequestHandle *handle = cls;
1623
1624 /* Lookup client redirect uri to verify request */
1625 handle->gns_op =
1628 &handle->oidc->client_pkey,
1632 handle);
1633}
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 1637 of file openid_plugin.c.

1638{
1639 struct GNUNET_HashCode hc;
1640 char *value;
1641 char *res;
1642
1643 GNUNET_CRYPTO_hash (key, strlen (key), &hc);
1645 ->url_param_map,
1646 &hc))
1647 return NULL;
1648 value =
1649 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc);
1650 if (NULL == value)
1651 return NULL;
1653 return res;
1654}
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:1831

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

1665{
1666 struct RequestHandle *handle = cls;
1667 struct GNUNET_HashCode cache_key;
1668
1669 char *expected_scope;
1670 char delimiter[] = " ";
1671 int number_of_ignored_parameter, iterator;
1672
1673
1674 // REQUIRED value: redirect_uri
1675 handle->oidc->redirect_uri =
1677 if (NULL == handle->oidc->redirect_uri)
1678 {
1680 handle->edesc = GNUNET_strdup ("missing parameter redirect_uri");
1682 return;
1683 }
1684
1685 // REQUIRED value: response_type
1686 handle->oidc->response_type =
1688 if (NULL == handle->oidc->response_type)
1689 {
1691 handle->edesc = GNUNET_strdup ("missing parameter response_type");
1693 return;
1694 }
1695
1696 // REQUIRED value: scope
1698 if (NULL == handle->oidc->scope)
1699 {
1701 handle->edesc = GNUNET_strdup ("missing parameter scope");
1703 return;
1704 }
1705
1706 // OPTIONAL value: nonce
1708
1709 // OPTIONAL value: claims
1711
1712 // TODO check other values if needed
1713 number_of_ignored_parameter =
1714 sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1715 for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1716 {
1718 strlen (OIDC_ignored_parameter_array[iterator]),
1719 &cache_key);
1720 if (GNUNET_YES ==
1722 ->url_param_map,
1723 &cache_key))
1724 {
1726 GNUNET_asprintf (&handle->edesc,
1727 "Server will not handle parameter: %s",
1730 return;
1731 }
1732 }
1733
1734 // We only support authorization code flows.
1735 if (0 != strcmp (handle->oidc->response_type,
1737 {
1739 handle->edesc = GNUNET_strdup ("The authorization server does not support "
1740 "obtaining this authorization code.");
1742 return;
1743 }
1744
1745 // Checks if scope contains 'openid'
1746 expected_scope = GNUNET_strdup (handle->oidc->scope);
1747 char *test;
1748 test = strtok (expected_scope, delimiter);
1749 while (NULL != test)
1750 {
1751 if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1752 break;
1753 test = strtok (NULL, delimiter);
1754 }
1755 if (NULL == test)
1756 {
1758 handle->edesc =
1759 GNUNET_strdup ("The requested scope is invalid, unknown, or malformed.");
1761 GNUNET_free (expected_scope);
1762 return;
1763 }
1764
1765 GNUNET_free (expected_scope);
1766 if ((NULL == handle->oidc->login_identity) &&
1767 (GNUNET_NO == handle->oidc->user_cancelled))
1769 else
1771}
#define OIDC_ERROR_KEY_INVALID_REQUEST
OIDC error key for invalid requests.
static char * get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
static char * OIDC_ignored_parameter_array[]
OIDC ignored parameter array.
#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 1778 of file openid_plugin.c.

1779{
1780 struct RequestHandle *handle = cls;
1782
1783 if (GNUNET_OK !=
1785 {
1786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1787 return;
1788 }
1789 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1790 handle->tld = GNUNET_strdup (option + 1);
1791}
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 1802 of file openid_plugin.c.

1805{
1806 struct RequestHandle *handle = cls;
1807 struct EgoEntry *tmp_ego;
1808 const struct GNUNET_CRYPTO_PrivateKey *priv_key;
1810
1812
1813 // RECOMMENDED value: state - REQUIRED for answers
1815
1816 // REQUIRED value: client_id
1818 if (NULL == handle->oidc->client_id)
1819 {
1821 handle->edesc = GNUNET_strdup ("missing parameter client_id");
1822 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1824 return;
1825 }
1826
1827 // OPTIONAL value: code_challenge
1828 handle->oidc->code_challenge = get_url_parameter_copy (handle,
1830 if (NULL == handle->oidc->code_challenge)
1831 {
1833 "OAuth authorization request does not contain PKCE parameters!\n");
1834 }
1835
1836 if (GNUNET_OK !=
1838 &handle->oidc->client_pkey))
1839 {
1841 handle->edesc = GNUNET_strdup ("The client is not authorized to request an "
1842 "authorization code using this method.");
1843 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1845 return;
1846 }
1847
1848 // If we know this identity, translated the corresponding TLD
1849 // TODO: We might want to have a reverse lookup functionality for TLDs?
1850 for (tmp_ego = ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1851 {
1852 priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1854 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1855 {
1856 handle->tld = GNUNET_strdup (tmp_ego->identifier);
1857 handle->ego_entry = ego_tail;
1858 }
1859 }
1860 if (NULL == handle->tld)
1862 handle);
1863 if (NULL == handle->tld)
1864 handle->tld = GNUNET_strdup (handle->oidc->client_id);
1866}
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:602
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, MHD_HTTP_INTERNAL_SERVER_ERROR, 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 1877 of file openid_plugin.c.

1880{
1881 struct MHD_Response *resp = GNUNET_REST_create_response ("");
1882 struct RequestHandle *handle = cls;
1883 struct GNUNET_HashCode cache_key;
1884 struct GNUNET_TIME_Absolute *current_time;
1885 struct GNUNET_TIME_Absolute *last_time;
1886 char *cookie;
1887 char *header_val;
1888 json_t *root;
1889 json_error_t error;
1890 json_t *identity;
1891 char term_data[handle->rest_handle->data_size + 1];
1892
1893 term_data[handle->rest_handle->data_size] = '\0';
1894 GNUNET_memcpy (term_data,
1895 handle->rest_handle->data,
1896 handle->rest_handle->data_size);
1897 root = json_loads (term_data, JSON_DECODE_ANY, &error);
1898 identity = json_object_get (root, "identity");
1899 if (! json_is_string (identity))
1900 {
1902 "Error parsing json string from %s\n",
1903 term_data);
1904 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1905 json_decref (root);
1907 return;
1908 }
1909 GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity));
1910 GNUNET_asprintf (&header_val,
1911 "%s;Max-Age=%d",
1912 cookie,
1914 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
1915 "Set-Cookie", header_val));
1916 GNUNET_assert (MHD_NO !=
1917 MHD_add_response_header (resp,
1918 "Access-Control-Allow-Methods",
1919 "POST"));
1920 GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key);
1921
1922 if (0 != strcmp (json_string_value (identity), "Denied"))
1923 {
1924 current_time = GNUNET_new (struct GNUNET_TIME_Absolute);
1925 *current_time = GNUNET_TIME_relative_to_absolute (
1928 last_time =
1930 GNUNET_free (last_time);
1932 &cache_key,
1933 current_time,
1935 }
1936 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1937 GNUNET_free (cookie);
1938 GNUNET_free (header_val);
1939 json_decref (root);
1941}
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, MHD_HTTP_BAD_REQUEST, MHD_HTTP_OK, 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 1945 of file openid_plugin.c.

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

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

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

2048{
2049 char *expected_pass;
2050 char *received_cid;
2051 char *received_cpw;
2052 char *pkce_cv;
2053
2055 &received_cid,
2056 &received_cpw))
2057 {
2059 "Received client credentials in HTTP AuthZ header\n");
2060 }
2062 &received_cid,
2063 &received_cpw))
2064 {
2066 "Received client credentials in POST body\n");
2067 }
2068 else
2069 {
2072 if (NULL == pkce_cv)
2073 {
2075 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2076 return GNUNET_SYSERR;
2077 }
2078 handle->public_client = GNUNET_YES;
2079 GNUNET_free (pkce_cv);
2081 GNUNET_STRINGS_string_to_data (received_cid,
2082 strlen (received_cid),
2083 cid,
2084 sizeof(struct GNUNET_CRYPTO_PublicKey));
2085 GNUNET_free (received_cid);
2086 return GNUNET_OK;
2087
2088 }
2089
2090 // check client password
2092 "reclaim-rest-plugin",
2093 "OIDC_CLIENT_HMAC_SECRET",
2094 &expected_pass))
2095 {
2096 if (0 != strcmp (expected_pass, received_cpw))
2097 {
2098 GNUNET_free (expected_pass);
2100 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2101 GNUNET_free (received_cpw);
2102 GNUNET_free (received_cid);
2103 return GNUNET_SYSERR;
2104 }
2105 GNUNET_free (expected_pass);
2106 }
2107 else
2108 {
2109 GNUNET_free (received_cpw);
2110 GNUNET_free (received_cid);
2112 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2113 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2114 return GNUNET_SYSERR;
2115 }
2116 // check client_id
2117 for (handle->ego_entry = ego_head; NULL != handle->ego_entry;
2118 handle->ego_entry = handle->ego_entry->next)
2119 {
2120 if (0 == strcmp (handle->ego_entry->keystring, received_cid))
2121 break;
2122 }
2123 if (NULL == handle->ego_entry)
2124 {
2125 GNUNET_free (received_cpw);
2126 GNUNET_free (received_cid);
2128 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2129 return GNUNET_SYSERR;
2130 }
2131 GNUNET_STRINGS_string_to_data (received_cid,
2132 strlen (received_cid),
2133 cid,
2134 sizeof(struct GNUNET_CRYPTO_PublicKey));
2135
2136 GNUNET_free (received_cpw);
2137 GNUNET_free (received_cid);
2138 return GNUNET_OK;
2139}
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, MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_UNAUTHORIZED, 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()

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

Definition at line 2143 of file openid_plugin.c.

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

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

2171{
2172 struct RequestHandle *handle = cls;
2173 const struct EgoEntry *ego_entry = NULL;
2174 struct GNUNET_TIME_Relative expiration_time;
2175 struct GNUNET_RECLAIM_AttributeList *cl = NULL;
2176 struct GNUNET_RECLAIM_PresentationList *pl = NULL;
2178 struct GNUNET_CRYPTO_PublicKey cid;
2179 struct GNUNET_HashCode cache_key;
2180 struct MHD_Response *resp = NULL;
2181 char *grant_type = NULL;
2182 char *code = NULL;
2183 char *json_response = NULL;
2184 char *id_token = NULL;
2185 char *access_token = NULL;
2186 char *jwa = NULL;
2187 char *jwt_secret = NULL;
2188 char *nonce = NULL;
2189 char *code_verifier = NULL;
2190 json_t *oidc_jwk = NULL;
2191 char *oidc_jwk_path = NULL;
2192 char *oidc_directory = NULL;
2193 char *tmp_at = NULL;
2194 char *received_cid = NULL;
2195
2196 /*
2197 * Check Authorization
2198 */
2200 {
2202 "OIDC authorization for token endpoint failed\n");
2204 return;
2205 }
2207
2208 /*
2209 * Check parameter
2210 */
2211
2212 // TODO Do not allow multiple equal parameter names
2213 // REQUIRED grant_type
2215 strlen (OIDC_GRANT_TYPE_KEY),
2216 &cache_key);
2218 if (NULL == grant_type)
2219 {
2221 handle->edesc = GNUNET_strdup ("missing parameter grant_type");
2222 handle->response_code = MHD_HTTP_BAD_REQUEST;
2224 return;
2225 }
2226
2227 // Check parameter grant_type == "authorization_code"
2228 if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type))
2229 {
2231 handle->response_code = MHD_HTTP_BAD_REQUEST;
2232 GNUNET_free (grant_type);
2234 return;
2235 }
2236 GNUNET_free (grant_type);
2237 // REQUIRED code
2239 if (NULL == code)
2240 {
2242 handle->edesc = GNUNET_strdup ("missing parameter code");
2243 handle->response_code = MHD_HTTP_BAD_REQUEST;
2245 return;
2246 }
2247 ego_entry = find_ego (handle, &cid);
2248 if (NULL == ego_entry)
2249 {
2251 handle->edesc = GNUNET_strdup ("Unknown client");
2252 handle->response_code = MHD_HTTP_BAD_REQUEST;
2253 GNUNET_free (code);
2255 return;
2256 }
2257
2258 // REQUIRED code verifier
2260 if (NULL == code_verifier)
2261 {
2263 "OAuth authorization request does not contain PKCE parameters!\n");
2264
2265 }
2266
2267 // decode code
2268 if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid, code,
2269 code_verifier,
2270 &ticket,
2271 &cl, &pl, &nonce,
2273 {
2275 handle->edesc = GNUNET_strdup ("invalid code");
2276 handle->response_code = MHD_HTTP_BAD_REQUEST;
2277 GNUNET_free (code);
2278 if (NULL != code_verifier)
2279 GNUNET_free (code_verifier);
2281 return;
2282 }
2283 if (NULL != code_verifier)
2284 GNUNET_free (code_verifier);
2285
2286 // create jwt
2288 "reclaim-rest-plugin",
2289 "expiration_time",
2290 &expiration_time))
2291 {
2293 handle->edesc = GNUNET_strdup ("gnunet configuration failed");
2294 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2295 GNUNET_free (code);
2296 if (NULL != nonce)
2297 GNUNET_free (nonce);
2301 return;
2302 }
2303
2304 // Check if HMAC or RSA should be used
2306 "reclaim-rest-plugin",
2307 "oidc_json_web_algorithm",
2308 &jwa))
2309 {
2311 "Could not read OIDC JSON Web Algorithm config attribute."
2312 "Defaulting to RS256.");
2313 jwa = JWT_ALG_VALUE_RSA;
2314 }
2315
2316 char *tmp = GNUNET_strdup (ticket.gns_name);
2317 GNUNET_assert (NULL != strtok (tmp, "."));
2318 char *key = strtok (NULL, ".");
2319 struct GNUNET_CRYPTO_PublicKey issuer;
2320 GNUNET_assert (NULL != key);
2323 GNUNET_free (tmp);
2324
2325 if (! strcmp (jwa, JWT_ALG_VALUE_RSA))
2326 {
2327 // Replace for now
2328 oidc_jwk_path = get_oidc_jwk_path (cls);
2329 oidc_jwk = read_jwk_from_file (oidc_jwk_path);
2330
2331 // Check if secret JWK exists
2332 if (! oidc_jwk)
2333 {
2334 // Generate and save a new key
2336 oidc_directory = get_oidc_dir_path (cls);
2337
2338 // Create new oidc directory
2339 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
2340 {
2342 ("Failed to create directory `%s' for storing oidc data\n"),
2343 oidc_directory);
2344 }
2345 else
2346 {
2347 write_jwk_to_file (oidc_jwk_path, oidc_jwk);
2348 }
2349 }
2350
2351 // Generate oidc token
2352 id_token = OIDC_generate_id_token_rsa (received_cid,
2353 &issuer,
2354 cl,
2355 pl,
2356 &expiration_time,
2357 (NULL != nonce) ? nonce : NULL,
2358 oidc_jwk);
2359 }
2360 else if (! strcmp (jwa, JWT_ALG_VALUE_HMAC))
2361 {
2362 // TODO OPTIONAL acr,amr,azp
2364 "reclaim-rest-plugin",
2365 "jwt_secret",
2366 &jwt_secret))
2367 {
2369 handle->edesc = GNUNET_strdup ("No signing secret configured!");
2370 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
2371 GNUNET_free (code);
2374 if (NULL != nonce)
2375 GNUNET_free (nonce);
2377 return;
2378 }
2379
2380 id_token = OIDC_generate_id_token_hmac (received_cid,
2381 &issuer,
2382 cl,
2383 pl,
2384 &expiration_time,
2385 (NULL != nonce) ? nonce : NULL,
2386 jwt_secret);
2387
2388 GNUNET_free (jwt_secret);
2389 }
2390 else
2391 {
2392 // TODO: OPTION NOT FOUND ERROR
2393 }
2394
2395 if (NULL != nonce)
2396 GNUNET_free (nonce);
2397 access_token = OIDC_access_token_new (&ticket);
2402 GNUNET_CRYPTO_hash (access_token,
2403 strlen (access_token),
2404 &cache_key);
2416 &cache_key);
2418 &cache_key,
2419 code,
2421 /* If there was a previous code in there, free the old value */
2422 if (NULL != tmp_at)
2423 {
2425 "OIDC access token already issued. Cleanup.\n");
2426 GNUNET_free (tmp_at);
2427 }
2428
2429 OIDC_build_token_response (access_token,
2430 id_token,
2431 &expiration_time,
2432 &json_response);
2433
2434 resp = GNUNET_REST_create_response (json_response);
2435 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2436 "Cache-Control",
2437 "no-store"));
2438 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2439 "Pragma", "no-cache"));
2440 GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
2441 "Content-Type",
2442 "application/json"));
2443 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2446 GNUNET_free (access_token);
2447 GNUNET_free (json_response);
2448 GNUNET_free (id_token);
2450}
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:496
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:421
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)
Parse reclaim ticket and nonce from authorization code.
Definition: oidc_helper.c:751
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:473
char * OIDC_access_token_new(const struct GNUNET_RECLAIM_Ticket *ticket)
Generate a new access token.
Definition: oidc_helper.c:892
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:864
#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
json_t * read_jwk_from_file(const char *filename)
Read the the JSON Web Key in the given file and return it.
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.
const struct EgoEntry * find_ego(struct RequestHandle *handle, struct GNUNET_CRYPTO_PublicKey *test_key)
#define OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE
OIDC error key for unsupported grants.
char * get_oidc_jwk_path(void *cls)
Return the path to the RSA JWK key file.
#define OIDC_GRANT_TYPE_KEY
OIDC grant_type key.
Definition: openid_plugin.c:92
static int check_authorization(struct RequestHandle *handle, struct GNUNET_CRYPTO_PublicKey *cid)
#define OIDC_CODE_KEY
OIDC code key.
#define OIDC_GRANT_TYPE_VALUE
OIDC grant_type key.
Definition: openid_plugin.c:97
json_t * oidc_jwk
The RSA key used by the oidc enpoint.
json_t * generate_jwk()
Generate a new RSA JSON Web Key.
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_CRYPTO_public_key_from_string(), GNUNET_DISK_directory_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_RECLAIM_attribute_list_destroy(), GNUNET_RECLAIM_presentation_list_destroy(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_SYSERR, handle, JWT_ALG_VALUE_HMAC, JWT_ALG_VALUE_RSA, key, MHD_HTTP_BAD_REQUEST, MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_OK, 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_jwk, 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 2457 of file openid_plugin.c.

2461{
2462 struct RequestHandle *handle = cls;
2465 struct MHD_Response *resp;
2466 struct GNUNET_HashCode cache_key;
2467 char *result_str;
2468 char *cached_code;
2469
2470 if (NULL != handle->consume_timeout_op)
2471 GNUNET_SCHEDULER_cancel (handle->consume_timeout_op);
2472 handle->consume_timeout_op = NULL;
2473 handle->idp_op = NULL;
2474
2478 GNUNET_CRYPTO_hash (handle->access_token,
2479 strlen (handle->access_token),
2480 &cache_key);
2482 &cache_key);
2483 if (NULL != cached_code)
2484 {
2487 &cache_key,
2488 cached_code));
2489 GNUNET_free (cached_code);
2490 }
2491
2492
2493 if (NULL == identity)
2494 {
2495 char *tmp = GNUNET_strdup (handle->ticket.gns_name);
2496 GNUNET_assert (NULL != strtok (tmp, "."));
2497 char *key = strtok (NULL, ".");
2498 struct GNUNET_CRYPTO_PublicKey issuer;
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:346
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, MHD_HTTP_OK, 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 char *nonce;
2563 char *cached_code;
2564 char *result_str;
2565 char *received_cid;
2566
2567 handle->consume_timeout_op = NULL;
2568 if (NULL != handle->idp_op)
2569 GNUNET_RECLAIM_cancel (handle->idp_op);
2570 handle->idp_op = NULL;
2571
2573 "Ticket consumptioned timed out. Using cache...\n");
2574 GNUNET_CRYPTO_hash (handle->access_token,
2575 strlen (handle->access_token),
2576 &cache_key);
2578 &cache_key);
2579 if (NULL == cached_code)
2580 {
2582 handle->edesc = GNUNET_strdup ("No Access Token in cache!");
2583 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2585 return;
2586 }
2592 &cache_key,
2593 cached_code));
2595 GNUNET_STRINGS_string_to_data (received_cid,
2596 strlen (received_cid),
2597 &cid,
2598 sizeof(struct GNUNET_CRYPTO_PublicKey));
2599
2600 // decode code
2601 if (GNUNET_OK != OIDC_parse_authz_code (received_cid, &cid,
2602 cached_code, NULL, &ticket,
2603 &cl, &pl, &nonce,
2605 {
2607 handle->edesc = GNUNET_strdup ("invalid code");
2608 handle->response_code = MHD_HTTP_BAD_REQUEST;
2609 GNUNET_free (cached_code);
2610 if (NULL != nonce)
2611 GNUNET_free (nonce);
2613 return;
2614 }
2615
2616 GNUNET_free (cached_code);
2617
2618 char *tmp = GNUNET_strdup (handle->ticket.gns_name);
2619 GNUNET_assert (NULL != strtok (tmp, "."));
2620 char *key = strtok (NULL, ".");
2621 struct GNUNET_CRYPTO_PublicKey issuer;
2622 GNUNET_assert (NULL != key);
2625 GNUNET_free (tmp);
2626 result_str = OIDC_generate_userinfo (&issuer,
2627 cl,
2628 pl);
2629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Userinfo: %s\n", result_str);
2630 resp = GNUNET_REST_create_response (result_str);
2631 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
2632 GNUNET_free (result_str);
2633 GNUNET_free (nonce);
2637}
@ 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, MHD_HTTP_BAD_REQUEST, MHD_HTTP_OK, MHD_HTTP_UNAUTHORIZED, 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 2648 of file openid_plugin.c.

2651{
2652 // TODO expiration time
2653 struct RequestHandle *handle = cls;
2655 char delimiter[] = " ";
2656 struct GNUNET_HashCode cache_key;
2657 char *authorization;
2658 char *authorization_type;
2659 char *authorization_access_token;
2660
2661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n");
2664 &cache_key);
2666 ->header_param_map,
2667 &cache_key))
2668 {
2670 handle->edesc = GNUNET_strdup ("No Access Token");
2671 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2673 return;
2674 }
2675 authorization =
2676 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map,
2677 &cache_key);
2678
2679 // split header in "Bearer" and access_token
2680 authorization = GNUNET_strdup (authorization);
2681 authorization_type = strtok (authorization, delimiter);
2682 if ((NULL == authorization_type) ||
2683 (0 != strcmp ("Bearer", authorization_type)))
2684 {
2686 handle->edesc = GNUNET_strdup ("No Access Token");
2687 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2689 GNUNET_free (authorization);
2690 return;
2691 }
2692 authorization_access_token = strtok (NULL, delimiter);
2693 if (NULL == authorization_access_token)
2694 {
2696 handle->edesc = GNUNET_strdup ("Access token missing");
2697 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2699 GNUNET_free (authorization);
2700 return;
2701 }
2702
2703 if (GNUNET_OK != OIDC_access_token_parse (authorization_access_token,
2704 &ticket))
2705 {
2707 handle->edesc = GNUNET_strdup ("The access token is invalid");
2708 handle->response_code = MHD_HTTP_UNAUTHORIZED;
2710 GNUNET_free (authorization);
2711 return;
2712
2713 }
2714 GNUNET_assert (NULL != ticket);
2715 handle->ticket = *ticket;
2717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n");
2718 handle->attr_userinfo_list =
2720 handle->presentations =
2722
2723 /* If the consume takes too long, we use values from the cache */
2724 handle->access_token = GNUNET_strdup (authorization_access_token);
2726 &consume_fail,
2727 handle);
2729 &handle->ticket,
2731 handle);
2732 GNUNET_free (authorization);
2733}
struct GNUNET_RECLAIM_Operation * GNUNET_RECLAIM_ticket_consume(struct GNUNET_RECLAIM_Handle *h, const struct GNUNET_RECLAIM_Ticket *ticket, 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:1278
int OIDC_access_token_parse(const char *token, struct GNUNET_RECLAIM_Ticket **ticket)
Parse an access token.
Definition: oidc_helper.c:907
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, MHD_HTTP_UNAUTHORIZED, 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 2744 of file openid_plugin.c.

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

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, MHD_HTTP_OK, oidc_jwk, 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 2825 of file openid_plugin.c.

2829{
2830 struct EgoEntry *ego_entry;
2832
2833 if (NULL == ego)
2834 {
2836 return;
2837 }
2839
2840 {
2841 ego_entry = GNUNET_new (struct EgoEntry);
2844 ego_entry->ego = ego;
2845 ego_entry->identifier = GNUNET_strdup (identifier);
2847 ego_tail,
2848 ego_entry);
2849 return;
2850 }
2851 /* Ego renamed or added */
2852 if (identifier != NULL)
2853 {
2854 for (ego_entry = ego_head; NULL != ego_entry;
2855 ego_entry = ego_entry->next)
2856 {
2857 if (ego_entry->ego == ego)
2858 {
2859 /* Rename */
2860 GNUNET_free (ego_entry->identifier);
2861 ego_entry->identifier = GNUNET_strdup (identifier);
2862 break;
2863 }
2864 }
2865 if (NULL == ego_entry)
2866 {
2867 /* Add */
2868 ego_entry = GNUNET_new (struct EgoEntry);
2871 ego_entry->ego = ego;
2872 ego_entry->identifier = GNUNET_strdup (identifier);
2874 ego_tail,
2875 ego_entry);
2876 }
2877 }
2878 else
2879 {
2880 /* Delete */
2881 for (ego_entry = ego_head; NULL != ego_entry;
2882 ego_entry = ego_entry->next)
2883 {
2884 if (ego_entry->ego == ego)
2885 break;
2886 }
2887 if (NULL == ego_entry)
2888 return; /* Not found */
2889
2891 ego_tail,
2892 ego_entry);
2893 GNUNET_free (ego_entry->identifier);
2894 GNUNET_free (ego_entry->keystring);
2895 GNUNET_free (ego_entry);
2896 return;
2897 }
2898}
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:551
#define ID_REST_STATE_INIT
State while collecting all egos.
Definition: openid_plugin.c:82
static int state
The processing state.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
Definition: openid_plugin.c:87
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 2902 of file openid_plugin.c.

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

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

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

3006{
3007 struct MHD_Response *resp;
3008 struct RequestHandle *handle = cls;
3009
3010 // For now, independent of path return all options
3011 resp = GNUNET_REST_create_response (NULL);
3012 GNUNET_assert (MHD_NO !=
3013 MHD_add_response_header (resp,
3014 "Access-Control-Allow-Methods",
3015 allow_methods));
3016 GNUNET_assert (MHD_NO !=
3017 MHD_add_response_header (resp,
3018 "Access-Control-Allow-Origin",
3019 "*"));
3020 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
3022 return;
3023}

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

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

3031{
3032 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
3034 static const struct GNUNET_REST_RequestHandler handlers[] =
3035 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
3036 { MHD_HTTP_METHOD_POST,
3038 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
3039 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
3040 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
3041 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
3042 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_JWKS, &jwks_endpoint },
3043 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_OIDC_CONFIG,
3045 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC_CONFIG,
3047 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
3049
3050 handle->oidc = GNUNET_new (struct OIDC_Variables);
3051 if (NULL == OIDC_cookie_jar_map)
3053 GNUNET_NO);
3054 if (NULL == oidc_code_cache)
3056 GNUNET_NO);
3057
3058 handle->response_code = 0;
3060 handle->proc_cls = proc_cls;
3061 handle->proc = proc;
3062 handle->rest_handle = rest_handle;
3063 handle->url = GNUNET_strdup (rest_handle->url);
3064 handle->timeout_task =
3068 handle);
3069 if (handle->url[strlen (handle->url) - 1] == '/')
3070 handle->url[strlen (handle->url) - 1] = '\0';
3071 if (GNUNET_NO ==
3072 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
3073 return GNUNET_NO;
3074
3075 return GNUNET_YES;
3076}
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:52
#define GNUNET_REST_API_NS_LOGIN
Login namespace.
Definition: openid_plugin.c:77
#define GNUNET_REST_API_NS_OIDC
REST root namespace.
Definition: openid_plugin.c:47
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:67
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:62
#define GNUNET_REST_API_NS_USERINFO
UserInfo endpoint.
Definition: openid_plugin.c:72
#define GNUNET_REST_API_NS_AUTHORIZE
Authorize endpoint.
Definition: openid_plugin.c:57
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 3086 of file openid_plugin.c.

3087{
3088 static struct Plugin plugin;
3089 struct GNUNET_REST_Plugin *api;
3090
3091 oid_cfg = c;
3092 if (NULL != plugin.cfg)
3093 return NULL; /* can only initialize once! */
3094 memset (&plugin, 0, sizeof(struct Plugin));
3095 plugin.cfg = oid_cfg;
3096 api = GNUNET_new (struct GNUNET_REST_Plugin);
3097 api->cls = &plugin;
3103 "reclaim-rest-plugin",
3104 "OIDC_USERINFO_CONSUME_TIMEOUT",
3106 {
3108 }
3109
3110
3113 "%s, %s, %s, %s, %s",
3114 MHD_HTTP_METHOD_GET,
3115 MHD_HTTP_METHOD_POST,
3116 MHD_HTTP_METHOD_PUT,
3117 MHD_HTTP_METHOD_DELETE,
3118 MHD_HTTP_METHOD_OPTIONS);
3119
3121 _ ("OpenID Connect REST API initialized\n"));
3122 return api;
3123}
struct TestcasePlugin * plugin
The process handle to the testbed service.
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:178
struct returned by the initialization function of the plugin
char * name
Plugin name.
void * cls
The closure of the plugin.
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 3127 of file openid_plugin.c.

3128{
3130 return GNUNET_YES;
3131}

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 ( void *  cls)

Exit point from the plugin.

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

Definition at line 3141 of file openid_plugin.c.

3142{
3143 struct GNUNET_REST_Plugin *api = cls;
3144 struct Plugin *plugin = api->cls;
3145 struct EgoEntry *ego_entry;
3146
3147 plugin->cfg = NULL;
3148 while (NULL != requests_head)
3150 if (NULL != OIDC_cookie_jar_map)
3151 {
3154 NULL);
3156 }
3157 if (NULL != oidc_code_cache)
3158 {
3161 NULL);
3163 }
3164
3166 if (NULL != gns_handle)
3168 if (NULL != identity_handle)
3170 if (NULL != idp)
3172 while (NULL != (ego_entry = ego_head))
3173 {
3175 ego_tail,
3176 ego_entry);
3177 GNUNET_free (ego_entry->identifier);
3178 GNUNET_free (ego_entry->keystring);
3179 GNUNET_free (ego_entry);
3180 }
3181 GNUNET_free (api);
3183 "OpenID Connect REST plugin is finished\n");
3184 return NULL;
3185}
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, GNUNET_REST_Plugin::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

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 248 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 259 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 264 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 269 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 274 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 284 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 289 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 294 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 299 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 309 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 enpoint.

Definition at line 322 of file openid_plugin.c.

Referenced by jwks_endpoint(), and token_endpoint().

◆ requests_head

struct RequestHandle* requests_head
static

DLL.

Definition at line 586 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 591 of file openid_plugin.c.

Referenced by cleanup_handle(), and REST_openid_process_request().