summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth2.c')
-rw-r--r--auth2.c88
1 files changed, 81 insertions, 7 deletions
diff --git a/auth2.c b/auth2.c
index e2543a501..3849b07ab 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.115 2007/04/14 22:01:58 stevesk Exp $ */ 1/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -26,12 +26,17 @@
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/uio.h>
29 31
32#include <fcntl.h>
30#include <pwd.h> 33#include <pwd.h>
31#include <stdarg.h> 34#include <stdarg.h>
32#include <string.h> 35#include <string.h>
36#include <unistd.h>
33 37
34#include "xmalloc.h" 38#include "xmalloc.h"
39#include "atomicio.h"
35#include "ssh2.h" 40#include "ssh2.h"
36#include "packet.h" 41#include "packet.h"
37#include "log.h" 42#include "log.h"
@@ -89,12 +94,75 @@ static void input_userauth_request(int, u_int32_t, void *);
89/* helper */ 94/* helper */
90static Authmethod *authmethod_lookup(const char *); 95static Authmethod *authmethod_lookup(const char *);
91static char *authmethods_get(void); 96static char *authmethods_get(void);
92int user_key_allowed(struct passwd *, Key *); 97
98char *
99auth2_read_banner(void)
100{
101 struct stat st;
102 char *banner = NULL;
103 size_t len, n;
104 int fd;
105
106 if ((fd = open(options.banner, O_RDONLY)) == -1)
107 return (NULL);
108 if (fstat(fd, &st) == -1) {
109 close(fd);
110 return (NULL);
111 }
112 if (st.st_size > 1*1024*1024) {
113 close(fd);
114 return (NULL);
115 }
116
117 len = (size_t)st.st_size; /* truncate */
118 banner = xmalloc(len + 1);
119 n = atomicio(read, fd, banner, len);
120 close(fd);
121
122 if (n != len) {
123 xfree(banner);
124 return (NULL);
125 }
126 banner[n] = '\0';
127
128 return (banner);
129}
130
131void
132userauth_send_banner(const char *msg)
133{
134 if (datafellows & SSH_BUG_BANNER)
135 return;
136
137 packet_start(SSH2_MSG_USERAUTH_BANNER);
138 packet_put_cstring(msg);
139 packet_put_cstring(""); /* language, unused */
140 packet_send();
141 debug("%s: sent", __func__);
142}
143
144static void
145userauth_banner(void)
146{
147 char *banner = NULL;
148
149 if (options.banner == NULL ||
150 strcasecmp(options.banner, "none") == 0 ||
151 (datafellows & SSH_BUG_BANNER) != 0)
152 return;
153
154 if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
155 goto done;
156 userauth_send_banner(banner);
157
158done:
159 if (banner)
160 xfree(banner);
161}
93 162
94/* 163/*
95 * loop until authctxt->success == TRUE 164 * loop until authctxt->success == TRUE
96 */ 165 */
97
98void 166void
99do_authentication2(Authctxt *authctxt) 167do_authentication2(Authctxt *authctxt)
100{ 168{
@@ -188,6 +256,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
188 authctxt->role = role ? xstrdup(role) : NULL; 256 authctxt->role = role ? xstrdup(role) : NULL;
189 if (use_privsep) 257 if (use_privsep)
190 mm_inform_authserv(service, style, role); 258 mm_inform_authserv(service, style, role);
259 userauth_banner();
191 } else if (strcmp(user, authctxt->user) != 0 || 260 } else if (strcmp(user, authctxt->user) != 0 ||
192 strcmp(service, authctxt->service) != 0) { 261 strcmp(service, authctxt->service) != 0) {
193 packet_disconnect("Change of username or service not allowed: " 262 packet_disconnect("Change of username or service not allowed: "
@@ -207,7 +276,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
207 276
208 /* try to authenticate user */ 277 /* try to authenticate user */
209 m = authmethod_lookup(method); 278 m = authmethod_lookup(method);
210 if (m != NULL) { 279 if (m != NULL && authctxt->failures < options.max_authtries) {
211 debug2("input_userauth_request: try method %s", method); 280 debug2("input_userauth_request: try method %s", method);
212 authenticated = m->userauth(authctxt); 281 authenticated = m->userauth(authctxt);
213 } 282 }
@@ -274,9 +343,13 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
274 /* now we can break out */ 343 /* now we can break out */
275 authctxt->success = 1; 344 authctxt->success = 1;
276 } else { 345 } else {
277 /* Dont count server configuration issues against the client */ 346
278 if (!authctxt->server_caused_failure && 347 /* Allow initial try of "none" auth without failure penalty */
279 authctxt->failures++ > options.max_authtries) { 348 /* Don't count server configuration issues against the client */
349 if (!authctxt->server_caused_failure &&
350 (authctxt->attempt > 1 || strcmp(method, "none") != 0))
351 authctxt->failures++;
352 if (authctxt->failures >= options.max_authtries) {
280#ifdef SSH_AUDIT_EVENTS 353#ifdef SSH_AUDIT_EVENTS
281 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 354 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
282#endif 355#endif
@@ -332,3 +405,4 @@ authmethod_lookup(const char *name)
332 name ? name : "NULL"); 405 name ? name : "NULL");
333 return NULL; 406 return NULL;
334} 407}
408