From b116af629be03f4e44bca0adfe5f76eee278fbbc Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Sun, 24 Jan 2016 13:33:24 +0200 Subject: [PATCH 1/4] swaylock: remove global variable pam_reply --- swaylock/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/swaylock/main.c b/swaylock/main.c index c01445e7..e04d0d62 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -36,11 +36,15 @@ void sway_terminate(void) { } char *password; -struct pam_response *pam_reply; int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + + struct pam_response *pam_reply = malloc(sizeof(struct pam_response)); + pam_reply[0].resp = password; + pam_reply[0].resp_retcode = 0; *resp = pam_reply; + return PAM_SUCCESS; } @@ -57,9 +61,6 @@ bool verify_password(char *password) { if ((pam_err = pam_start("swaylock", username, &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { sway_abort("PAM returned %d\n", pam_err); } - pam_reply = (struct pam_response *)malloc(sizeof(struct pam_response)); - pam_reply[0].resp = password; - pam_reply[0].resp_retcode = 0; if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) { memset(password, 0, strlen(password)); return false; From 52fea936930d500edf7a1e257421049111d352f1 Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Sun, 24 Jan 2016 13:33:32 +0200 Subject: [PATCH 2/4] swaylock: add pam conversation debug output --- swaylock/main.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/swaylock/main.c b/swaylock/main.c index e04d0d62..ca3453ff 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -40,6 +40,20 @@ char *password; int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + const char* msg_style_names[] = { + NULL, + "PAM_PROMPT_ECHO_OFF", + "PAM_PROMPT_ECHO_ON", + "PAM_ERROR_MSG", + "PAM_TEXT_INFO", + }; + + for(int i=0; imsg_style], + msg[i]->msg); + } + struct pam_response *pam_reply = malloc(sizeof(struct pam_response)); pam_reply[0].resp = password; pam_reply[0].resp_retcode = 0; From dab651a240ad59722c3c23fcea6e2f91909b2a1b Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Sun, 24 Jan 2016 14:35:28 +0200 Subject: [PATCH 3/4] swaylock: fix pam conversation --- swaylock/main.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/swaylock/main.c b/swaylock/main.c index ca3453ff..e6095d35 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -48,16 +48,26 @@ int function_conversation(int num_msg, const struct pam_message **msg, "PAM_TEXT_INFO", }; + /* PAM expects an array of responses, one for each message */ + struct pam_response *pam_reply = calloc(num_msg, sizeof(struct pam_response)); + *resp = pam_reply; + for(int i=0; imsg_style], msg[i]->msg); - } - struct pam_response *pam_reply = malloc(sizeof(struct pam_response)); - pam_reply[0].resp = password; - pam_reply[0].resp_retcode = 0; - *resp = pam_reply; + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + case PAM_PROMPT_ECHO_ON: + pam_reply[i].resp = password; + break; + + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + break; + } + } return PAM_SUCCESS; } From 071e09721449e1bfc9331077368c53391dd9b932 Mon Sep 17 00:00:00 2001 From: Christoph Gysin Date: Sat, 23 Jan 2016 22:43:51 +0200 Subject: [PATCH 4/4] swaylock: don't memset memory that has been freed swaylock is randomly crashing because we write to password that has already been freed in pam_authenticate(). --- swaylock/main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/swaylock/main.c b/swaylock/main.c index e6095d35..9530b6dc 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -75,7 +75,7 @@ int function_conversation(int num_msg, const struct pam_message **msg, /** * password will be zeroed out. */ -bool verify_password(char *password) { +bool verify_password() { struct passwd *passwd = getpwuid(getuid()); char *username = passwd->pw_name; @@ -86,14 +86,11 @@ bool verify_password(char *password) { sway_abort("PAM returned %d\n", pam_err); } if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) { - memset(password, 0, strlen(password)); return false; } if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { - memset(password, 0, strlen(password)); return false; } - memset(password, 0, strlen(password)); return true; } @@ -101,9 +98,11 @@ void notify_key(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t cod if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { switch (sym) { case XKB_KEY_Return: - if (verify_password(password)) { + if (verify_password()) { exit(0); } + password = malloc(1024); // TODO: Let this grow + password[0] = '\0'; break; default: {