From 547bce236ab46db3b2be3d34477d64108bc719fb Mon Sep 17 00:00:00 2001 From: zachmann Date: Thu, 21 Dec 2023 11:33:44 +0100 Subject: [PATCH] [oidc-add; oidc-agent] add option to oidc-add to add an config to the agent without checking if it works; #553 --- src/defines/agent_values.h | 1 + src/defines/ipc_values.h | 6 +++-- src/oidc-add/add_handler.c | 14 +++++------ src/oidc-add/oidc-add_options.c | 8 ++++++ src/oidc-add/oidc-add_options.h | 29 +++++++++++----------- src/oidc-agent/oidcd/oidcd.c | 12 +++++---- src/oidc-agent/oidcd/oidcd_handler.c | 37 +++++++++++++++------------- src/oidc-agent/oidcd/oidcd_handler.h | 2 +- src/utils/config/add_config.c | 5 ++-- src/utils/config/add_config.h | 1 + 10 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/defines/agent_values.h b/src/defines/agent_values.h index d2f0c877..7245a15c 100644 --- a/src/defines/agent_values.h +++ b/src/defines/agent_values.h @@ -50,6 +50,7 @@ #define CONFIG_KEY_STATSCOLLECTSHARE "stats_collect_share" #define CONFIG_KEY_STATSCOLLECTLOCATION "stats_collect_location" #define CONFIG_KEY_LEGACYAUDMODE "legacy_aud_mode" +#define CONFIG_KEY_PLAINADD "skip-check" #define ACCOUNTINFO_KEY_HASPUBCLIENT "pubclient" diff --git a/src/defines/ipc_values.h b/src/defines/ipc_values.h index 352dc636..77100888 100644 --- a/src/defines/ipc_values.h +++ b/src/defines/ipc_values.h @@ -36,6 +36,7 @@ #define IPC_KEY_ONLYAT "only_at" #define IPC_KEY_MYTOKEN_OIDC_ISS "oidc_issuer" #define IPC_KEY_MYTOKEN_MY_ISS "mytoken_issuer" +#define IPC_KEY_PLAINADD "plain_add" // STATUS #define STATUS_SUCCESS "success" @@ -137,11 +138,12 @@ #define REQUEST_ADD_LIFETIME \ "{\"" IPC_KEY_REQUEST "\":\"" REQUEST_VALUE_ADD "\",\"" IPC_KEY_CONFIG \ "\":%s,\"" IPC_KEY_LIFETIME "\":%lu,\"" IPC_KEY_PASSWORDENTRY \ - "\":%s,\"" IPC_KEY_CONFIRM "\":%d,\"" IPC_KEY_ALWAYSALLOWID "\":%d}" + "\":%s,\"" IPC_KEY_CONFIRM "\":%d,\"" IPC_KEY_ALWAYSALLOWID \ + "\":%d,\"" IPC_KEY_PLAINADD "\":%d}" #define REQUEST_ADD \ "{\"" IPC_KEY_REQUEST "\":\"" REQUEST_VALUE_ADD "\",\"" IPC_KEY_CONFIG \ "\":%s,\"" IPC_KEY_PASSWORDENTRY "\":%s,\"" IPC_KEY_CONFIRM \ - "\":%d,\"" IPC_KEY_ALWAYSALLOWID "\":%d}" + "\":%d,\"" IPC_KEY_ALWAYSALLOWID "\":%d,\"" IPC_KEY_PLAINADD "\":%d}" #define REQUEST_REMOVE \ "{\"" IPC_KEY_REQUEST "\":\"" REQUEST_VALUE_REMOVE "\",\"" IPC_KEY_SHORTNAME \ "\":\"%s\"}" diff --git a/src/oidc-add/add_handler.c b/src/oidc-add/add_handler.c index 6b877249..03db1a05 100644 --- a/src/oidc-add/add_handler.c +++ b/src/oidc-add/add_handler.c @@ -80,14 +80,14 @@ void add_handleAdd(char* account, struct arguments* arguments) { char* res = NULL; if (storePW) { - res = ipc_cryptCommunicate(arguments->remote, REQUEST_ADD_LIFETIME, json_p, - arguments->lifetime.lifetime, pw_str, - arguments->confirm, - arguments->always_allow_idtoken); + res = ipc_cryptCommunicate( + arguments->remote, REQUEST_ADD_LIFETIME, json_p, + arguments->lifetime.lifetime, pw_str, arguments->confirm, + arguments->always_allow_idtoken, arguments->plainadd); } else { - res = ipc_cryptCommunicate(arguments->remote, REQUEST_ADD, json_p, pw_str, - arguments->confirm, - arguments->always_allow_idtoken); + res = ipc_cryptCommunicate( + arguments->remote, REQUEST_ADD, json_p, pw_str, arguments->confirm, + arguments->always_allow_idtoken, arguments->plainadd); } secFree(pw_str); secFree(json_p); diff --git a/src/oidc-add/oidc-add_options.c b/src/oidc-add/oidc-add_options.c index 65165326..ab67ebc9 100644 --- a/src/oidc-add/oidc-add_options.c +++ b/src/oidc-add/oidc-add_options.c @@ -1,5 +1,6 @@ #include "oidc-add_options.h" +#include "defines/agent_values.h" #include "defines/settings.h" #include "utils/commonFeatures.h" #include "utils/config/add_config.h" @@ -13,6 +14,7 @@ #define OPT_PW_FILE 7 #define OPT_REMOTE 8 #define OPT_PW_ENV 9 +#define OPT_PLAINADD 10 static struct argp_option options[] = { {0, 0, 0, 0, "General:", 1}, @@ -53,6 +55,10 @@ static struct argp_option options[] = { "Always allow id-token requests without manual approval by the user for " "this account configuration.", 1}, + {CONFIG_KEY_PLAINADD, OPT_PLAINADD, 0, 0, + "Indicates that the agent should load the account configuration without " + "checking it, i.e. no access token is obtained on load.", + 1}, {"remote", OPT_REMOTE, 0, 0, "Use a remote central oidc-agent, instead of a local one.", 1}, {"force", 'f', 0, 0, @@ -107,6 +113,7 @@ static error_t parse_opt(int key, char* arg, struct argp_state* state) { arguments->pw_lifetime.argProvided = 1; break; case OPT_ALWAYS_ALLOW_IDTOKEN: arguments->always_allow_idtoken = 1; break; + case OPT_PLAINADD: arguments->plainadd = 1; break; case 't': if (!isdigit(*arg)) { return ARGP_ERR_UNKNOWN; @@ -169,6 +176,7 @@ void initArguments(struct arguments* arguments) { arguments->always_allow_idtoken = 0; arguments->remote = 0; arguments->force = 0; + arguments->plainadd = getAddConfig()->plain_add; arguments->pw_prompt_mode = getAddConfig()->pw_prompt_mode; set_pw_prompt_mode(arguments->pw_prompt_mode); } diff --git a/src/oidc-add/oidc-add_options.h b/src/oidc-add/oidc-add_options.h index 83f27c0e..9d0906bd 100644 --- a/src/oidc-add/oidc-add_options.h +++ b/src/oidc-add/oidc-add_options.h @@ -13,20 +13,21 @@ struct arguments { char* pw_file; char* pw_env; - unsigned char remove; - unsigned char removeAll; - unsigned char debug; - unsigned char verbose; - unsigned char listConfigured; - unsigned char listLoaded; - unsigned char print; - unsigned char lock; - unsigned char unlock; - unsigned char confirm; - unsigned char always_allow_idtoken; - unsigned char pw_prompt_mode; - unsigned char remote; - unsigned char force; + unsigned char remove : 1; + unsigned char removeAll : 1; + unsigned char debug : 1; + unsigned char verbose : 1; + unsigned char listConfigured : 1; + unsigned char listLoaded : 1; + unsigned char print : 1; + unsigned char lock : 1; + unsigned char unlock : 1; + unsigned char confirm : 1; + unsigned char always_allow_idtoken : 1; + unsigned char pw_prompt_mode : 2; + unsigned char remote : 1; + unsigned char force : 1; + unsigned char plainadd : 1; struct lifetimeArg pw_lifetime; struct lifetimeArg lifetime; diff --git a/src/oidc-agent/oidcd/oidcd.c b/src/oidc-agent/oidcd/oidcd.c index 64073a7c..7545fcaf 100644 --- a/src/oidc-agent/oidcd/oidcd.c +++ b/src/oidc-agent/oidcd/oidcd.c @@ -72,7 +72,8 @@ int oidcd_main(struct ipcPipe pipes, const struct arguments* arguments) { IPC_KEY_NOSCHEME, IPC_KEY_CERTPATH, IPC_KEY_AUDIENCE, IPC_KEY_ALWAYSALLOWID, IPC_KEY_FILENAME, IPC_KEY_DATA, OIDC_KEY_REGISTRATION_CLIENT_URI, OIDC_KEY_REGISTRATION_ACCESS_TOKEN, - IPC_KEY_ONLYAT, AGENT_KEY_CONFIG_ENDPOINT, AGENT_KEY_MYTOKENPROFILE); + IPC_KEY_ONLYAT, AGENT_KEY_CONFIG_ENDPOINT, AGENT_KEY_MYTOKENPROFILE, + IPC_KEY_PLAINADD); if (getJSONValuesFromString(q, pairs, sizeof(pairs) / sizeof(*pairs)) < 0) { ipc_writeToPipe(pipes, RESPONSE_BADREQUEST, oidc_serror()); secFreeKeyValuePairs(pairs, sizeof(pairs) / sizeof(*pairs)); @@ -85,9 +86,9 @@ int oidcd_main(struct ipcPipe pipes, const struct arguments* arguments) { lifetime, password, applicationHint, confirm, issuer, noscheme, cert_path, audience, alwaysallowid, filename, data, registration_client_uri, registration_access_token, only_at, - config_endpoint, - profile); // Gives variables for key_value values; - // e.g. _request=pairs[0].value + config_endpoint, profile, + plainadd); // Gives variables for key_value values; + // e.g. _request=pairs[0].value if (_request == NULL) { ipc_writeToPipe(pipes, RESPONSE_BADREQUEST, "No request type."); secFreeKeyValuePairs(pairs, sizeof(pairs) / sizeof(*pairs)); @@ -121,7 +122,8 @@ int oidcd_main(struct ipcPipe pipes, const struct arguments* arguments) { } else if (strequal(_request, REQUEST_VALUE_DEVICELOOKUP)) { oidcd_handleDeviceLookup(pipes, _device, _only_at); } else if (strequal(_request, REQUEST_VALUE_ADD)) { - oidcd_handleAdd(pipes, _config, _lifetime, _confirm, _alwaysallowid); + oidcd_handleAdd(pipes, _config, _lifetime, _confirm, _alwaysallowid, + _plainadd); } else if (strequal(_request, REQUEST_VALUE_REMOVE)) { oidcd_handleRm(pipes, _shortname); } else if (strequal(_request, REQUEST_VALUE_REMOVEALL)) { diff --git a/src/oidc-agent/oidcd/oidcd_handler.c b/src/oidc-agent/oidcd/oidcd_handler.c index 55ec195d..31fa447e 100644 --- a/src/oidc-agent/oidcd/oidcd_handler.c +++ b/src/oidc-agent/oidcd/oidcd_handler.c @@ -261,24 +261,27 @@ void oidcd_handleGen(struct ipcPipe pipes, const char* account_json, * checks if an account is feasible (issuer config / AT retrievable) and adds it * to the loaded list; does not check if account already loaded. */ -oidc_error_t addAccount(struct ipcPipe pipes, struct oidc_account* account) { +oidc_error_t addAccount(struct ipcPipe pipes, struct oidc_account* account, + unsigned char plain_load) { if (account == NULL) { oidc_setArgNullFuncError(__func__); return oidc_errno; } - if (obtainIssuerConfig(account) != OIDC_SUCCESS) { - return oidc_errno; - } - if (!strValid(account_getTokenEndpoint(account))) { - return oidc_errno; - } - if (getAccessTokenUsingRefreshFlow(account, FORCE_NEW_TOKEN, NULL, NULL, - pipes) == NULL) { - account_setDeath(account, - time(NULL) + 10); // with short timeout so no password - // required for re-authentication - db_addAccountEncrypted(account); - return oidc_errno; + if (!plain_load) { + if (obtainIssuerConfig(account) != OIDC_SUCCESS) { + return oidc_errno; + } + if (!strValid(account_getTokenEndpoint(account))) { + return oidc_errno; + } + if (getAccessTokenUsingRefreshFlow(account, FORCE_NEW_TOKEN, NULL, NULL, + pipes) == NULL) { + account_setDeath(account, + time(NULL) + 10); // with short timeout so no password + // required for re-authentication + db_addAccountEncrypted(account); + return oidc_errno; + } } db_addAccountEncrypted(account); oidcd_handleUpdateIssuer(pipes, account_getIssuerUrl(account), @@ -288,7 +291,7 @@ oidc_error_t addAccount(struct ipcPipe pipes, struct oidc_account* account) { void oidcd_handleAdd(struct ipcPipe pipes, const char* account_json, const char* timeout_str, const char* confirm_str, - const char* alwaysallowid) { + const char* alwaysallowid, const char* plain_load_str) { agent_log(DEBUG, "Handle Add request"); struct oidc_account* account = getAccountFromJSON(account_json); if (account == NULL) { @@ -319,7 +322,7 @@ void oidcd_handleAdd(struct ipcPipe pipes, const char* account_json, secFreeAccount(account); return; } - if (addAccount(pipes, account) != OIDC_SUCCESS) { + if (addAccount(pipes, account, strToBit(plain_load_str)) != OIDC_SUCCESS) { char* help = getHelpWithAccountInfo(account); if (help != NULL) { ipc_writeToPipe(pipes, RESPONSE_ERROR_INFO, oidc_serror(), help); @@ -423,7 +426,7 @@ oidc_error_t oidcd_autoload(struct ipcPipe pipes, const char* short_name, account_setDeath(account, agent_state.defaultTimeout ? time(NULL) + agent_state.defaultTimeout : 0); - return addAccount(pipes, account); + return addAccount(pipes, account, 0); } #define CONFIRMATION_MODE_AT 0 diff --git a/src/oidc-agent/oidcd/oidcd_handler.h b/src/oidc-agent/oidcd/oidcd_handler.h index 4670b618..a8c0fc6d 100644 --- a/src/oidc-agent/oidcd/oidcd_handler.h +++ b/src/oidc-agent/oidcd/oidcd_handler.h @@ -13,7 +13,7 @@ void oidcd_handleReauthenticate(struct ipcPipe pipes, char* short_name, const struct arguments* arguments); void oidcd_handleAdd(struct ipcPipe, const char* account_json, const char* timeout_str, const char* confirm_str, - const char* alwaysallowid); + const char* alwaysallowid, const char* plain_load_str); void oidcd_handleDelete(struct ipcPipe, const char* account_json); void oidcd_handleDeleteClient(struct ipcPipe pipes, const char* client_uri, const char* registration_access_token, diff --git a/src/utils/config/add_config.c b/src/utils/config/add_config.c index 1d9ebf92..3fcbfbcc 100644 --- a/src/utils/config/add_config.c +++ b/src/utils/config/add_config.c @@ -25,18 +25,19 @@ static add_config_t* _getAddConfig(const char* json) { } INIT_KEY_VALUE(CONFIG_KEY_STOREPW, CONFIG_KEY_PWPROMPTMODE, - CONFIG_KEY_DEBUGLOGGING); + CONFIG_KEY_DEBUGLOGGING, CONFIG_KEY_PLAINADD); if (getJSONValuesFromString(json, pairs, sizeof(pairs) / sizeof(*pairs)) < 0) { SEC_FREE_KEY_VALUES(); oidc_perror(); exit(oidc_errno); } - KEY_VALUE_VARS(store_pw, pw_prompt, debug); + KEY_VALUE_VARS(store_pw, pw_prompt, debug, plainadd); add_config_t* c = secAlloc(sizeof(add_config_t)); c->store_pw = strToBit(_store_pw); c->pw_prompt_mode = parse_prompt_mode(_pw_prompt); c->debug = strToBit(_debug); + c->plain_add = strToBit(_plainadd); SEC_FREE_KEY_VALUES(); return c; } diff --git a/src/utils/config/add_config.h b/src/utils/config/add_config.h index 35288cf1..e04bb0b0 100644 --- a/src/utils/config/add_config.h +++ b/src/utils/config/add_config.h @@ -5,6 +5,7 @@ struct add_config { unsigned char store_pw : 1; unsigned char pw_prompt_mode : 2; unsigned char debug : 1; + unsigned char plain_add : 1; }; typedef struct add_config add_config_t;