diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index a33e0561ef..ff6329b3fd 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -304,6 +304,9 @@
#define CONFDB_PC_PASSKEY_INTERACTIVE_PROMPT "interactive_prompt"
#define CONFDB_PC_PASSKEY_TOUCH "touch"
#define CONFDB_PC_PASSKEY_TOUCH_PROMPT "touch_prompt"
+#define CONFDB_PC_TYPE_OAUTH2 "oauth2"
+#define CONFDB_PC_OAUTH2_INTERACTIVE "interactive"
+#define CONFDB_PC_OAUTH2_INTERACTIVE_PROMPT "interactive_prompt"
struct confdb_ctx;
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index fb9fc2a459..c355737386 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -16,6 +16,8 @@ section_re = ^prompting/2fa$
section_re = ^prompting/2fa/[^/\@]\{1,\}$
section_re = ^prompting/passkey$
section_re = ^prompting/passkey/[^/\@]\{1,\}$
+section_re = ^prompting/oauth2$
+section_re = ^prompting/oauth2/[^/\@]\{1,\}$
section_re = ^domain/[^/\@]\{1,\}$
section_re = ^domain/[^/\@]\{1,\}/[^/\@]\{1,\}$
section_re = ^application/[^/\@]\{1,\}$
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index b69d6bfc6e..0fe38b0477 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -4496,6 +4496,41 @@ ldap_user_extra_attrs = phone:telephoneNumber
+
+
+ [prompting/oauth2]
+
+ to configure OAuth2 authentication prompting,
+ allowed options are:
+
+
+ interactive
+
+ boolean value, if True prompt a message after
+ asking the user to authenticate, and wait
+ before requesting the access token.
+
+ If False, make sure to set the
+ idp_request_timeout
+ sufficiently high, to give the user time to
+ authenticate.
+
+ Default: true
+
+
+
+
+ interactive_prompt
+
+ to change the message of the interactive prompt.
+
+
+
+
+
+
+
+
It is possible to add a subsection for specific PAM services,
diff --git a/src/responder/pam/pam_prompting_config.c b/src/responder/pam/pam_prompting_config.c
index 27f794b929..19d7cec398 100644
--- a/src/responder/pam/pam_prompting_config.c
+++ b/src/responder/pam/pam_prompting_config.c
@@ -27,6 +27,7 @@
#define DEFAULT_PASSKEY_PROMPT_INTERACTIVE _("Insert your Passkey device, then press ENTER.")
#define DEFAULT_PASSKEY_PROMPT_TOUCH _("Please touch the device.")
+#define DEFAULT_OAUTH2_PROMPT_INTERACTIVE _("Press ENTER to continue.")
typedef errno_t (pam_set_prompting_fn_t)(TALLOC_CTX *, struct confdb_ctx *,
const char *,
@@ -147,6 +148,39 @@ static errno_t pam_set_passkey_prompting_options(TALLOC_CTX *tmp_ctx,
return ret;
}
+
+static errno_t pam_set_oauth2_prompting_options(TALLOC_CTX *tmp_ctx,
+ struct confdb_ctx *cdb,
+ const char *section,
+ struct prompt_config ***pc_list)
+{
+ bool oauth2_interactive = false;
+ char *oauth2_interactive_prompt = NULL;
+ int ret;
+
+
+ ret = confdb_get_bool(cdb, section, CONFDB_PC_OAUTH2_INTERACTIVE, true,
+ &oauth2_interactive);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "confdb_get_bool failed, using defaults");
+ }
+
+ if (oauth2_interactive) {
+ ret = confdb_get_string(cdb, tmp_ctx, section, CONFDB_PC_OAUTH2_INTERACTIVE_PROMPT,
+ DEFAULT_OAUTH2_PROMPT_INTERACTIVE, &oauth2_interactive_prompt);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "confdb_get_string failed, using defaults");
+ }
+ }
+
+ ret = pc_list_add_oauth2(pc_list, oauth2_interactive_prompt);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "pc_list_add_oauth2 failed.\n");
+ }
+
+ return ret;
+}
+
static errno_t pam_set_prompting_options(struct confdb_ctx *cdb,
const char *service_name,
char **sections,
@@ -232,6 +266,19 @@ errno_t pam_eval_prompting_config(struct pam_ctx *pctx, struct pam_data *pd,
goto done;
}
+ if (types.oauth2_auth) {
+ ret = pam_set_prompting_options(pctx->rctx->cdb, pd->service,
+ pctx->prompting_config_sections,
+ pctx->num_prompting_config_sections,
+ CONFDB_PC_TYPE_OAUTH2,
+ pam_set_oauth2_prompting_options,
+ &pc_list);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "pam_set_prompting_options failed.\n");
+ goto done;
+ }
+ }
+
if (types.passkey_auth) {
ret = pam_set_prompting_options(pctx->rctx->cdb, pd->service,
pctx->prompting_config_sections,
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index cee29125bd..d843715c49 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -119,6 +119,7 @@ struct pam_resp_auth_type {
bool cert_auth;
bool passkey_auth;
bool backend_returned_no_auth_type;
+ bool oauth2_auth;
};
struct sss_cmd_table *get_pam_cmds(void);
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index fd55ac0150..fe5dbec0fe 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -914,6 +914,9 @@ static void evaluate_pam_resp_list(struct pam_data *pd,
case SSS_PAM_PASSKEY_KRB_INFO:
types.passkey_auth = true;
break;
+ case SSS_PAM_OAUTH2_INFO:
+ types.oauth2_auth = true;
+ break;
case SSS_PASSWORD_PROMPTING:
types.password_auth = true;
break;
@@ -954,7 +957,8 @@ errno_t pam_get_auth_types(struct pam_data *pd,
evaluate_pam_resp_list(pd, &types, NULL);
- if (!types.password_auth && !types.otp_auth && !types.cert_auth && !types.passkey_auth) {
+ if (!types.password_auth && !types.otp_auth && !types.cert_auth &&
+ !types.oauth2_auth && !types.passkey_auth) {
/* If the backend cannot determine which authentication types are
* available the default would be to prompt for a password. */
types.password_auth = true;
@@ -962,10 +966,11 @@ errno_t pam_get_auth_types(struct pam_data *pd,
}
DEBUG(SSSDBG_TRACE_ALL, "Authentication types for user [%s] and service "
- "[%s]:%s%s%s%s\n", pd->user, pd->service,
+ "[%s]:%s%s%s%s%s\n", pd->user, pd->service,
types.password_auth ? " password": "",
types.otp_auth ? " two-factor" : "",
types.passkey_auth ? " passkey" : "",
+ types.oauth2_auth ? " oauth2" : "",
types.cert_auth ? " smartcard" : "");
ret = EOK;
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 21d2e7f284..af0c2b55a1 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -1849,37 +1849,47 @@ static int prompt_2fa_single(pam_handle_t *pamh, struct pam_items *pi,
return PAM_SUCCESS;
}
-static int prompt_oauth2(pam_handle_t *pamh, struct pam_items *pi)
+static int prompt_oauth2(pam_handle_t *pamh, struct pam_items *pi,
+ const char *prompt)
{
- char *answer = NULL;
char *msg;
int ret;
if (pi->oauth2_url_complete != NULL) {
- ret = asprintf(&msg, _("Authenticate at %1$s and press ENTER."),
+ ret = asprintf(&msg, _("Authenticate at \"%1$s\"."),
pi->oauth2_url_complete);
} else {
- ret = asprintf(&msg, _("Authenticate with PIN %1$s at %2$s and press "
- "ENTER."), pi->oauth2_pin, pi->oauth2_url);
+ ret = asprintf(&msg, _("Authenticate with PIN \"%1$s\" at \"%2$s\"."),
+ pi->oauth2_pin, pi->oauth2_url);
}
if (ret == -1) {
return PAM_SYSTEM_ERR;
}
- ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, msg, NULL, &answer);
+ ret = do_pam_conversation(pamh, PAM_TEXT_INFO, msg, NULL, NULL);
free(msg);
if (ret != PAM_SUCCESS) {
D(("do_pam_conversation failed."));
return ret;
}
- /* We don't care about answer here. We just need to notify that the
- * authentication has finished. */
- free(answer);
+ if (prompt != NULL && prompt[0] != '\0') {
+ char *answer = NULL;
+
+ ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, NULL, &answer);
+ if (ret != PAM_SUCCESS) {
+ D(("do_pam_conversation failed."));
+ return ret;
+ }
+
+ /* We don't care about answer here. We just need to notify that the
+ * authentication has finished. */
+ free(answer);
+ }
pi->pam_authtok = strdup(pi->oauth2_pin);
pi->pam_authtok_type = SSS_AUTHTOK_TYPE_OAUTH2;
- pi->pam_authtok_size=strlen(pi->oauth2_pin);
+ pi->pam_authtok_size = strlen(pi->oauth2_pin);
return PAM_SUCCESS;
}
@@ -2608,6 +2618,10 @@ static int prompt_by_config(pam_handle_t *pamh, struct pam_items *pi)
pc_get_passkey_inter_prompt(pi->pc[c]),
pc_get_passkey_touch_prompt(pi->pc[c]));
break;
+ case PC_TYPE_OAUTH2:
+ ret = prompt_oauth2(pamh, pi,
+ pc_get_oauth2_inter_prompt(pi->pc[c]));
+ break;
case PC_TYPE_SMARTCARD:
ret = prompt_sc_pin(pamh, pi);
/* Todo: add extra string option */
@@ -2647,13 +2661,13 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
}
pi->pam_authtok_size = strlen(pi->pam_authtok);
} else {
- if (pi->oauth2_url != NULL) {
- /* Prompt config is not supported for OAuth2. */
- ret = prompt_oauth2(pamh, pi);
- } else if (pi->pc != NULL) {
+ if (pi->pc != NULL) {
ret = prompt_by_config(pamh, pi);
} else {
- if (pi->cert_list != NULL) {
+ if (pi->oauth2_url != NULL) {
+ /* Prompt config is not supported for OAuth2. */
+ ret = prompt_oauth2(pamh, pi, _("Press ENTER to continue."));
+ } else if (pi->cert_list != NULL) {
if (pi->cert_list->next == NULL) {
/* Only one certificate */
pi->selected_cert = pi->cert_list;
diff --git a/src/sss_client/pam_sss_prompt_config.c b/src/sss_client/pam_sss_prompt_config.c
index caf308c826..9e72c22fb6 100644
--- a/src/sss_client/pam_sss_prompt_config.c
+++ b/src/sss_client/pam_sss_prompt_config.c
@@ -55,6 +55,10 @@ struct prompt_config_eidp {
char *prompt_link;
};
+struct prompt_config_oauth2 {
+ char *prompt_inter;
+};
+
struct prompt_config {
enum prompt_config_type type;
union {
@@ -64,6 +68,7 @@ struct prompt_config {
struct prompt_config_passkey passkey;
struct prompt_config_smartcard smartcard;
struct prompt_config_eidp eidp;
+ struct prompt_config_oauth2 oauth2;
} data;
};
@@ -155,6 +160,14 @@ const char *pc_get_smartcard_pin_prompt(struct prompt_config *pc)
return NULL;
}
+const char *pc_get_oauth2_inter_prompt(struct prompt_config *pc)
+{
+ if (pc != NULL && (pc_get_type(pc) == PC_TYPE_OAUTH2)) {
+ return pc->data.oauth2.prompt_inter;
+ }
+ return NULL;
+}
+
static void pc_free_passkey(struct prompt_config *pc)
{
if (pc != NULL && pc_get_type(pc) == PC_TYPE_PASSKEY) {
@@ -166,6 +179,15 @@ static void pc_free_passkey(struct prompt_config *pc)
return;
}
+static void pc_free_oauth2(struct prompt_config *pc)
+{
+ if (pc != NULL && pc_get_type(pc) == PC_TYPE_OAUTH2) {
+ free(pc->data.oauth2.prompt_inter);
+ pc->data.oauth2.prompt_inter = NULL;
+ }
+ return;
+}
+
static void pc_free_password(struct prompt_config *pc)
{
if (pc != NULL && pc_get_type(pc) == PC_TYPE_PASSWORD) {
@@ -246,6 +268,9 @@ void pc_list_free(struct prompt_config **pc_list)
case PC_TYPE_EIDP:
pc_free_eidp(pc_list[c]);
break;
+ case PC_TYPE_OAUTH2:
+ pc_free_oauth2(pc_list[c]);
+ break;
default:
return;
}
@@ -275,6 +300,31 @@ static errno_t pc_list_add_pc(struct prompt_config ***pc_list,
return EOK;
}
+static errno_t pc_copy_string(int size, uint8_t *buf, size_t *off, char **out) {
+ char *str;
+ uint32_t l;
+ size_t rp = *off;
+
+ if (rp > size - sizeof(uint32_t)) {
+ return EINVAL;
+ }
+ SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
+
+ if (l > size || rp > size - l) {
+ return EINVAL;
+ }
+ str = strndup((char *) buf + rp, l);
+ if (str == NULL) {
+ return ENOMEM;
+ }
+ rp += l;
+
+ *out = str;
+ *off = rp;
+
+ return EOK;
+}
+
#define DEFAULT_PASSWORD_PROMPT _("Password: ")
#define DEFAULT_2FA_SINGLE_PROMPT _("Password + Token value: ")
#define DEFAULT_2FA_PROMPT_1ST _("First Factor: ")
@@ -545,6 +595,46 @@ errno_t pc_list_add_smartcard(struct prompt_config ***pc_list,
return ret;
}
+errno_t pc_list_add_oauth2(struct prompt_config ***pc_list,
+ const char *prompt_inter)
+{
+ struct prompt_config *pc;
+ int ret;
+
+ if (pc_list == NULL) {
+ return EINVAL;
+ }
+
+ pc = calloc(1, sizeof(struct prompt_config));
+ if (pc == NULL) {
+ return ENOMEM;
+ }
+
+ pc->type = PC_TYPE_OAUTH2;
+
+ pc->data.oauth2.prompt_inter = strdup(prompt_inter != NULL ? prompt_inter
+ : "");
+ if (pc->data.oauth2.prompt_inter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = pc_list_add_pc(pc_list, pc);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ free(pc->data.oauth2.prompt_inter);
+ free(pc);
+ }
+
+ return ret;
+}
+
errno_t pam_get_response_prompt_config(struct prompt_config **pc_list, int *len,
uint8_t **data)
{
@@ -594,6 +684,10 @@ errno_t pam_get_response_prompt_config(struct prompt_config **pc_list, int *len,
l += sizeof(uint32_t);
l += strlen(pc_list[c]->data.eidp.prompt_link);
break;
+ case PC_TYPE_OAUTH2:
+ l += sizeof(uint32_t);
+ l += strlen(pc_list[c]->data.oauth2.prompt_inter);
+ break;
default:
return EINVAL;
}
@@ -675,6 +769,13 @@ errno_t pam_get_response_prompt_config(struct prompt_config **pc_list, int *len,
safealign_memcpy(&d[rp], pc_list[c]->data.eidp.prompt_link,
strlen(pc_list[c]->data.eidp.prompt_link), &rp);
break;
+ case PC_TYPE_OAUTH2:
+ SAFEALIGN_SET_UINT32(&d[rp],
+ strlen(pc_list[c]->data.oauth2.prompt_inter),
+ &rp);
+ safealign_memcpy(&d[rp], pc_list[c]->data.oauth2.prompt_inter,
+ strlen(pc_list[c]->data.oauth2.prompt_inter), &rp);
+ break;
default:
free(d);
return EINVAL;
@@ -723,22 +824,10 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
switch (type) {
case PC_TYPE_PASSWORD:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- ret = EINVAL;
- goto done;
- }
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- rp += l;
ret = pc_list_add_password(&pl, str);
free(str);
@@ -747,42 +836,16 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
}
break;
case PC_TYPE_2FA:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- ret = EINVAL;
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
- goto done;
- }
- rp += l;
- if (rp > size - sizeof(uint32_t)) {
+ ret = pc_copy_string(size, buf, &rp, &str2);
+ if (ret != 0) {
free(str);
- ret = EINVAL;
goto done;
}
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- str2 = strndup((char *) buf + rp, l);
- if (str2 == NULL) {
- free(str);
- ret = ENOMEM;
- goto done;
- }
- rp += l;
ret = pc_list_add_2fa(&pl, str, str2);
free(str);
@@ -792,42 +855,16 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
}
break;
case PC_TYPE_PASSKEY:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
- if (l > size || rp > size - l) {
- ret = EINVAL;
- goto done;
- }
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
- goto done;
- }
- rp += l;
-
- if (rp > size - sizeof(uint32_t)) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- str2 = strndup((char *) buf + rp, l);
- if (str2 == NULL) {
+ ret = pc_copy_string(size, buf, &rp, &str2);
+ if (ret != 0) {
free(str);
- ret = ENOMEM;
goto done;
}
- rp += l;
ret = pc_list_add_passkey(&pl, str, str2);
free(str);
@@ -836,23 +873,23 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
goto done;
}
break;
- case PC_TYPE_2FA_SINGLE:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
+ case PC_TYPE_OAUTH2:
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
- if (l > size || rp > size - l) {
- ret = EINVAL;
+ ret = pc_list_add_oauth2(&pl, str);
+ free(str);
+ if (ret != EOK) {
goto done;
}
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
+ break;
+ case PC_TYPE_2FA_SINGLE:
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- rp += l;
ret = pc_list_add_2fa_single(&pl, str);
free(str);
@@ -861,42 +898,16 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
}
break;
case PC_TYPE_SMARTCARD:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- ret = EINVAL;
- goto done;
- }
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- rp += l;
- if (rp > size - sizeof(uint32_t)) {
+ ret = pc_copy_string(size, buf, &rp, &str2);
+ if (ret != 0) {
free(str);
- ret = EINVAL;
goto done;
}
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- str2 = strndup((char *) buf + rp, l);
- if (str2 == NULL) {
- free(str);
- ret = ENOMEM;
- goto done;
- }
- rp += l;
ret = pc_list_add_smartcard(&pl, str, str2);
free(str);
@@ -906,42 +917,16 @@ errno_t pc_list_from_response(int size, uint8_t *buf,
}
break;
case PC_TYPE_EIDP:
- if (rp > size - sizeof(uint32_t)) {
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- ret = EINVAL;
- goto done;
- }
- str = strndup((char *) buf + rp, l);
- if (str == NULL) {
- ret = ENOMEM;
+ ret = pc_copy_string(size, buf, &rp, &str);
+ if (ret != 0) {
goto done;
}
- rp += l;
- if (rp > size - sizeof(uint32_t)) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- SAFEALIGN_COPY_UINT32(&l, buf + rp, &rp);
-
- if (l > size || rp > size - l) {
- free(str);
- ret = EINVAL;
- goto done;
- }
- str2 = strndup((char *) buf + rp, l);
- if (str2 == NULL) {
+ ret = pc_copy_string(size, buf, &rp, &str2);
+ if (ret != 0) {
free(str);
- ret = ENOMEM;
goto done;
}
- rp += l;
ret = pc_list_add_eidp(&pl, str, str2);
free(str);
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index 727d5ba8e3..57e1ead454 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -682,6 +682,7 @@ enum prompt_config_type {
PC_TYPE_PASSKEY,
PC_TYPE_SMARTCARD,
PC_TYPE_EIDP,
+ PC_TYPE_OAUTH2,
PC_TYPE_LAST
};
@@ -698,9 +699,12 @@ const char *pc_get_eidp_init_prompt(struct prompt_config *pc);
const char *pc_get_eidp_link_prompt(struct prompt_config *pc);
const char *pc_get_smartcard_init_prompt(struct prompt_config *pc);
const char *pc_get_smartcard_pin_prompt(struct prompt_config *pc);
+const char *pc_get_oauth2_inter_prompt(struct prompt_config *pc);
errno_t pc_list_add_passkey(struct prompt_config ***pc_list,
const char *inter_prompt,
const char *touch_prompt);
+errno_t pc_list_add_oauth2(struct prompt_config ***pc_list,
+ const char *inter_prompt);
void pc_list_free(struct prompt_config **pc_list);
errno_t pc_list_add_password(struct prompt_config ***pc_list,
const char *prompt);