diff options
author | emersion <contact@emersion.fr> | 2018-04-13 09:14:37 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-13 09:14:37 -0400 |
commit | 2b34bf1882f24ebd8c87debb2e2223bc084736c3 (patch) | |
tree | b27acb8f604bf5fc5cc39b927d3e62d748cf7313 /swaylock/password.c | |
parent | container_destroy: fix segfault (diff) | |
parent | Merge pull request #1808 from emersion/xwayland-unmapped-on-create (diff) | |
download | sway-2b34bf1882f24ebd8c87debb2e2223bc084736c3.tar.gz sway-2b34bf1882f24ebd8c87debb2e2223bc084736c3.tar.zst sway-2b34bf1882f24ebd8c87debb2e2223bc084736c3.zip |
Merge branch 'master' into crashes
Diffstat (limited to 'swaylock/password.c')
-rw-r--r-- | swaylock/password.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/swaylock/password.c b/swaylock/password.c index 1839f991..c8df3de8 100644 --- a/swaylock/password.c +++ b/swaylock/password.c | |||
@@ -1,7 +1,9 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
1 | #include <assert.h> | 2 | #include <assert.h> |
2 | #include <pwd.h> | 3 | #include <pwd.h> |
3 | #include <security/pam_appl.h> | 4 | #include <security/pam_appl.h> |
4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <string.h> | ||
5 | #include <unistd.h> | 7 | #include <unistd.h> |
6 | #include <wlr/util/log.h> | 8 | #include <wlr/util/log.h> |
7 | #include <xkbcommon/xkbcommon.h> | 9 | #include <xkbcommon/xkbcommon.h> |
@@ -20,7 +22,7 @@ static int function_conversation(int num_msg, const struct pam_message **msg, | |||
20 | switch (msg[i]->msg_style) { | 22 | switch (msg[i]->msg_style) { |
21 | case PAM_PROMPT_ECHO_OFF: | 23 | case PAM_PROMPT_ECHO_OFF: |
22 | case PAM_PROMPT_ECHO_ON: | 24 | case PAM_PROMPT_ECHO_ON: |
23 | pam_reply[i].resp = pw->buffer; | 25 | pam_reply[i].resp = strdup(pw->buffer); // PAM clears and frees this |
24 | break; | 26 | break; |
25 | case PAM_ERROR_MSG: | 27 | case PAM_ERROR_MSG: |
26 | case PAM_TEXT_INFO: | 28 | case PAM_TEXT_INFO: |
@@ -30,6 +32,16 @@ static int function_conversation(int num_msg, const struct pam_message **msg, | |||
30 | return PAM_SUCCESS; | 32 | return PAM_SUCCESS; |
31 | } | 33 | } |
32 | 34 | ||
35 | void clear_password_buffer(struct swaylock_password *pw) { | ||
36 | // Use volatile keyword so so compiler can't optimize this out. | ||
37 | volatile char *buffer = pw->buffer; | ||
38 | volatile char zero = '\0'; | ||
39 | for (size_t i = 0; i < sizeof(buffer); ++i) { | ||
40 | buffer[i] = zero; | ||
41 | } | ||
42 | pw->len = 0; | ||
43 | } | ||
44 | |||
33 | static bool attempt_password(struct swaylock_password *pw) { | 45 | static bool attempt_password(struct swaylock_password *pw) { |
34 | struct passwd *passwd = getpwuid(getuid()); | 46 | struct passwd *passwd = getpwuid(getuid()); |
35 | char *username = passwd->pw_name; | 47 | char *username = passwd->pw_name; |
@@ -38,6 +50,7 @@ static bool attempt_password(struct swaylock_password *pw) { | |||
38 | }; | 50 | }; |
39 | pam_handle_t *local_auth_handle = NULL; | 51 | pam_handle_t *local_auth_handle = NULL; |
40 | int pam_err; | 52 | int pam_err; |
53 | // TODO: only call pam_start once. keep the same handle the whole time | ||
41 | if ((pam_err = pam_start("swaylock", username, | 54 | if ((pam_err = pam_start("swaylock", username, |
42 | &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { | 55 | &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { |
43 | wlr_log(L_ERROR, "PAM returned error %d", pam_err); | 56 | wlr_log(L_ERROR, "PAM returned error %d", pam_err); |
@@ -46,18 +59,15 @@ static bool attempt_password(struct swaylock_password *pw) { | |||
46 | wlr_log(L_ERROR, "pam_authenticate failed"); | 59 | wlr_log(L_ERROR, "pam_authenticate failed"); |
47 | goto fail; | 60 | goto fail; |
48 | } | 61 | } |
62 | // TODO: only call pam_end once we succeed at authing. refresh tokens beforehand | ||
49 | if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { | 63 | if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { |
50 | wlr_log(L_ERROR, "pam_end failed"); | 64 | wlr_log(L_ERROR, "pam_end failed"); |
51 | goto fail; | 65 | goto fail; |
52 | } | 66 | } |
53 | // PAM frees this | 67 | clear_password_buffer(pw); |
54 | pw->buffer = NULL; | ||
55 | pw->len = pw->size = 0; | ||
56 | return true; | 68 | return true; |
57 | fail: | 69 | fail: |
58 | // PAM frees this | 70 | clear_password_buffer(pw); |
59 | pw->buffer = NULL; | ||
60 | pw->len = pw->size = 0; | ||
61 | return false; | 71 | return false; |
62 | } | 72 | } |
63 | 73 | ||
@@ -70,24 +80,10 @@ static bool backspace(struct swaylock_password *pw) { | |||
70 | } | 80 | } |
71 | 81 | ||
72 | static void append_ch(struct swaylock_password *pw, uint32_t codepoint) { | 82 | static void append_ch(struct swaylock_password *pw, uint32_t codepoint) { |
73 | if (!pw->buffer) { | ||
74 | pw->size = 8; | ||
75 | if (!(pw->buffer = malloc(pw->size))) { | ||
76 | // TODO: Display error | ||
77 | return; | ||
78 | } | ||
79 | pw->buffer[0] = 0; | ||
80 | } | ||
81 | size_t utf8_size = utf8_chsize(codepoint); | 83 | size_t utf8_size = utf8_chsize(codepoint); |
82 | if (pw->len + utf8_size + 1 >= pw->size) { | 84 | if (pw->len + utf8_size + 1 >= sizeof(pw->buffer)) { |
83 | size_t size = pw->size * 2; | 85 | // TODO: Display error |
84 | char *buffer = realloc(pw->buffer, size); | 86 | return; |
85 | if (!buffer) { | ||
86 | // TODO: Display error | ||
87 | return; | ||
88 | } | ||
89 | pw->size = size; | ||
90 | pw->buffer = buffer; | ||
91 | } | 87 | } |
92 | utf8_encode(&pw->buffer[pw->len], codepoint); | 88 | utf8_encode(&pw->buffer[pw->len], codepoint); |
93 | pw->buffer[pw->len + utf8_size] = 0; | 89 | pw->buffer[pw->len + utf8_size] = 0; |