=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/auth2.c,v retrieving revision 1.116 retrieving revision 1.117 diff -u -r1.116 -r1.117 --- src/usr.bin/ssh/auth2.c 2007/09/29 00:25:51 1.116 +++ src/usr.bin/ssh/auth2.c 2008/07/02 12:36:39 1.117 @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.116 2007/09/29 00:25:51 dtucker Exp $ */ +/* $OpenBSD: auth2.c,v 1.117 2008/07/02 12:36:39 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -25,11 +25,16 @@ #include +#include +#include +#include #include #include #include +#include +#include "atomicio.h" #include "xmalloc.h" #include "ssh2.h" #include "packet.h" @@ -84,10 +89,65 @@ static Authmethod *authmethod_lookup(const char *); static char *authmethods_get(void); +char * +auth2_read_banner(void) +{ + struct stat st; + char *banner = NULL; + size_t len, n; + int fd; + + if ((fd = open(options.banner, O_RDONLY)) == -1) + return (NULL); + if (fstat(fd, &st) == -1) { + close(fd); + return (NULL); + } + if (st.st_size > 1*1024*1024) { + close(fd); + return (NULL); + } + + len = (size_t)st.st_size; /* truncate */ + banner = xmalloc(len + 1); + n = atomicio(read, fd, banner, len); + close(fd); + + if (n != len) { + xfree(banner); + return (NULL); + } + banner[n] = '\0'; + + return (banner); +} + +static void +userauth_banner(void) +{ + char *banner = NULL; + + if (options.banner == NULL || + strcasecmp(options.banner, "none") == 0 || + (datafellows & SSH_BUG_BANNER) != 0) + return; + + if ((banner = PRIVSEP(auth2_read_banner())) == NULL) + goto done; + + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(banner); + packet_put_cstring(""); /* language, unused */ + packet_send(); + debug("userauth_banner: sent"); +done: + if (banner) + xfree(banner); +} + /* * loop until authctxt->success == TRUE */ - void do_authentication2(Authctxt *authctxt) { @@ -168,6 +228,7 @@ authctxt->style = style ? xstrdup(style) : NULL; if (use_privsep) mm_inform_authserv(service, style); + userauth_banner(); } else if (strcmp(user, authctxt->user) != 0 || strcmp(service, authctxt->service) != 0) { packet_disconnect("Change of username or service not allowed: " @@ -186,7 +247,7 @@ /* try to authenticate user */ m = authmethod_lookup(method); - if (m != NULL) { + if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); } @@ -227,7 +288,7 @@ /* now we can break out */ authctxt->success = 1; } else { - if (authctxt->failures++ > options.max_authtries) + if (++authctxt->failures > options.max_authtries) packet_disconnect(AUTH_FAIL_MSG, authctxt->user); methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); @@ -279,3 +340,4 @@ name ? name : "NULL"); return NULL; } +