diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | auth2-none.c | 72 | ||||
-rw-r--r-- | auth2.c | 78 |
3 files changed, 94 insertions, 74 deletions
@@ -33,6 +33,22 @@ | |||
33 | Merge duplicate host key file checks, based in part on a patch from Rob | 33 | Merge duplicate host key file checks, based in part on a patch from Rob |
34 | Holland via bz #1348 . Also checks for non-regular files during protocol | 34 | Holland via bz #1348 . Also checks for non-regular files during protocol |
35 | 1 RSA auth. ok djm@ | 35 | 1 RSA auth. ok djm@ |
36 | - djm@cvs.openbsd.org 2008/07/02 12:36:39 | ||
37 | [auth2-none.c auth2.c] | ||
38 | Make protocol 2 MaxAuthTries behaviour a little more sensible: | ||
39 | Check whether client has exceeded MaxAuthTries before running | ||
40 | an authentication method and skip it if they have, previously it | ||
41 | would always allow one try (for "none" auth). | ||
42 | Preincrement failure count before post-auth test - previously this | ||
43 | checked and postincremented, also to allow one "none" try. | ||
44 | Together, these two changes always count the "none" auth method | ||
45 | which could be skipped by a malicious client (e.g. an SSH worm) | ||
46 | to get an extra attempt at a real auth method. They also make | ||
47 | MaxAuthTries=0 a useful way to block users entirely (esp. in a | ||
48 | sshd_config Match block). | ||
49 | Also, move sending of any preauth banner from "none" auth method | ||
50 | to the first call to input_userauth_request(), so worms that skip | ||
51 | the "none" method get to see it too. | ||
36 | 52 | ||
37 | 20080630 | 53 | 20080630 |
38 | - (djm) OpenBSD CVS Sync | 54 | - (djm) OpenBSD CVS Sync |
@@ -4516,4 +4532,4 @@ | |||
4516 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 4532 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
4517 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 4533 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
4518 | 4534 | ||
4519 | $Id: ChangeLog,v 1.5047 2008/07/02 12:37:30 dtucker Exp $ | 4535 | $Id: ChangeLog,v 1.5048 2008/07/02 12:56:09 dtucker Exp $ |
diff --git a/auth2-none.c b/auth2-none.c index 28e593e6c..10accfe55 100644 --- a/auth2-none.c +++ b/auth2-none.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-none.c,v 1.14 2007/08/23 03:22:16 djm Exp $ */ | 1 | /* $OpenBSD: auth2-none.c,v 1.15 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 | * |
@@ -31,9 +31,10 @@ | |||
31 | 31 | ||
32 | #include <fcntl.h> | 32 | #include <fcntl.h> |
33 | #include <stdarg.h> | 33 | #include <stdarg.h> |
34 | #include <unistd.h> | ||
35 | #include <string.h> | 34 | #include <string.h> |
35 | #include <unistd.h> | ||
36 | 36 | ||
37 | #include "atomicio.h" | ||
37 | #include "xmalloc.h" | 38 | #include "xmalloc.h" |
38 | #include "key.h" | 39 | #include "key.h" |
39 | #include "hostfile.h" | 40 | #include "hostfile.h" |
@@ -42,7 +43,6 @@ | |||
42 | #include "log.h" | 43 | #include "log.h" |
43 | #include "buffer.h" | 44 | #include "buffer.h" |
44 | #include "servconf.h" | 45 | #include "servconf.h" |
45 | #include "atomicio.h" | ||
46 | #include "compat.h" | 46 | #include "compat.h" |
47 | #include "ssh2.h" | 47 | #include "ssh2.h" |
48 | #ifdef GSSAPI | 48 | #ifdef GSSAPI |
@@ -56,77 +56,11 @@ extern ServerOptions options; | |||
56 | /* "none" is allowed only one time */ | 56 | /* "none" is allowed only one time */ |
57 | static int none_enabled = 1; | 57 | static int none_enabled = 1; |
58 | 58 | ||
59 | char * | ||
60 | auth2_read_banner(void) | ||
61 | { | ||
62 | struct stat st; | ||
63 | char *banner = NULL; | ||
64 | size_t len, n; | ||
65 | int fd; | ||
66 | |||
67 | if ((fd = open(options.banner, O_RDONLY)) == -1) | ||
68 | return (NULL); | ||
69 | if (fstat(fd, &st) == -1) { | ||
70 | close(fd); | ||
71 | return (NULL); | ||
72 | } | ||
73 | if (st.st_size > 1*1024*1024) { | ||
74 | close(fd); | ||
75 | return (NULL); | ||
76 | } | ||
77 | |||
78 | len = (size_t)st.st_size; /* truncate */ | ||
79 | banner = xmalloc(len + 1); | ||
80 | n = atomicio(read, fd, banner, len); | ||
81 | close(fd); | ||
82 | |||
83 | if (n != len) { | ||
84 | xfree(banner); | ||
85 | return (NULL); | ||
86 | } | ||
87 | banner[n] = '\0'; | ||
88 | |||
89 | return (banner); | ||
90 | } | ||
91 | |||
92 | void | ||
93 | userauth_send_banner(const char *msg) | ||
94 | { | ||
95 | if (datafellows & SSH_BUG_BANNER) | ||
96 | return; | ||
97 | |||
98 | packet_start(SSH2_MSG_USERAUTH_BANNER); | ||
99 | packet_put_cstring(msg); | ||
100 | packet_put_cstring(""); /* language, unused */ | ||
101 | packet_send(); | ||
102 | debug("%s: sent", __func__); | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | userauth_banner(void) | ||
107 | { | ||
108 | char *banner = NULL; | ||
109 | |||
110 | if (options.banner == NULL || | ||
111 | strcasecmp(options.banner, "none") == 0 || | ||
112 | (datafellows & SSH_BUG_BANNER) != 0) | ||
113 | return; | ||
114 | |||
115 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) | ||
116 | goto done; | ||
117 | userauth_send_banner(banner); | ||
118 | |||
119 | done: | ||
120 | if (banner) | ||
121 | xfree(banner); | ||
122 | } | ||
123 | |||
124 | static int | 59 | static int |
125 | userauth_none(Authctxt *authctxt) | 60 | userauth_none(Authctxt *authctxt) |
126 | { | 61 | { |
127 | none_enabled = 0; | 62 | none_enabled = 0; |
128 | packet_check_eom(); | 63 | packet_check_eom(); |
129 | userauth_banner(); | ||
130 | #ifdef HAVE_CYGWIN | 64 | #ifdef HAVE_CYGWIN |
131 | if (check_nt_auth(1, authctxt->pw) == 0) | 65 | if (check_nt_auth(1, authctxt->pw) == 0) |
132 | return (0); | 66 | return (0); |
@@ -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 | |||