Commit 29b072f7 29b072f730bbe6b96d8518987ed125a6020fb5d4 by Sergey Poznyakoff

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.
1 parent 178da060
...@@ -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
......