diff options
Diffstat (limited to 'auth2.c')
-rw-r--r-- | auth2.c | 78 |
1 files changed, 74 insertions, 4 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2.c,v 1.116 2007/09/29 00:25:51 dtucker Exp $ */ | 1 | /* $OpenBSD: auth2.c,v 1.117 2008/07/02 12:36:39 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,10 +26,14 @@ | |||
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" |
35 | #include "ssh2.h" | 39 | #include "ssh2.h" |
@@ -88,10 +92,74 @@ static void input_userauth_request(int, u_int32_t, void *); | |||
88 | static Authmethod *authmethod_lookup(const char *); | 92 | static Authmethod *authmethod_lookup(const char *); |
89 | static char *authmethods_get(void); | 93 | static char *authmethods_get(void); |
90 | 94 | ||
95 | char * | ||
96 | auth2_read_banner(void) | ||
97 | { | ||
98 | struct stat st; | ||
99 | char *banner = NULL; | ||
100 | size_t len, n; | ||
101 | int fd; | ||
102 | |||
103 | if ((fd = open(options.banner, O_RDONLY)) == -1) | ||
104 | return (NULL); | ||
105 | if (fstat(fd, &st) == -1) { | ||
106 | close(fd); | ||
107 | return (NULL); | ||
108 | } | ||
109 | if (st.st_size > 1*1024*1024) { | ||
110 | close(fd); | ||
111 | return (NULL); | ||
112 | } | ||
113 | |||
114 | len = (size_t)st.st_size; /* truncate */ | ||
115 | banner = xmalloc(len + 1); | ||
116 | n = atomicio(read, fd, banner, len); | ||
117 | close(fd); | ||
118 | |||
119 | if (n != len) { | ||
120 | xfree(banner); | ||
121 | return (NULL); | ||
122 | } | ||
123 | banner[n] = '\0'; | ||
124 | |||
125 | return (banner); | ||
126 | } | ||
127 | |||
128 | void | ||
129 | userauth_send_banner(const char *msg) | ||
130 | { | ||
131 | if (datafellows & SSH_BUG_BANNER) | ||
132 | return; | ||
133 | |||
134 | packet_start(SSH2_MSG_USERAUTH_BANNER); | ||
135 | packet_put_cstring(msg); | ||
136 | packet_put_cstring(""); /* language, unused */ | ||
137 | packet_send(); | ||
138 | debug("%s: sent", __func__); | ||
139 | } | ||
140 | |||
141 | static void | ||
142 | userauth_banner(void) | ||
143 | { | ||
144 | char *banner = NULL; | ||
145 | |||
146 | if (options.banner == NULL || | ||
147 | strcasecmp(options.banner, "none") == 0 || | ||
148 | (datafellows & SSH_BUG_BANNER) != 0) | ||
149 | return; | ||
150 | |||
151 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) | ||
152 | goto done; | ||
153 | userauth_send_banner(banner); | ||
154 | |||
155 | done: | ||
156 | if (banner) | ||
157 | xfree(banner); | ||
158 | } | ||
159 | |||
91 | /* | 160 | /* |
92 | * loop until authctxt->success == TRUE | 161 | * loop until authctxt->success == TRUE |
93 | */ | 162 | */ |
94 | |||
95 | void | 163 | void |
96 | do_authentication2(Authctxt *authctxt) | 164 | do_authentication2(Authctxt *authctxt) |
97 | { | 165 | { |
@@ -179,6 +247,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
179 | authctxt->style = style ? xstrdup(style) : NULL; | 247 | authctxt->style = style ? xstrdup(style) : NULL; |
180 | if (use_privsep) | 248 | if (use_privsep) |
181 | mm_inform_authserv(service, style); | 249 | mm_inform_authserv(service, style); |
250 | userauth_banner(); | ||
182 | } else if (strcmp(user, authctxt->user) != 0 || | 251 | } else if (strcmp(user, authctxt->user) != 0 || |
183 | strcmp(service, authctxt->service) != 0) { | 252 | strcmp(service, authctxt->service) != 0) { |
184 | packet_disconnect("Change of username or service not allowed: " | 253 | packet_disconnect("Change of username or service not allowed: " |
@@ -197,7 +266,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) | |||
197 | 266 | ||
198 | /* try to authenticate user */ | 267 | /* try to authenticate user */ |
199 | m = authmethod_lookup(method); | 268 | m = authmethod_lookup(method); |
200 | if (m != NULL) { | 269 | if (m != NULL && authctxt->failures < options.max_authtries) { |
201 | debug2("input_userauth_request: try method %s", method); | 270 | debug2("input_userauth_request: try method %s", method); |
202 | authenticated = m->userauth(authctxt); | 271 | authenticated = m->userauth(authctxt); |
203 | } | 272 | } |
@@ -264,7 +333,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) | |||
264 | /* now we can break out */ | 333 | /* now we can break out */ |
265 | authctxt->success = 1; | 334 | authctxt->success = 1; |
266 | } else { | 335 | } else { |
267 | if (authctxt->failures++ > options.max_authtries) { | 336 | if (++authctxt->failures > options.max_authtries) { |
268 | #ifdef SSH_AUDIT_EVENTS | 337 | #ifdef SSH_AUDIT_EVENTS |
269 | PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); | 338 | PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); |
270 | #endif | 339 | #endif |
@@ -320,3 +389,4 @@ authmethod_lookup(const char *name) | |||
320 | name ? name : "NULL"); | 389 | name ? name : "NULL"); |
321 | return NULL; | 390 | return NULL; |
322 | } | 391 | } |
392 | |||