Mercurial > dropbear
comparison svr-authpam.c @ 1617:1fbe598a14fb
Merge bugfix delay invalid users
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 23 Aug 2018 23:43:45 +0800 |
parents | 5d2d1021ca00 |
children | 258b57b208ae |
comparison
equal
deleted
inserted
replaced
1611:0196f4f83fee | 1617:1fbe598a14fb |
---|---|
176 * fairly standard (ie just "what's your username, what's your password, OK"). | 176 * fairly standard (ie just "what's your username, what's your password, OK"). |
177 * | 177 * |
178 * Keyboard interactive would be a lot nicer, but since PAM is synchronous, it | 178 * Keyboard interactive would be a lot nicer, but since PAM is synchronous, it |
179 * gets very messy trying to send the interactive challenges, and read the | 179 * gets very messy trying to send the interactive challenges, and read the |
180 * interactive responses, over the network. */ | 180 * interactive responses, over the network. */ |
181 void svr_auth_pam() { | 181 void svr_auth_pam(int valid_user) { |
182 | 182 |
183 struct UserDataS userData = {NULL, NULL}; | 183 struct UserDataS userData = {NULL, NULL}; |
184 struct pam_conv pamConv = { | 184 struct pam_conv pamConv = { |
185 pamConvFunc, | 185 pamConvFunc, |
186 &userData /* submitted to pamvConvFunc as appdata_ptr */ | 186 &userData /* submitted to pamvConvFunc as appdata_ptr */ |
187 }; | 187 }; |
188 const char* printable_user = NULL; | |
188 | 189 |
189 pam_handle_t* pamHandlep = NULL; | 190 pam_handle_t* pamHandlep = NULL; |
190 | 191 |
191 char * password = NULL; | 192 char * password = NULL; |
192 unsigned int passwordlen; | 193 unsigned int passwordlen; |
202 goto cleanup; | 203 goto cleanup; |
203 } | 204 } |
204 | 205 |
205 password = buf_getstring(ses.payload, &passwordlen); | 206 password = buf_getstring(ses.payload, &passwordlen); |
206 | 207 |
208 /* We run the PAM conversation regardless of whether the username is valid | |
209 in case the conversation function has an inherent delay. | |
210 Use ses.authstate.username rather than ses.authstate.pw_name. | |
211 After PAM succeeds we then check the valid_user flag too */ | |
212 | |
207 /* used to pass data to the PAM conversation function - don't bother with | 213 /* used to pass data to the PAM conversation function - don't bother with |
208 * strdup() etc since these are touched only by our own conversation | 214 * strdup() etc since these are touched only by our own conversation |
209 * function (above) which takes care of it */ | 215 * function (above) which takes care of it */ |
210 userData.user = ses.authstate.pw_name; | 216 userData.user = ses.authstate.username; |
211 userData.passwd = password; | 217 userData.passwd = password; |
218 | |
219 if (ses.authstate.pw_name) { | |
220 printable_user = ses.authstate.pw_name; | |
221 } else { | |
222 printable_user = "<invalid username>"; | |
223 } | |
212 | 224 |
213 /* Init pam */ | 225 /* Init pam */ |
214 if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) { | 226 if ((rc = pam_start("sshd", NULL, &pamConv, &pamHandlep)) != PAM_SUCCESS) { |
215 dropbear_log(LOG_WARNING, "pam_start() failed, rc=%d, %s", | 227 dropbear_log(LOG_WARNING, "pam_start() failed, rc=%d, %s", |
216 rc, pam_strerror(pamHandlep, rc)); | 228 rc, pam_strerror(pamHandlep, rc)); |
240 if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) { | 252 if ((rc = pam_authenticate(pamHandlep, 0)) != PAM_SUCCESS) { |
241 dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s", | 253 dropbear_log(LOG_WARNING, "pam_authenticate() failed, rc=%d, %s", |
242 rc, pam_strerror(pamHandlep, rc)); | 254 rc, pam_strerror(pamHandlep, rc)); |
243 dropbear_log(LOG_WARNING, | 255 dropbear_log(LOG_WARNING, |
244 "Bad PAM password attempt for '%s' from %s", | 256 "Bad PAM password attempt for '%s' from %s", |
245 ses.authstate.pw_name, | 257 printable_user, |
246 svr_ses.addrstring); | 258 svr_ses.addrstring); |
247 send_msg_userauth_failure(0, 1); | 259 send_msg_userauth_failure(0, 1); |
248 goto cleanup; | 260 goto cleanup; |
249 } | 261 } |
250 | 262 |
251 if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) { | 263 if ((rc = pam_acct_mgmt(pamHandlep, 0)) != PAM_SUCCESS) { |
252 dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s", | 264 dropbear_log(LOG_WARNING, "pam_acct_mgmt() failed, rc=%d, %s", |
253 rc, pam_strerror(pamHandlep, rc)); | 265 rc, pam_strerror(pamHandlep, rc)); |
254 dropbear_log(LOG_WARNING, | 266 dropbear_log(LOG_WARNING, |
255 "Bad PAM password attempt for '%s' from %s", | 267 "Bad PAM password attempt for '%s' from %s", |
256 ses.authstate.pw_name, | 268 printable_user, |
257 svr_ses.addrstring); | 269 svr_ses.addrstring); |
258 send_msg_userauth_failure(0, 1); | 270 send_msg_userauth_failure(0, 1); |
259 goto cleanup; | 271 goto cleanup; |
272 } | |
273 | |
274 if (!valid_user) { | |
275 /* PAM auth succeeded but the username isn't allowed in for another reason | |
276 (checkusername() failed) */ | |
277 send_msg_userauth_failure(0, 1); | |
260 } | 278 } |
261 | 279 |
262 /* successful authentication */ | 280 /* successful authentication */ |
263 dropbear_log(LOG_NOTICE, "PAM password auth succeeded for '%s' from %s", | 281 dropbear_log(LOG_NOTICE, "PAM password auth succeeded for '%s' from %s", |
264 ses.authstate.pw_name, | 282 ses.authstate.pw_name, |