static void input_done(void) { STOP_TIMER(clear_pam_wrong_timeout); pam_state = STATE_PAM_VERIFY; redraw_screen(); if (pam_authenticate(pam_handle, 0) == PAM_SUCCESS) { DEBUG("successfully authenticated\n"); clear_password_memory(); /* PAM credentials should be refreshed, this will for example update any kerberos tickets. * Related to credentials pam_end() needs to be called to cleanup any temporary * credentials like kerberos /tmp/krb5cc_pam_* files which may of been left behind if the * refresh of the credentials failed. */ pam_setcred(pam_handle, PAM_REFRESH_CRED); pam_end(pam_handle, PAM_SUCCESS); exit(0); } if (debug_mode) fprintf(stderr, "Authentication failure\n"); /* Get state of Caps and Num lock modifiers, to be displayed in * STATE_PAM_WRONG state */ xkb_mod_index_t idx, num_mods; const char *mod_name; num_mods = xkb_keymap_num_mods(xkb_keymap); for (idx = 0; idx < num_mods; idx++) { if (!xkb_state_mod_index_is_active(xkb_state, idx, XKB_STATE_MODS_EFFECTIVE)) continue; mod_name = xkb_keymap_mod_get_name(xkb_keymap, idx); if (mod_name == NULL) continue; /* Replace certain xkb names with nicer, human-readable ones. */ if (strcmp(mod_name, XKB_MOD_NAME_CAPS) == 0) mod_name = "Caps Lock"; else if (strcmp(mod_name, XKB_MOD_NAME_ALT) == 0) mod_name = "Alt"; else if (strcmp(mod_name, XKB_MOD_NAME_NUM) == 0) mod_name = "Num Lock"; else if (strcmp(mod_name, XKB_MOD_NAME_LOGO) == 0) mod_name = "Win"; char *tmp; if (modifier_string == NULL) { if (asprintf(&tmp, "%s", mod_name) != -1) modifier_string = tmp; } else if (asprintf(&tmp, "%s, %s", modifier_string, mod_name) != -1) { free(modifier_string); modifier_string = tmp; } } pam_state = STATE_PAM_WRONG; failed_attempts += 1; clear_input(); if (unlock_indicator) redraw_screen(); /* Skip all the events during the pam verification to avoid bad people * spamming keys and locking pam in an endless validation loop */ xcb_generic_event_t *ev = xcb_poll_for_event(conn); free(ev); while (ev != NULL) { ev = xcb_poll_for_queued_event(conn); free(ev); } /* Clear this state after 2 seconds (unless the user enters another * password during that time). */ ev_now_update(main_loop); START_TIMER(clear_pam_wrong_timeout, TSTAMP_N_SECS(2), clear_pam_wrong); /* Cancel the clear_indicator_timeout, it would hide the unlock indicator * too early. */ STOP_TIMER(clear_indicator_timeout); /* beep on authentication failure, if enabled */ if (beep) { xcb_bell(conn, 100); xcb_flush(conn); } }
virtual shared_generic_event_ptr poll_for_queued_event(void) const { return shared_generic_event_ptr(xcb_poll_for_queued_event(m_c.get())); }