comparison svr-auth.c @ 1641:a2bbc22ea1e6 coverity

merge coverity
author Matt Johnston <matt@ucc.asn.au>
date Thu, 21 Mar 2019 00:14:38 +0800
parents 592a18dac250
children 7c17995bcdfb
comparison
equal deleted inserted replaced
1610:96e4c9b2cc00 1641:a2bbc22ea1e6
77 unsigned int userlen, servicelen, methodlen; 77 unsigned int userlen, servicelen, methodlen;
78 int valid_user = 0; 78 int valid_user = 0;
79 79
80 TRACE(("enter recv_msg_userauth_request")) 80 TRACE(("enter recv_msg_userauth_request"))
81 81
82 /* for compensating failure delay */
83 gettime_wrapper(&ses.authstate.auth_starttime);
84
82 /* ignore packets if auth is already done */ 85 /* ignore packets if auth is already done */
83 if (ses.authstate.authdone == 1) { 86 if (ses.authstate.authdone == 1) {
84 TRACE(("leave recv_msg_userauth_request: authdone already")) 87 TRACE(("leave recv_msg_userauth_request: authdone already"))
85 return; 88 return;
86 } 89 }
147 !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) { 150 !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
148 /* user wants to try password auth */ 151 /* user wants to try password auth */
149 if (methodlen == AUTH_METHOD_PASSWORD_LEN && 152 if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
150 strncmp(methodname, AUTH_METHOD_PASSWORD, 153 strncmp(methodname, AUTH_METHOD_PASSWORD,
151 AUTH_METHOD_PASSWORD_LEN) == 0) { 154 AUTH_METHOD_PASSWORD_LEN) == 0) {
152 if (valid_user) { 155 svr_auth_password(valid_user);
153 svr_auth_password(); 156 goto out;
154 goto out;
155 }
156 } 157 }
157 } 158 }
158 #endif 159 #endif
159 160
160 #if DROPBEAR_SVR_PAM_AUTH 161 #if DROPBEAR_SVR_PAM_AUTH
162 !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) { 163 !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
163 /* user wants to try password auth */ 164 /* user wants to try password auth */
164 if (methodlen == AUTH_METHOD_PASSWORD_LEN && 165 if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
165 strncmp(methodname, AUTH_METHOD_PASSWORD, 166 strncmp(methodname, AUTH_METHOD_PASSWORD,
166 AUTH_METHOD_PASSWORD_LEN) == 0) { 167 AUTH_METHOD_PASSWORD_LEN) == 0) {
167 if (valid_user) { 168 svr_auth_pam(valid_user);
168 svr_auth_pam(); 169 goto out;
169 goto out;
170 }
171 } 170 }
172 } 171 }
173 #endif 172 #endif
174 173
175 #if DROPBEAR_SVR_PUBKEY_AUTH 174 #if DROPBEAR_SVR_PUBKEY_AUTH
176 /* user wants to try pubkey auth */ 175 /* user wants to try pubkey auth */
177 if (methodlen == AUTH_METHOD_PUBKEY_LEN && 176 if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
178 strncmp(methodname, AUTH_METHOD_PUBKEY, 177 strncmp(methodname, AUTH_METHOD_PUBKEY,
179 AUTH_METHOD_PUBKEY_LEN) == 0) { 178 AUTH_METHOD_PUBKEY_LEN) == 0) {
180 if (valid_user) { 179 svr_auth_pubkey(valid_user);
181 svr_auth_pubkey();
182 } else {
183 /* pubkey has no failure delay */
184 send_msg_userauth_failure(0, 0);
185 }
186 goto out; 180 goto out;
187 } 181 }
188 #endif 182 #endif
189 183
190 /* nothing matched, we just fail with a delay */ 184 /* nothing matched, we just fail with a delay */
280 return DROPBEAR_FAILURE; 274 return DROPBEAR_FAILURE;
281 } 275 }
282 276
283 /* check if we are running as non-root, and login user is different from the server */ 277 /* check if we are running as non-root, and login user is different from the server */
284 uid = geteuid(); 278 uid = geteuid();
285 if (uid != 0 && uid != ses.authstate.pw_uid) { 279 if (!(DROPBEAR_SVR_MULTIUSER && uid == 0) && uid != ses.authstate.pw_uid) {
286 TRACE(("running as nonroot, only server uid is allowed")) 280 TRACE(("running as nonroot, only server uid is allowed"))
287 dropbear_log(LOG_WARNING, 281 dropbear_log(LOG_WARNING,
288 "Login attempt with wrong user %s from %s", 282 "Login attempt with wrong user %s from %s",
289 ses.authstate.pw_name, 283 ses.authstate.pw_name,
290 svr_ses.addrstring); 284 svr_ses.addrstring);
389 383
390 buf_putbyte(ses.writepayload, partial ? 1 : 0); 384 buf_putbyte(ses.writepayload, partial ? 1 : 0);
391 encrypt_packet(); 385 encrypt_packet();
392 386
393 if (incrfail) { 387 if (incrfail) {
394 unsigned int delay; 388 /* The SSH_MSG_AUTH_FAILURE response is delayed to attempt to
395 genrandom((unsigned char*)&delay, sizeof(delay)); 389 avoid user enumeration and slow brute force attempts.
396 /* We delay for 300ms +- 50ms */ 390 The delay is adjusted by the time already spent in processing
397 delay = 250000 + (delay % 100000); 391 authentication (ses.authstate.auth_starttime timestamp). */
392
393 /* Desired total delay 300ms +-50ms (in nanoseconds).
394 Beware of integer overflow if increasing these values */
395 const unsigned int mindelay = 250000000;
396 const unsigned int vardelay = 100000000;
397 unsigned int rand_delay;
398 struct timespec delay;
399
400 gettime_wrapper(&delay);
401 delay.tv_sec -= ses.authstate.auth_starttime.tv_sec;
402 delay.tv_nsec -= ses.authstate.auth_starttime.tv_nsec;
403
404 /* carry */
405 if (delay.tv_nsec < 0) {
406 delay.tv_nsec += 1000000000;
407 delay.tv_sec -= 1;
408 }
409
410 genrandom((unsigned char*)&rand_delay, sizeof(rand_delay));
411 rand_delay = mindelay + (rand_delay % vardelay);
412
413 if (delay.tv_sec == 0 && delay.tv_nsec <= mindelay) {
414 /* Compensate for elapsed time */
415 delay.tv_nsec = rand_delay - delay.tv_nsec;
416 } else {
417 /* No time left or time went backwards, just delay anyway */
418 delay.tv_sec = 0;
419 delay.tv_nsec = rand_delay;
420 }
421
422
398 #if DROPBEAR_FUZZ 423 #if DROPBEAR_FUZZ
399 if (!fuzz.fuzzing) 424 if (!fuzz.fuzzing)
400 #endif 425 #endif
401 { 426 {
402 usleep(delay); 427 while (nanosleep(&delay, &delay) == -1 && errno == EINTR) { /* Go back to sleep */ }
403 } 428 }
429
404 ses.authstate.failcount++; 430 ses.authstate.failcount++;
405 } 431 }
406 432
407 if (ses.authstate.failcount >= svr_opts.maxauthtries) { 433 if (ses.authstate.failcount >= svr_opts.maxauthtries) {
408 char * userstr; 434 char * userstr;