Mercurial > dropbear
comparison svr-session.c @ 1790:42745af83b7d
Introduce extra delay before closing unauthenticated sessions
To make it harder for attackers, introduce a delay to keep an
unauthenticated session open a bit longer, thus blocking a connection
slot until after the delay.
Without this, while there is a limit on the amount of attempts an attacker
can make at the same time (MAX_UNAUTH_PER_IP), the time taken by dropbear to
handle one attempt is still short and thus for each of the allowed parallel
attempts many attempts can be chained one after the other. The attempt rate
is then:
"MAX_UNAUTH_PER_IP / <process time of one attempt>".
With the delay, this rate becomes:
"MAX_UNAUTH_PER_IP / UNAUTH_CLOSE_DELAY".
author | Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> |
---|---|
date | Wed, 15 Feb 2017 13:53:04 +0100 |
parents | a6da10ac64b5 |
children | 8a78cc13eb30 |
comparison
equal
deleted
inserted
replaced
1789:249681d9ecda | 1790:42745af83b7d |
---|---|
213 void svr_dropbear_exit(int exitcode, const char* format, va_list param) { | 213 void svr_dropbear_exit(int exitcode, const char* format, va_list param) { |
214 char exitmsg[150]; | 214 char exitmsg[150]; |
215 char fullmsg[300]; | 215 char fullmsg[300]; |
216 char fromaddr[60]; | 216 char fromaddr[60]; |
217 int i; | 217 int i; |
218 int add_delay = 0; | |
218 | 219 |
219 #if DROPBEAR_PLUGIN | 220 #if DROPBEAR_PLUGIN |
220 if ((ses.plugin_session != NULL)) { | 221 if ((ses.plugin_session != NULL)) { |
221 svr_ses.plugin_instance->delete_session(ses.plugin_session); | 222 svr_ses.plugin_instance->delete_session(ses.plugin_session); |
222 } | 223 } |
245 } else if (ses.authstate.pw_name) { | 246 } else if (ses.authstate.pw_name) { |
246 /* we have a potential user */ | 247 /* we have a potential user */ |
247 snprintf(fullmsg, sizeof(fullmsg), | 248 snprintf(fullmsg, sizeof(fullmsg), |
248 "Exit before auth%s: (user '%s', %u fails): %s", | 249 "Exit before auth%s: (user '%s', %u fails): %s", |
249 fromaddr, ses.authstate.pw_name, ses.authstate.failcount, exitmsg); | 250 fromaddr, ses.authstate.pw_name, ses.authstate.failcount, exitmsg); |
251 add_delay = 1; | |
250 } else { | 252 } else { |
251 /* before userauth */ | 253 /* before userauth */ |
252 snprintf(fullmsg, sizeof(fullmsg), "Exit before auth%s: %s", fromaddr, exitmsg); | 254 snprintf(fullmsg, sizeof(fullmsg), "Exit before auth%s: %s", fromaddr, exitmsg); |
255 add_delay = 1; | |
253 } | 256 } |
254 | 257 |
255 dropbear_log(LOG_INFO, "%s", fullmsg); | 258 dropbear_log(LOG_INFO, "%s", fullmsg); |
259 | |
260 /* To make it harder for attackers, introduce a delay to keep an | |
261 * unauthenticated session open a bit longer, thus blocking a connection | |
262 * slot until after the delay. Without this, while there is a limit on | |
263 * the amount of attempts an attacker can make at the same time | |
264 * (MAX_UNAUTH_PER_IP), the time taken by dropbear to handle one attempt | |
265 * is still short and thus for each of the allowed parallel attempts | |
266 * many attempts can be chained one after the other. The attempt rate is | |
267 * then: | |
268 * "MAX_UNAUTH_PER_IP / <process time of one attempt>". | |
269 * With the delay, this rate becomes: | |
270 * "MAX_UNAUTH_PER_IP / UNAUTH_CLOSE_DELAY". | |
271 */ | |
272 if ((add_delay != 0) && (UNAUTH_CLOSE_DELAY > 0)) { | |
273 TRACE(("svr_dropbear_exit: start delay of %d seconds", UNAUTH_CLOSE_DELAY)); | |
274 sleep(UNAUTH_CLOSE_DELAY); | |
275 TRACE(("svr_dropbear_exit: end delay of %d seconds", UNAUTH_CLOSE_DELAY)); | |
276 } | |
256 | 277 |
257 #if DROPBEAR_VFORK | 278 #if DROPBEAR_VFORK |
258 /* For uclinux only the main server process should cleanup - we don't want | 279 /* For uclinux only the main server process should cleanup - we don't want |
259 * forked children doing that */ | 280 * forked children doing that */ |
260 if (svr_ses.server_pid == getpid()) | 281 if (svr_ses.server_pid == getpid()) |