mirror of
https://gitlab.com/mishakmak/pam-fprint-grosshack.git
synced 2026-04-08 20:03:34 +02:00
pam_fprintd: Ignore any verify signal if we didn't complete VerifyStart
In case fprintd is emitting a verify signal for another request that is still going on while we're about to start a new verification, we'd just accept such signal, so potentially allowing a log-in because another concurrent request succeeded. To avoid this, use async call to VerifyStart and open a verify window (during which we accept the verification related signals) that is kept open just once the VerifyStart call has been completed and before stopping the verification again. As that's the only moment in which we can be sure that we've control of the daemon events for such device. Thanks to Benjamin to find out the race. Fixes: #47
This commit is contained in:
committed by
Benjamin Berg
parent
a30c45629e
commit
47751548b2
@ -164,6 +164,8 @@ typedef struct {
|
||||
char *result;
|
||||
bool timed_out;
|
||||
bool is_swipe;
|
||||
bool verify_started;
|
||||
int verify_ret;
|
||||
pam_handle_t *pamh;
|
||||
|
||||
char *driver;
|
||||
@ -193,6 +195,11 @@ verify_result (sd_bus_message *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data->verify_started) {
|
||||
pam_syslog (data->pamh, LOG_ERR, "Unexpected VerifyResult '%s', %"PRIu64" signal", result, done);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "Verify result: %s (done: %d)", result, done ? 1 : 0);
|
||||
|
||||
@ -225,6 +232,11 @@ verify_finger_selected (sd_bus_message *m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data->verify_started) {
|
||||
pam_syslog (data->pamh, LOG_ERR, "Unexpected VerifyFingerSelected %s signal", finger_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg = finger_str_to_msg(finger_name, data->driver, data->is_swipe);
|
||||
if (debug)
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "verify_finger_selected %s", msg);
|
||||
@ -278,6 +290,35 @@ fail:
|
||||
return sd_bus_error_set_errno(error, r);
|
||||
}
|
||||
|
||||
|
||||
static int verify_started_cb (sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *ret_error) {
|
||||
const sd_bus_error *error = sd_bus_message_get_error (m);
|
||||
verify_data *data = userdata;
|
||||
|
||||
if (error) {
|
||||
if (sd_bus_error_has_name (error, "net.reactivated.Fprint.Error.NoEnrolledPrints")) {
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "No prints enrolled");
|
||||
data->verify_ret = PAM_USER_UNKNOWN;
|
||||
} else {
|
||||
data->verify_ret = PAM_AUTH_ERR;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "VerifyStart failed: %s", error->message);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "VerifyStart completed successfully");
|
||||
|
||||
data->verify_started = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_verify (pam_handle_t *pamh,
|
||||
sd_bus *bus,
|
||||
@ -348,28 +389,28 @@ do_verify (pam_handle_t *pamh,
|
||||
|
||||
while (ret == PAM_AUTH_ERR && data->max_tries > 0) {
|
||||
uint64_t verification_end = now () + (timeout * USEC_PER_SEC);
|
||||
sd_bus_message *m = NULL;
|
||||
sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
data->timed_out = false;
|
||||
data->verify_started = false;
|
||||
data->verify_ret = PAM_INCOMPLETE;
|
||||
|
||||
r = sd_bus_call_method (bus,
|
||||
"net.reactivated.Fprint",
|
||||
dev,
|
||||
"net.reactivated.Fprint.Device",
|
||||
"VerifyStart",
|
||||
&error,
|
||||
&m,
|
||||
"s",
|
||||
"any");
|
||||
if (debug)
|
||||
pam_syslog (data->pamh, LOG_DEBUG, "About to call VerifyStart");
|
||||
|
||||
r = sd_bus_call_method_async (bus,
|
||||
NULL,
|
||||
"net.reactivated.Fprint",
|
||||
dev,
|
||||
"net.reactivated.Fprint.Device",
|
||||
"VerifyStart",
|
||||
verify_started_cb,
|
||||
data,
|
||||
"s",
|
||||
"any");
|
||||
|
||||
if (r < 0) {
|
||||
if (sd_bus_error_has_name (&error, "net.reactivated.Fprint.Error.NoEnrolledPrints"))
|
||||
ret = PAM_USER_UNKNOWN;
|
||||
|
||||
if (debug)
|
||||
pam_syslog (pamh, LOG_DEBUG, "VerifyStart failed: %s", error.message);
|
||||
sd_bus_error_free (&error);
|
||||
pam_syslog (pamh, LOG_DEBUG, "VerifyStart call failed: %d", r);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -383,6 +424,10 @@ do_verify (pam_handle_t *pamh,
|
||||
r = sd_bus_process (bus, NULL);
|
||||
if (r < 0)
|
||||
break;
|
||||
if (data->verify_ret != PAM_INCOMPLETE)
|
||||
break;
|
||||
if (!data->verify_started)
|
||||
continue;
|
||||
if (data->result != NULL)
|
||||
break;
|
||||
if (r == 0) {
|
||||
@ -397,12 +442,18 @@ do_verify (pam_handle_t *pamh,
|
||||
}
|
||||
}
|
||||
|
||||
if (data->verify_ret != PAM_INCOMPLETE) {
|
||||
ret = data->verify_ret;
|
||||
break;
|
||||
}
|
||||
|
||||
if (now () >= verification_end) {
|
||||
data->timed_out = true;
|
||||
send_info_msg (data->pamh, _("Verification timed out"));
|
||||
}
|
||||
|
||||
/* Ignore errors from VerifyStop */
|
||||
data->verify_started = false;
|
||||
sd_bus_call_method (bus,
|
||||
"net.reactivated.Fprint",
|
||||
dev,
|
||||
|
||||
Reference in New Issue
Block a user