Commit 47751548 authored by Marco Trevisan's avatar Marco Trevisan Committed by Benjamin Berg
Browse files

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
parent a30c4562
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment