diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a4e9da..278a1860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,12 @@ -## oidc-agent 5.1.1 +## oidc-agent 5.2.0 + +### Features + +- Added possibility to add custom request parameters to requests done by the agent. This is done through + a `custom_parameters.config` file placed in the agent dir or `/etc/oidc-agent` ### Change / Enhancement / Bugfix diff --git a/VERSION b/VERSION index 3bff0591..7cbea073 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.1.1 \ No newline at end of file +5.2.0 \ No newline at end of file diff --git a/config/custom_parameters.config.example b/config/custom_parameters.config.example new file mode 100644 index 00000000..faf2f9db --- /dev/null +++ b/config/custom_parameters.config.example @@ -0,0 +1,23 @@ +[ + { + "parameter": "key", + "value": "value / $VALUE / /home/user/value", + "for_issuer": [ + "https://example.com" + ], + "for_account": [ + "iam", + "example" + ], + "request": [ + "refresh", + "auth_url", + "code-exchange", + "device-init", + "device-polling", + "registration", + "revocation", + "password" + ] + } +] \ No newline at end of file diff --git a/config/custom_parameters.config.unity b/config/custom_parameters.config.unity new file mode 100644 index 00000000..ed109337 --- /dev/null +++ b/config/custom_parameters.config.unity @@ -0,0 +1,13 @@ +[ + { + "parameter": "claims_in_tokens", + "value": "id_token token", + "for_issuer": [ + "https://login.helmholtz.de/oauth2", + "https://login-dev.helmholtz.de/oauth2" + ], + "request": [ + "auth_url" + ] + } +] \ No newline at end of file diff --git a/gitbook/configuration/custom-parameters.md b/gitbook/configuration/custom-parameters.md new file mode 100644 index 00000000..b02aff0e --- /dev/null +++ b/gitbook/configuration/custom-parameters.md @@ -0,0 +1,18 @@ +# Custom Request Parameter + +Since version `5.2.0` it is possible to customize the requests send by the agent to the OPs and add custom request +parameters. + +Custom parameters can be configured in a config file named `custom_parameters.config`. As usual the file can be placed +in `/etc/oidc-agent` or the agent directory. If both are present parameters are merged together. + +The `custom_parameters.config` contains a json array of parameter specifications. A parameter specification is a json +object that can have the following fields: + +| Field Name | Description | +|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `parameter` | The name of the parameter to be added to the request | +| `value` | The value that should be used. The value can be given in different ways. If the value starts with a `$` the following characters are interpreted as an environment variable and the value is read from this variable. If the given value starts with an `/` it is interpreted as a file path and the first line from that file is used as the value. Otherwise the value is used directly. | +| `for_issuer` | A JSON array of issuer urls for which this parameter should be used | +| `for_account` | A JSON array of account shortnames for which this parameter should be used | +| `request` | A JSON array of requests for which this parameter should be used. Possible values are `refresh`, `auth_url`, `code-exchange`,`device-init`,`device-polling`,`registration`,`revocation`,`password` | diff --git a/gitbook/configuration/default-accounts.md b/gitbook/configuration/default-accounts.md index c47d74c9..8f9d8bfc 100644 --- a/gitbook/configuration/default-accounts.md +++ b/gitbook/configuration/default-accounts.md @@ -1,9 +1,6 @@ ## Default Account Configuration for a Provider + The `issuer.config` file in the [oidc-agent directory](directory.md) can also -be used to set an default account configuration file for each provider by adding -the shortname of this account configuration after the issuer url. -A line in the `issuer.config` file should look the following: -``` -[] -``` +be used to set a default account configuration file for each provider by using the `default_account` claim. for more +details please refer to the [documentations about issuer.config](issuers.md). diff --git a/gitbook/provider/known-issues.md b/gitbook/provider/known-issues.md index b53176ea..2cfcdce3 100644 --- a/gitbook/provider/known-issues.md +++ b/gitbook/provider/known-issues.md @@ -1,11 +1,14 @@ ## Known Issues + ### Expiring Refresh Tokens + oidc-agent assumes that refresh tokens do not expire. But some providers might use refresh tokens that expire after a certain time or when they are not used for a specific time. To prevent the latter use oidc-agent / oidc-token regularly -(you also can use a cron job). +(you can also use a cron job). oidc-agent is able to update a stored refresh token. However, therefore it has to receive a new -refresh token from the provider. If a refresh token expired (e.g. because the token was used within the lifetime of that token), use `oidc-gen --reauthenticate ` to re-authenticate and update the refresh token. +refresh token from the provider. If a refresh token expired (e.g. because the token was used within the lifetime of that +token), use `oidc-gen --reauthenticate ` to re-authenticate and update the refresh token. diff --git a/src/defines/agent_values.h b/src/defines/agent_values.h index ab1da22c..01a3b5d7 100644 --- a/src/defines/agent_values.h +++ b/src/defines/agent_values.h @@ -54,6 +54,12 @@ #define CONFIG_KEY_LEGACYAUDMODE "legacy_aud_mode" #define CONFIG_KEY_PLAINADD "skip-check" +#define CUSTOMPARAMETERS_KEY_PARAMETER "parameter" +#define CUSTOMPARAMETERS_KEY_VALUE "value" +#define CUSTOMPARAMETERS_KEY_ISSUERS "for_issuer" +#define CUSTOMPARAMETERS_KEY_ACCOUNTS "for_account" +#define CUSTOMPARAMETERS_KEY_REQUESTS "request" + #define ACCOUNTINFO_KEY_HASPUBCLIENT "pubclient" // INTERNAL / CLI FLOW VALUES diff --git a/src/defines/settings.c b/src/defines/settings.c index ed5c8282..2d6b4329 100644 --- a/src/defines/settings.c +++ b/src/defines/settings.c @@ -12,12 +12,13 @@ // one is appended later #endif -char* _config_path = NULL; -char* _cert_file = NULL; -char* _etc_issuer_config_file = NULL; -char* _etc_issuer_config_dir = NULL; -char* _etc_config_file = NULL; -char* _etc_mytoken_base = NULL; +char* _config_path = NULL; +char* _cert_file = NULL; +char* _etc_issuer_config_file = NULL; +char* _etc_issuer_config_dir = NULL; +char* _etc_custom_parameter_file = NULL; +char* _etc_config_file = NULL; +char* _etc_mytoken_base = NULL; static const char* config_path() { if (_config_path == NULL) { @@ -49,6 +50,14 @@ const char* ETC_ISSUER_CONFIG_DIR() { return _etc_issuer_config_dir; } +const char* ETC_CUSTOM_PARAMETERS_FILE() { + if (_etc_custom_parameter_file == NULL) { + _etc_custom_parameter_file = + oidc_pathcat(config_path(), "oidc-agent/" CUSTOM_PARAMETERS_FILENAME); + } + return _etc_custom_parameter_file; +} + const char* ETC_CONFIG_FILE() { if (_etc_config_file == NULL) { _etc_config_file = oidc_pathcat(config_path(), "oidc-agent/config"); diff --git a/src/defines/settings.h b/src/defines/settings.h index c3856e81..c99556a7 100644 --- a/src/defines/settings.h +++ b/src/defines/settings.h @@ -39,11 +39,13 @@ // file names #define ISSUER_CONFIG_FILENAME "issuer.config" #define ISSUER_CONFIG_DIRNAME ISSUER_CONFIG_FILENAME ".d" +#define CUSTOM_PARAMETERS_FILENAME "custom_parameters.config" #ifdef ANY_MSYS const char* CERT_FILE(); const char* ETC_ISSUER_CONFIG_FILE(); const char* ETC_ISSUER_CONFIG_DIR(); +const char* ETC_CUSTOM_PARAMETERS_FILE(); const char* _MYTOKEN_GLOBAL_BASE(); const char* ETC_CONFIG_FILE(); @@ -56,6 +58,8 @@ const char* ETC_CONFIG_FILE(); #define ETC_ISSUER_CONFIG_FILE CONFIG_PATH "/oidc-agent/" ISSUER_CONFIG_FILENAME #define ETC_ISSUER_CONFIG_DIR CONFIG_PATH "/oidc-agent/" ISSUER_CONFIG_DIRNAME +#define ETC_CUSTOM_PARAMETERS_FILE \ + CONFIG_PATH "/oidc-agent/" CUSTOM_PARAMETERS_FILENAME #define ETC_CONFIG_FILE CONFIG_PATH "/oidc-agent/config" #endif diff --git a/src/oidc-agent/oidc/flows/code.c b/src/oidc-agent/oidc/flows/code.c index 87736e2d..ea89b37f 100644 --- a/src/oidc-agent/oidc/flows/code.c +++ b/src/oidc-agent/oidc/flows/code.c @@ -7,6 +7,7 @@ #include "oidc-agent/httpserver/startHttpserver.h" #include "oidc.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/config/issuerConfig.h" #include "utils/crypt/crypt.h" #include "utils/listUtils.h" @@ -37,6 +38,7 @@ oidc_error_t codeExchange(struct oidc_account* account, const char* code, list_rpush(postData, list_node_new(account_getClientSecret(account))); } } + addCustomParameters(postData, account, OIDC_REQUEST_TYPE_CODEEXCHANGE); char* data = generatePostDataFromList(postData); list_destroy(postData); if (data == NULL) { @@ -146,6 +148,7 @@ char* buildCodeFlowUri(const struct oidc_account* account, char** state_ptr, addAudienceRFC8707ToList(postData, aud_tmp); } } + addCustomParameters(postData, account, OIDC_REQUEST_TYPE_AUTHURL); char* uri_parameters = generatePostDataFromList(postData); secFree(code_challenge); secFree(scope); diff --git a/src/oidc-agent/oidc/flows/device.c b/src/oidc-agent/oidc/flows/device.c index 3c862c74..f4aa8086 100644 --- a/src/oidc-agent/oidc/flows/device.c +++ b/src/oidc-agent/oidc/flows/device.c @@ -6,14 +6,16 @@ #include "oidc-agent/oidcd/deviceCodeEntry.h" #include "oidc.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/config/issuerConfig.h" #include "utils/db/deviceCode_db.h" #include "utils/errorUtils.h" #include "utils/string/stringUtils.h" char* generateDeviceCodePostData(const struct oidc_account* a) { - return generatePostData(OIDC_KEY_CLIENTID, account_getClientId(a), - OIDC_KEY_SCOPE, account_getAuthScope(a), NULL); + return generatePostData(OIDC_REQUEST_TYPE_DEVICEINIT, a, OIDC_KEY_CLIENTID, + account_getClientId(a), OIDC_KEY_SCOPE, + account_getAuthScope(a), NULL); } char* generateDeviceCodeLookupPostData(const struct oidc_account* a, @@ -41,6 +43,7 @@ char* generateDeviceCodeLookupPostData(const struct oidc_account* a, addAudienceRFC8707ToList(postDataList, aud_tmp); } } + addCustomParameters(postDataList, a, OIDC_REQUEST_TYPE_DEVICEPOLLING); char* str = generatePostDataFromList(postDataList); list_destroy(postDataList); secFree(tmp_devicecode); diff --git a/src/oidc-agent/oidc/flows/oidc.c b/src/oidc-agent/oidc/flows/oidc.c index e932007b..bf9cdbc0 100644 --- a/src/oidc-agent/oidc/flows/oidc.c +++ b/src/oidc-agent/oidc/flows/oidc.c @@ -11,6 +11,7 @@ #include "oidc-agent/http/http_ipc.h" #include "oidc-agent/oidcd/internal_request_handler.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/errorUtils.h" #include "utils/json.h" #include "utils/key_value.h" @@ -21,7 +22,9 @@ /** * last argument has to be NULL */ -char* generatePostData(char* k1, char* v1, ...) { +char* generatePostData(const char* request_type, + const struct oidc_account* account, char* k1, char* v1, + ...) { va_list args; va_start(args, v1); list_t* list = list_new(); @@ -32,6 +35,7 @@ char* generatePostData(char* k1, char* v1, ...) { list_rpush(list, list_node_new(s)); } va_end(args); + addCustomParameters(list, account, request_type); char* data = generatePostDataFromList(list); list_destroy(list); return data; diff --git a/src/oidc-agent/oidc/flows/oidc.h b/src/oidc-agent/oidc/flows/oidc.h index 9b022051..8d611220 100644 --- a/src/oidc-agent/oidc/flows/oidc.h +++ b/src/oidc-agent/oidc/flows/oidc.h @@ -11,7 +11,9 @@ #define TOKENPARSEMODE_RETURN_MT 0x08 #define TOKENPARSEMODE_SAVE_MT 0x08 -char* generatePostData(char* k1, char* v1, ...); +char* generatePostData(const char* request_type, + const struct oidc_account* account, char* k1, char* v1, + ...); char* generatePostDataFromList(list_t* list); char* parseTokenResponse(unsigned char mode, const char* res, struct oidc_account* a, struct ipcPipe pipes, diff --git a/src/oidc-agent/oidc/flows/password.c b/src/oidc-agent/oidc/flows/password.c index 62302350..d90cb6ad 100644 --- a/src/oidc-agent/oidc/flows/password.c +++ b/src/oidc-agent/oidc/flows/password.c @@ -7,6 +7,7 @@ #include "oidc-agent/http/http_ipc.h" #include "oidc.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/config/issuerConfig.h" #include "utils/oidc_error.h" #include "utils/string/stringUtils.h" @@ -40,6 +41,7 @@ char* generatePasswordPostData(const struct oidc_account* a, addAudienceRFC8707ToList(postDataList, aud_tmp); } } + addCustomParameters(postDataList, a, OIDC_REQUEST_TYPE_PASSWORD); char* str = generatePostDataFromList(postDataList); secFree(aud_tmp); list_destroy(postDataList); diff --git a/src/oidc-agent/oidc/flows/refresh.c b/src/oidc-agent/oidc/flows/refresh.c index de720189..79685f1f 100644 --- a/src/oidc-agent/oidc/flows/refresh.c +++ b/src/oidc-agent/oidc/flows/refresh.c @@ -7,6 +7,7 @@ #include "oidc-agent/http/http_ipc.h" #include "oidc.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/config/issuerConfig.h" #include "utils/string/stringUtils.h" @@ -57,6 +58,7 @@ char* generateRefreshPostData(const struct oidc_account* a, const char* scope, addAudienceRFC8707ToList(postDataList, aud_tmp); } } + addCustomParameters(postDataList, a, OIDC_REQUEST_TYPE_REFRESH); char* str = generatePostDataFromList(postDataList); list_destroy(postDataList); secFree(aud_tmp); diff --git a/src/oidc-agent/oidc/flows/revoke.c b/src/oidc-agent/oidc/flows/revoke.c index 820eb8f2..97ad0952 100644 --- a/src/oidc-agent/oidc/flows/revoke.c +++ b/src/oidc-agent/oidc/flows/revoke.c @@ -5,6 +5,7 @@ #include "oidc-agent/http/http_ipc.h" #include "oidc.h" #include "utils/agentLogger.h" +#include "utils/config/custom_parameter.h" #include "utils/parseJson.h" #include "utils/string/stringUtils.h" @@ -18,8 +19,9 @@ oidc_error_t _revokeToken(struct oidc_account* account, } char* refresh_token = account_getRefreshToken(account); char* data = generatePostData( - OIDC_KEY_TOKENTYPE_HINT, OIDC_TOKENTYPE_REFRESH, OIDC_KEY_TOKEN, - refresh_token, withClientId ? OIDC_KEY_CLIENTID : NULL, + OIDC_REQUEST_TYPE_REVOKE, account, OIDC_KEY_TOKENTYPE_HINT, + OIDC_TOKENTYPE_REFRESH, OIDC_KEY_TOKEN, refresh_token, + withClientId ? OIDC_KEY_CLIENTID : NULL, withClientId ? account_getClientId(account) : NULL, NULL); if (data == NULL) { return oidc_errno; diff --git a/src/utils/config/custom_parameter.c b/src/utils/config/custom_parameter.c new file mode 100644 index 00000000..fb789f98 --- /dev/null +++ b/src/utils/config/custom_parameter.c @@ -0,0 +1,225 @@ +#include "custom_parameter.h" + +#include + +#include "defines/agent_values.h" +#include "defines/settings.h" +#include "utils/file_io/file_io.h" +#include "utils/file_io/oidc_file_io.h" +#include "utils/json.h" +#include "utils/listUtils.h" +#include "utils/logger.h" +#include "utils/memory.h" +#include "utils/printer.h" +#include "utils/string/stringUtils.h" + +struct custom_parameter_tuple { + char* parameter; + char* value; + char* issuer; + char* account; + char* request; +}; + +int match_custom_parameter_tuples(struct custom_parameter_tuple* a, + struct custom_parameter_tuple* b) { + if (a == NULL && b == NULL) { + return 1; + } + if (a == NULL || b == NULL) { + return 0; + } + return strequal(a->parameter, b->parameter) && + strequal(a->request, b->request) && strequal(a->issuer, b->issuer) && + strequal(a->account, b->account); +} + +void _secFreeCustomParameterTuple(struct custom_parameter_tuple* p) { + if (p == NULL) { + return; + } + secFree(p->parameter); + secFree(p->value); + secFree(p->issuer); + secFree(p->account); + secFree(p->request); + secFree(p); +} + +char* tmp_file_value = NULL; + +const char* getValue(const struct custom_parameter_tuple* p) { + const char* v = p->value; + if (!strValid(v)) { + return NULL; + } + secFree(tmp_file_value); + switch (v[0]) { + case '$': return (getenv(v + 1)); + case '/': tmp_file_value = getLineFromFile(v); return tmp_file_value; + default: return (v); + } +} + +list_t* file_values = NULL; +list_t* _custom_parameters = NULL; + +list_t* parseCustomParametersObject(cJSON* j) { + INIT_KEY_VALUE(CUSTOMPARAMETERS_KEY_PARAMETER, CUSTOMPARAMETERS_KEY_VALUE, + CUSTOMPARAMETERS_KEY_ISSUERS, CUSTOMPARAMETERS_KEY_ACCOUNTS, + CUSTOMPARAMETERS_KEY_REQUESTS); + GET_JSON_VALUES_CJSON_RETURN_NULL_ONERROR(j); + KEY_VALUE_VARS(parameter, value, issuers, accounts, requests); + list_t* requests = JSONArrayStringToList(_requests); + if (requests == NULL) { + SEC_FREE_KEY_VALUES(); + return NULL; + } + list_t* issuers = JSONArrayStringToList(_issuers); + list_t* accounts = JSONArrayStringToList(_accounts); + if (issuers == NULL && accounts == NULL) { + SEC_FREE_KEY_VALUES(); + secFreeList(requests); + return NULL; + } + list_t* tuples = list_new(); + tuples->free = (freeFunction)_secFreeCustomParameterTuple; + tuples->match = (matchFunction)match_custom_parameter_tuples; + + list_iterator_t* requests_it = list_iterator_new(requests, LIST_HEAD); + list_node_t* requests_node; + while ((requests_node = list_iterator_next(requests_it))) { + if (issuers) { + list_iterator_t* issuers_it = list_iterator_new(issuers, LIST_HEAD); + list_node_t* issuers_node; + while ((issuers_node = list_iterator_next(issuers_it))) { + struct custom_parameter_tuple* p = + secAlloc(sizeof(struct custom_parameter_tuple)); + p->parameter = oidc_strcopy(_parameter); + p->value = oidc_strcopy(_value); + p->request = oidc_strcopy(requests_node->val); + p->issuer = oidc_strcopy(issuers_node->val); + list_rpush(tuples, list_node_new(p)); + } + list_iterator_destroy(issuers_it); + } + if (accounts) { + list_iterator_t* accounts_it = list_iterator_new(accounts, LIST_HEAD); + list_node_t* accounts_node; + while ((accounts_node = list_iterator_next(accounts_it))) { + struct custom_parameter_tuple* p = + secAlloc(sizeof(struct custom_parameter_tuple)); + p->parameter = oidc_strcopy(_parameter); + p->value = oidc_strcopy(_value); + p->request = oidc_strcopy(requests_node->val); + p->account = oidc_strcopy(accounts_node->val); + list_rpush(tuples, list_node_new(p)); + } + list_iterator_destroy(accounts_it); + } + } + list_iterator_destroy(requests_it); + secFreeList(accounts); + secFreeList(issuers); + secFreeList(requests); + SEC_FREE_KEY_VALUES(); + return tuples; +} + +void parseCustomParametersFileContent(const char* content) { + if (content == NULL) { + return; + } + cJSON* json = stringToJson(content); + if (json == NULL) { + return; + } + if (!cJSON_IsArray(json)) { + logger(ERROR, "malformed " CUSTOM_PARAMETERS_FILENAME); + secFreeJson(json); + return; + } + size_t current_len = _custom_parameters->len; + cJSON* j = json->child; + while (j) { + list_t* parameters = parseCustomParametersObject(j); + if (parameters == NULL) { + j = j->next; + continue; + } + parameters->free = NULL; // We'll manually free each node IF we do not add + // it to the other list. + list_iterator_t* it = list_iterator_new(parameters, LIST_HEAD); + list_node_t* node; + while ((node = list_iterator_next(it))) { + struct custom_parameter_tuple* p = node->val; + if (findInListUntil(_custom_parameters, current_len, p)) { + _secFreeCustomParameterTuple(p); + } else { + list_rpush(_custom_parameters, list_node_new(p)); + } + } + list_iterator_destroy(it); + secFreeList(parameters); + j = j->next; + } + secFreeJson(json); +} + +list_t* custom_parameters() { + if (_custom_parameters != NULL) { + return _custom_parameters; + } + _custom_parameters = list_new(); + _custom_parameters->free = (freeFunction)_secFreeCustomParameterTuple; + _custom_parameters->match = (matchFunction)match_custom_parameter_tuples; + char* agent_dir_content = readOidcFile(CUSTOM_PARAMETERS_FILENAME); + char* etc_content = readFile( +#ifdef ANY_MSYS + ETC_CUSTOM_PARAMETERS_FILE() +#else + ETC_CUSTOM_PARAMETERS_FILE +#endif + ); + parseCustomParametersFileContent(agent_dir_content); + parseCustomParametersFileContent(etc_content); + secFree(agent_dir_content); + secFree(etc_content); + return _custom_parameters; +} + +void _addCustomParameters(list_t* request_params, list_t* custom_parameters, + const struct oidc_account* account, + const char* request_type) { + secFreeList(file_values); + file_values = list_new(); + file_values->match = (matchFunction)strequal; + file_values->free = _secFree; + + list_iterator_t* it = list_iterator_new(custom_parameters, LIST_HEAD); + list_node_t* node; + while ((node = list_iterator_next(it))) { + struct custom_parameter_tuple* p = node->val; + if (!strequal(request_type, p->request)) { + continue; + } + if (!strequal(p->issuer, account_getIssuerUrl(account)) && + !strequal(p->account, account_getName(account))) { + continue; + } + list_rpush(request_params, list_node_new(p->parameter)); + list_rpush(request_params, list_node_new((void*)getValue(p))); + if (tmp_file_value != NULL) { + list_rpush(file_values, list_node_new(tmp_file_value)); + tmp_file_value = NULL; + } + } + list_iterator_destroy(it); +} + +void addCustomParameters(list_t* request_params, + const struct oidc_account* account, + const char* request_type) { + _addCustomParameters(request_params, custom_parameters(), account, + request_type); +} \ No newline at end of file diff --git a/src/utils/config/custom_parameter.h b/src/utils/config/custom_parameter.h new file mode 100644 index 00000000..20a9c21b --- /dev/null +++ b/src/utils/config/custom_parameter.h @@ -0,0 +1,19 @@ +#ifndef OIDC_CUSTOM_PARAMETER_H +#define OIDC_CUSTOM_PARAMETER_H + +#include "account/account.h" +#include "wrapper/list.h" + +#define OIDC_REQUEST_TYPE_REFRESH "refresh" +#define OIDC_REQUEST_TYPE_AUTHURL "auth_url" +#define OIDC_REQUEST_TYPE_CODEEXCHANGE "code-exchange" +#define OIDC_REQUEST_TYPE_DEVICEINIT "device-init" +#define OIDC_REQUEST_TYPE_DEVICEPOLLING "device-polling" +#define OIDC_REQUEST_TYPE_REVOKE "revocation" +#define OIDC_REQUEST_TYPE_PASSWORD "password" + +void addCustomParameters(list_t* request_params, + const struct oidc_account* account, + const char* request_type); + +#endif // OIDC_CUSTOM_PARAMETER_H diff --git a/src/utils/listUtils.c b/src/utils/listUtils.c index 24029ce0..182e061d 100644 --- a/src/utils/listUtils.c +++ b/src/utils/listUtils.c @@ -253,6 +253,29 @@ list_node_t* findInList(list_t* l, const void* v) { return list_find(l, (void*)v); } +list_node_t* findInListUntil(list_t* l, size_t limit, const void* v) { + if (l == NULL) { + return NULL; + } + if (limit > l->len) { + limit = l->len; + } + list_node_t* node; + for (size_t i = 0; i < limit; i++) { + node = list_ats(l, i); + if (l->match) { + if (l->match((void*)v, node->val)) { + return node; + } + } else { + if (v == node->val) { + return node; + } + } + } + return NULL; +} + list_t* findAllInList(list_t* l, const void* v) { if (l == NULL || v == NULL) { return NULL; diff --git a/src/utils/listUtils.h b/src/utils/listUtils.h index 91097495..a688c90a 100644 --- a/src/utils/listUtils.h +++ b/src/utils/listUtils.h @@ -22,6 +22,7 @@ list_t* subtractLists(list_t* a, list_t* b); char* subtractListStrings(const char* a, const char* b, char del); char* listToJSONArrayString(list_t* list); list_node_t* findInList(list_t* l, const void* v); +list_node_t* findInListUntil(list_t* l, size_t limit, const void* v); list_t* findAllInList(list_t* l, const void* v); void list_removeIfFound(list_t* l, const void* v); void list_mergeSort(list_t* l, matchFunction comp);