Skip to content

Commit bc91676

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 bc91676

File tree

1 file changed

+60
-5
lines changed

1 file changed

+60
-5
lines changed

src/providers/krb5/krb5_child.c

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,47 @@ struct krb5_req {
125125

126126
static krb5_context krb5_error_ctx;
127127

128+
static inline void debug_and_log(int level, int line,
129+
krb5_error_code krb5_error,
130+
const char *krb5_error_msg)
131+
{
132+
DEBUG(level, "%d: [%d][%s]\n", line, krb5_error, krb5_error_msg);
133+
if (level & (SSSDBG_CRIT_FAILURE | SSSDBG_FATAL_FAILURE)) {
134+
sss_log(SSS_LOG_ERR, "%s", krb5_error_msg);
135+
}
136+
137+
return;
138+
}
139+
128140
#define KRB5_CHILD_DEBUG_INT(level, errctx, krb5_error) do { \
129141
const char *__krb5_error_msg; \
130142
__krb5_error_msg = sss_krb5_get_error_message(errctx, krb5_error); \
131-
DEBUG(level, "%d: [%d][%s]\n", __LINE__, krb5_error, __krb5_error_msg); \
132-
if (level & (SSSDBG_CRIT_FAILURE | SSSDBG_FATAL_FAILURE)) { \
133-
sss_log(SSS_LOG_ERR, "%s", __krb5_error_msg); \
134-
} \
143+
debug_and_log(level, __LINE__, krb5_error, __krb5_error_msg); \
135144
sss_krb5_free_error_message(errctx, __krb5_error_msg); \
136145
} while(0)
137146

138147
#define KRB5_CHILD_DEBUG(level, error) KRB5_CHILD_DEBUG_INT(level, krb5_error_ctx, error)
139148

149+
static bool debug_and_check_if_pin_locked_error(krb5_context ctx, int level,
150+
krb5_error_code krb5_error)
151+
{
152+
const char *krb5_error_msg;
153+
bool res = false;
154+
155+
/* sss_krb5_free_error_message() never returns NULL */
156+
krb5_error_msg = sss_krb5_get_error_message(ctx, krb5_error);
157+
158+
if (strstr(krb5_error_msg, "pin locked") != NULL) {
159+
res = true;
160+
}
161+
162+
debug_and_log(level, __LINE__, krb5_error, krb5_error_msg);
163+
164+
sss_krb5_free_error_message(ctx, krb5_error_msg);
165+
166+
return res;
167+
}
168+
140169
static krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname,
141170
krb5_principal server_principal,
142171
krb5_principal client_principal,
@@ -2404,6 +2433,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24042433
char *cc_name;
24052434
int ret;
24062435
char *identity = NULL;
2436+
const uint32_t user_info_pin_locked = SSS_PAM_USER_INFO_PIN_LOCKED;
24072437

24082438
kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options,
24092439
sss_krb5_expire_callback_func,
@@ -2469,7 +2499,32 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
24692499
return 0;
24702500
} else {
24712501
if (kerr != 0) {
2472-
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2502+
/* If
2503+
* - during authentication
2504+
* - the pre-authentication failed
2505+
* - while Smartcard authentication was possible
2506+
* - and Smartcard credentials were available
2507+
* check if the PIN might be locked.
2508+
* Must be called before/instead of KRB5_CHILD_DEBUG because
2509+
* krb5_get_error_message() might only return the proper error
2510+
* message at the first call. */
2511+
if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
2512+
&& kerr == KRB5_PREAUTH_FAILED
2513+
&& kr->pkinit_prompting == true
2514+
&& IS_SC_AUTHTOK(kr->pd->authtok) ) {
2515+
if (debug_and_check_if_pin_locked_error(kr->ctx,
2516+
SSSDBG_CRIT_FAILURE, kerr) ) {
2517+
ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO,
2518+
sizeof(uint32_t),
2519+
(const uint8_t *) &user_info_pin_locked);
2520+
if (ret != EOK) {
2521+
DEBUG(SSSDBG_OP_FAILURE,
2522+
"Failed to add PIN locked message.\n");
2523+
}
2524+
}
2525+
} else {
2526+
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
2527+
}
24732528

24742529
if (kerr == EAGAIN) {
24752530
/* The most probable reason for krb5_get_init_creds_password()

0 commit comments

Comments
 (0)