Skip to content

Commit 30c80a9

Browse files
committed
krb5: check for PIN locked in error message
Currently the PIN locked message is only displays if the Smartcard authentication is done locally, e.g. if the system is offline. During pkinit libkrb5 does not send a dedicated error code but the error message generated by the library contains a hint. This patch checks the libkrb5 error message in case the authentication fails with the pre-authentication failed error code. This is a bit tricky because 'krb5_get_error_message()' currently only returns a defined result at the first call after a failed library call.
1 parent 280eece commit 30c80a9

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

src/providers/krb5/krb5_child.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,31 @@ static krb5_context krb5_error_ctx;
137137

138138
#define KRB5_CHILD_DEBUG(level, error) KRB5_CHILD_DEBUG_INT(level, krb5_error_ctx, error)
139139

140+
static bool debug_and_check_if_pin_locked_error(krb5_context ctx, int level,
141+
krb5_error_code krb5_error)
142+
{
143+
const char *krb5_error_msg;
144+
bool res = false;
145+
146+
krb5_error_msg = sss_krb5_get_error_message(ctx, krb5_error);
147+
if (krb5_error_msg == NULL) {
148+
return false;
149+
}
150+
151+
if (strstr(krb5_error_msg, "pin locked") != NULL) {
152+
res = true;
153+
}
154+
155+
DEBUG(level, "%d: [%d][%s]\n", __LINE__, krb5_error, krb5_error_msg);
156+
if (level & (SSSDBG_CRIT_FAILURE | SSSDBG_FATAL_FAILURE)) {
157+
sss_log(SSS_LOG_ERR, "%s", krb5_error_msg);
158+
}
159+
160+
sss_krb5_free_error_message(ctx, krb5_error_msg);
161+
162+
return res;
163+
}
164+
140165
static krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname,
141166
krb5_principal server_principal,
142167
krb5_principal client_principal,
@@ -2404,6 +2429,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24042429
char *cc_name;
24052430
int ret;
24062431
char *identity = NULL;
2432+
const uint32_t user_info_pin_locked = SSS_PAM_USER_INFO_PIN_LOCKED;
24072433

24082434
kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options,
24092435
sss_krb5_expire_callback_func,
@@ -2469,7 +2495,26 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24692495
return 0;
24702496
} else {
24712497
if (kerr != 0) {
2472-
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2498+
/* Check of a locked Smartcard PIN, must be called before/instead
2499+
* of KRB5_CHILD_DEBUG because krb5_get_error_message() might only
2500+
* return the proper error message at the first call. */
2501+
if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
2502+
&& kerr == KRB5_PREAUTH_FAILED
2503+
&& kr->pkinit_prompting == true
2504+
&& IS_SC_AUTHTOK(kr->pd->authtok) ) {
2505+
if (debug_and_check_if_pin_locked_error(kr->ctx,
2506+
SSSDBG_CRIT_FAILURE, kerr) ) {
2507+
ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO,
2508+
sizeof(uint32_t),
2509+
(const uint8_t *) &user_info_pin_locked);
2510+
if (ret != EOK) {
2511+
DEBUG(SSSDBG_OP_FAILURE,
2512+
"Failed to add PIN locked message.\n");
2513+
}
2514+
}
2515+
} else {
2516+
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2517+
}
24732518

24742519
if (kerr == EAGAIN) {
24752520
/* The most probable reason for krb5_get_init_creds_password()

0 commit comments

Comments
 (0)