Fix coredumps on null passwords in pam and ldap auth.
* libmu_auth/pam.c (mu_pam_service): Initialize to package name. (mu_pam_conv): Raise PAM_AUTHTOK_RECOVER_ERR, if password is NULL. Fix memory leak on errors. (mu_authenticate_pam): Fix return value. * libmu_auth/ldap.c (mu_ldap_authenticate): Prevent coredump on empty password.
Showing
2 changed files
with
64 additions
and
26 deletions
... | @@ -769,7 +769,7 @@ mu_ldap_authenticate (struct mu_auth_data **return_data MU_ARG_UNUSED, | ... | @@ -769,7 +769,7 @@ mu_ldap_authenticate (struct mu_auth_data **return_data MU_ARG_UNUSED, |
769 | char *db_pass = auth_data->passwd; | 769 | char *db_pass = auth_data->passwd; |
770 | char *pass = call_data; | 770 | char *pass = call_data; |
771 | 771 | ||
772 | if (auth_data->passwd == NULL) | 772 | if (auth_data->passwd == NULL || !pass) |
773 | return EINVAL; | 773 | return EINVAL; |
774 | 774 | ||
775 | if (db_pass[0] == '{') | 775 | if (db_pass[0] == '{') | ... | ... |
... | @@ -39,63 +39,96 @@ | ... | @@ -39,63 +39,96 @@ |
39 | #ifdef HAVE_CRYPT_H | 39 | #ifdef HAVE_CRYPT_H |
40 | # include <crypt.h> | 40 | # include <crypt.h> |
41 | #endif | 41 | #endif |
42 | |||
43 | #include <mailutils/list.h> | 42 | #include <mailutils/list.h> |
43 | #include <mailutils/errno.h> | ||
44 | #include <mailutils/iterator.h> | 44 | #include <mailutils/iterator.h> |
45 | #include <mailutils/mailbox.h> | 45 | #include <mailutils/mailbox.h> |
46 | #include <mailutils/mu_auth.h> | 46 | #include <mailutils/mu_auth.h> |
47 | #include <mailutils/nls.h> | 47 | #include <mailutils/nls.h> |
48 | 48 | ||
49 | char *mu_pam_service = NULL; | 49 | char *mu_pam_service = PACKAGE; |
50 | 50 | ||
51 | #ifdef USE_LIBPAM | 51 | #ifdef USE_LIBPAM |
52 | #define COPY_STRING(s) (s) ? strdup(s) : NULL | 52 | #define COPY_STRING(s) (s) ? strdup(s) : NULL |
53 | 53 | ||
54 | static char *_pwd; | 54 | static char *_pwd; |
55 | static char *_user; | 55 | static char *_user; |
56 | static int _perr = 0; | 56 | |
57 | #define overwrite_and_free(ptr) \ | ||
58 | do \ | ||
59 | { \ | ||
60 | char *s = ptr; \ | ||
61 | while (*s) \ | ||
62 | *s++ = 0; \ | ||
63 | } \ | ||
64 | while (0) | ||
65 | |||
57 | 66 | ||
58 | static int | 67 | static int |
59 | mu_pam_conv (int num_msg, const struct pam_message **msg, | 68 | mu_pam_conv (int num_msg, const struct pam_message **msg, |
60 | struct pam_response **resp, void *appdata_ptr MU_ARG_UNUSED) | 69 | struct pam_response **resp, void *appdata_ptr MU_ARG_UNUSED) |
61 | { | 70 | { |
62 | int replies = 0; | 71 | int status = PAM_SUCCESS; |
72 | int i; | ||
63 | struct pam_response *reply = NULL; | 73 | struct pam_response *reply = NULL; |
64 | 74 | ||
65 | reply = malloc (sizeof (*reply) * num_msg); | 75 | reply = calloc (num_msg, sizeof (*reply)); |
66 | if (!reply) | 76 | if (!reply) |
67 | return PAM_CONV_ERR; | 77 | return PAM_CONV_ERR; |
68 | 78 | ||
69 | for (replies = 0; replies < num_msg; replies++) | 79 | for (i = 0; i < num_msg && status == PAM_SUCCESS; i++) |
70 | { | 80 | { |
71 | switch (msg[replies]->msg_style) | 81 | switch (msg[i]->msg_style) |
72 | { | 82 | { |
73 | case PAM_PROMPT_ECHO_ON: | 83 | case PAM_PROMPT_ECHO_ON: |
74 | reply[replies].resp_retcode = PAM_SUCCESS; | 84 | reply[i].resp_retcode = PAM_SUCCESS; |
75 | reply[replies].resp = COPY_STRING (_user); | 85 | reply[i].resp = COPY_STRING (_user); |
76 | /* PAM frees resp */ | 86 | /* PAM frees resp */ |
77 | break; | 87 | break; |
78 | 88 | ||
79 | case PAM_PROMPT_ECHO_OFF: | 89 | case PAM_PROMPT_ECHO_OFF: |
80 | reply[replies].resp_retcode = PAM_SUCCESS; | 90 | if (_pwd) |
81 | reply[replies].resp = COPY_STRING (_pwd); | 91 | { |
82 | /* PAM frees resp */ | 92 | reply[i].resp_retcode = PAM_SUCCESS; |
93 | reply[i].resp = COPY_STRING (_pwd); | ||
94 | /* PAM frees resp */ | ||
95 | } | ||
96 | else | ||
97 | status = PAM_AUTHTOK_RECOVER_ERR; | ||
83 | break; | 98 | break; |
84 | 99 | ||
85 | case PAM_TEXT_INFO: | 100 | case PAM_TEXT_INFO: |
86 | case PAM_ERROR_MSG: | 101 | case PAM_ERROR_MSG: |
87 | reply[replies].resp_retcode = PAM_SUCCESS; | 102 | reply[i].resp_retcode = PAM_SUCCESS; |
88 | reply[replies].resp = NULL; | 103 | reply[i].resp = NULL; |
89 | break; | 104 | break; |
90 | 105 | ||
91 | default: | 106 | default: |
92 | free (reply); | 107 | status = PAM_CONV_ERR; |
93 | _perr = 1; | ||
94 | return PAM_CONV_ERR; | ||
95 | } | 108 | } |
96 | } | 109 | } |
97 | *resp = reply; | 110 | if (status != PAM_SUCCESS) |
98 | return PAM_SUCCESS; | 111 | { |
112 | for (i = 0; i < num_msg; i++) | ||
113 | if (reply[i].resp) | ||
114 | { | ||
115 | switch (msg[i]->msg_style) | ||
116 | { | ||
117 | case PAM_PROMPT_ECHO_ON: | ||
118 | case PAM_PROMPT_ECHO_OFF: | ||
119 | overwrite_and_free (reply[i].resp); | ||
120 | break; | ||
121 | |||
122 | case PAM_ERROR_MSG: | ||
123 | case PAM_TEXT_INFO: | ||
124 | free (reply[i].resp); | ||
125 | } | ||
126 | } | ||
127 | free (reply); | ||
128 | } | ||
129 | else | ||
130 | *resp = reply; | ||
131 | return status; | ||
99 | } | 132 | } |
100 | 133 | ||
101 | static struct pam_conv PAM_conversation = { &mu_pam_conv, NULL }; | 134 | static struct pam_conv PAM_conversation = { &mu_pam_conv, NULL }; |
... | @@ -111,11 +144,10 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, | ... | @@ -111,11 +144,10 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, |
111 | pam_handle_t *pamh; | 144 | pam_handle_t *pamh; |
112 | int pamerror; | 145 | int pamerror; |
113 | 146 | ||
114 | #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \ | 147 | #define PAM_ERROR if (pamerror != PAM_SUCCESS) goto pam_errlab; |
115 | goto pam_errlab; | ||
116 | 148 | ||
117 | if (!auth_data) | 149 | if (!auth_data) |
118 | return 1; | 150 | return EINVAL; |
119 | 151 | ||
120 | _user = (char *) auth_data->name; | 152 | _user = (char *) auth_data->name; |
121 | _pwd = pass; | 153 | _pwd = pass; |
... | @@ -128,7 +160,14 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, | ... | @@ -128,7 +160,14 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, |
128 | pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED); | 160 | pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED); |
129 | pam_errlab: | 161 | pam_errlab: |
130 | pam_end (pamh, PAM_SUCCESS); | 162 | pam_end (pamh, PAM_SUCCESS); |
131 | return pamerror != PAM_SUCCESS; | 163 | switch (pamerror) |
164 | { | ||
165 | case PAM_SUCCESS: | ||
166 | return 0; | ||
167 | case PAM_AUTH_ERR: | ||
168 | return MU_ERR_AUTH_FAILURE; | ||
169 | } | ||
170 | return MU_ERR_FAILURE; | ||
132 | } | 171 | } |
133 | 172 | ||
134 | #else | 173 | #else |
... | @@ -139,8 +178,7 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, | ... | @@ -139,8 +178,7 @@ mu_authenticate_pam (struct mu_auth_data **return_data MU_ARG_UNUSED, |
139 | void *func_data MU_ARG_UNUSED, | 178 | void *func_data MU_ARG_UNUSED, |
140 | void *call_data MU_ARG_UNUSED) | 179 | void *call_data MU_ARG_UNUSED) |
141 | { | 180 | { |
142 | errno = ENOSYS; | 181 | return ENOSYS; |
143 | return 1; | ||
144 | } | 182 | } |
145 | 183 | ||
146 | #endif | 184 | #endif | ... | ... |
-
Please register or sign in to post a comment