summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2019-06-05 06:41:44 +0100
committerColin Watson <cjwatson@debian.org>2019-06-05 06:41:44 +0100
commit102062f825fb26a74295a1c089c00c4c4c76b68a (patch)
tree3db66bc8c8483cce66516dff36f6ef56065143d9 /auth2.c
parent3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff)
parentfd0fa130ecf06d7d092932adcd5d77f1549bfc8d (diff)
Import openssh_8.0p1.orig.tar.gz
Diffstat (limited to 'auth2.c')
-rw-r--r--auth2.c131
1 files changed, 79 insertions, 52 deletions
diff --git a/auth2.c b/auth2.c
index 4d19957a6..16ae1a363 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.149 2018/07/11 18:53:29 markus Exp $ */ 1/* $OpenBSD: auth2.c,v 1.155 2019/03/25 22:34:52 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -35,6 +35,7 @@
35#include <stdarg.h> 35#include <stdarg.h>
36#include <string.h> 36#include <string.h>
37#include <unistd.h> 37#include <unistd.h>
38#include <time.h>
38 39
39#include "atomicio.h" 40#include "atomicio.h"
40#include "xmalloc.h" 41#include "xmalloc.h"
@@ -137,18 +138,21 @@ auth2_read_banner(void)
137 return (banner); 138 return (banner);
138} 139}
139 140
140void 141static void
141userauth_send_banner(const char *msg) 142userauth_send_banner(struct ssh *ssh, const char *msg)
142{ 143{
143 packet_start(SSH2_MSG_USERAUTH_BANNER); 144 int r;
144 packet_put_cstring(msg); 145
145 packet_put_cstring(""); /* language, unused */ 146 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
146 packet_send(); 147 (r = sshpkt_put_cstring(ssh, msg)) != 0 ||
148 (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */
149 (r = sshpkt_send(ssh)) != 0)
150 fatal("%s: %s", __func__, ssh_err(r));
147 debug("%s: sent", __func__); 151 debug("%s: sent", __func__);
148} 152}
149 153
150static void 154static void
151userauth_banner(void) 155userauth_banner(struct ssh *ssh)
152{ 156{
153 char *banner = NULL; 157 char *banner = NULL;
154 158
@@ -157,7 +161,7 @@ userauth_banner(void)
157 161
158 if ((banner = PRIVSEP(auth2_read_banner())) == NULL) 162 if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
159 goto done; 163 goto done;
160 userauth_send_banner(banner); 164 userauth_send_banner(ssh, banner);
161 165
162done: 166done:
163 free(banner); 167 free(banner);
@@ -167,10 +171,10 @@ done:
167 * loop until authctxt->success == TRUE 171 * loop until authctxt->success == TRUE
168 */ 172 */
169void 173void
170do_authentication2(Authctxt *authctxt) 174do_authentication2(struct ssh *ssh)
171{ 175{
172 struct ssh *ssh = active_state; /* XXX */ 176 Authctxt *authctxt = ssh->authctxt;
173 ssh->authctxt = authctxt; /* XXX move to caller */ 177
174 ssh_dispatch_init(ssh, &dispatch_protocol_error); 178 ssh_dispatch_init(ssh, &dispatch_protocol_error);
175 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); 179 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
176 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); 180 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
@@ -182,10 +186,12 @@ static int
182input_service_request(int type, u_int32_t seq, struct ssh *ssh) 186input_service_request(int type, u_int32_t seq, struct ssh *ssh)
183{ 187{
184 Authctxt *authctxt = ssh->authctxt; 188 Authctxt *authctxt = ssh->authctxt;
185 u_int len; 189 char *service = NULL;
186 int acceptit = 0; 190 int r, acceptit = 0;
187 char *service = packet_get_cstring(&len); 191
188 packet_check_eom(); 192 if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
193 (r = sshpkt_get_end(ssh)) != 0)
194 goto out;
189 195
190 if (authctxt == NULL) 196 if (authctxt == NULL)
191 fatal("input_service_request: no authctxt"); 197 fatal("input_service_request: no authctxt");
@@ -194,20 +200,24 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
194 if (!authctxt->success) { 200 if (!authctxt->success) {
195 acceptit = 1; 201 acceptit = 1;
196 /* now we can handle user-auth requests */ 202 /* now we can handle user-auth requests */
197 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); 203 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
204 &input_userauth_request);
198 } 205 }
199 } 206 }
200 /* XXX all other service requests are denied */ 207 /* XXX all other service requests are denied */
201 208
202 if (acceptit) { 209 if (acceptit) {
203 packet_start(SSH2_MSG_SERVICE_ACCEPT); 210 if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 ||
204 packet_put_cstring(service); 211 (r = sshpkt_put_cstring(ssh, service)) != 0 ||
205 packet_send(); 212 (r = sshpkt_send(ssh)) != 0 ||
206 packet_write_wait(); 213 (r = ssh_packet_write_wait(ssh)) != 0)
214 goto out;
207 } else { 215 } else {
208 debug("bad service request %s", service); 216 debug("bad service request %s", service);
209 packet_disconnect("bad service request %s", service); 217 ssh_packet_disconnect(ssh, "bad service request %s", service);
210 } 218 }
219 r = 0;
220 out:
211 free(service); 221 free(service);
212 return 0; 222 return 0;
213} 223}
@@ -255,16 +265,17 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
255{ 265{
256 Authctxt *authctxt = ssh->authctxt; 266 Authctxt *authctxt = ssh->authctxt;
257 Authmethod *m = NULL; 267 Authmethod *m = NULL;
258 char *user, *service, *method, *style = NULL; 268 char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
259 int authenticated = 0; 269 int r, authenticated = 0;
260 double tstart = monotime_double(); 270 double tstart = monotime_double();
261 271
262 if (authctxt == NULL) 272 if (authctxt == NULL)
263 fatal("input_userauth_request: no authctxt"); 273 fatal("input_userauth_request: no authctxt");
264 274
265 user = packet_get_cstring(NULL); 275 if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 ||
266 service = packet_get_cstring(NULL); 276 (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
267 method = packet_get_cstring(NULL); 277 (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
278 goto out;
268 debug("userauth-request for user %s service %s method %s", user, service, method); 279 debug("userauth-request for user %s service %s method %s", user, service, method);
269 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 280 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
270 281
@@ -273,7 +284,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
273 284
274 if (authctxt->attempt++ == 0) { 285 if (authctxt->attempt++ == 0) {
275 /* setup auth context */ 286 /* setup auth context */
276 authctxt->pw = PRIVSEP(getpwnamallow(user)); 287 authctxt->pw = PRIVSEP(getpwnamallow(ssh, user));
277 authctxt->user = xstrdup(user); 288 authctxt->user = xstrdup(user);
278 if (authctxt->pw && strcmp(service, "ssh-connection")==0) { 289 if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
279 authctxt->valid = 1; 290 authctxt->valid = 1;
@@ -283,12 +294,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
283 /* Invalid user, fake password information */ 294 /* Invalid user, fake password information */
284 authctxt->pw = fakepw(); 295 authctxt->pw = fakepw();
285#ifdef SSH_AUDIT_EVENTS 296#ifdef SSH_AUDIT_EVENTS
286 PRIVSEP(audit_event(SSH_INVALID_USER)); 297 PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
287#endif 298#endif
288 } 299 }
289#ifdef USE_PAM 300#ifdef USE_PAM
290 if (options.use_pam) 301 if (options.use_pam)
291 PRIVSEP(start_pam(authctxt)); 302 PRIVSEP(start_pam(ssh));
292#endif 303#endif
293 ssh_packet_set_log_preamble(ssh, "%suser %s", 304 ssh_packet_set_log_preamble(ssh, "%suser %s",
294 authctxt->valid ? "authenticating " : "invalid ", user); 305 authctxt->valid ? "authenticating " : "invalid ", user);
@@ -298,13 +309,14 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
298 authctxt->style = style ? xstrdup(style) : NULL; 309 authctxt->style = style ? xstrdup(style) : NULL;
299 if (use_privsep) 310 if (use_privsep)
300 mm_inform_authserv(service, style); 311 mm_inform_authserv(service, style);
301 userauth_banner(); 312 userauth_banner(ssh);
302 if (auth2_setup_methods_lists(authctxt) != 0) 313 if (auth2_setup_methods_lists(authctxt) != 0)
303 packet_disconnect("no authentication methods enabled"); 314 ssh_packet_disconnect(ssh,
315 "no authentication methods enabled");
304 } else if (strcmp(user, authctxt->user) != 0 || 316 } else if (strcmp(user, authctxt->user) != 0 ||
305 strcmp(service, authctxt->service) != 0) { 317 strcmp(service, authctxt->service) != 0) {
306 packet_disconnect("Change of username or service not allowed: " 318 ssh_packet_disconnect(ssh, "Change of username or service "
307 "(%s,%s) -> (%s,%s)", 319 "not allowed: (%s,%s) -> (%s,%s)",
308 authctxt->user, authctxt->service, user, service); 320 authctxt->user, authctxt->service, user, service);
309 } 321 }
310 /* reset state */ 322 /* reset state */
@@ -330,11 +342,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
330 ensure_minimum_time_since(tstart, 342 ensure_minimum_time_since(tstart,
331 user_specific_delay(authctxt->user)); 343 user_specific_delay(authctxt->user));
332 userauth_finish(ssh, authenticated, method, NULL); 344 userauth_finish(ssh, authenticated, method, NULL);
333 345 r = 0;
346 out:
334 free(service); 347 free(service);
335 free(user); 348 free(user);
336 free(method); 349 free(method);
337 return 0; 350 return r;
338} 351}
339 352
340void 353void
@@ -343,7 +356,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
343{ 356{
344 Authctxt *authctxt = ssh->authctxt; 357 Authctxt *authctxt = ssh->authctxt;
345 char *methods; 358 char *methods;
346 int partial = 0; 359 int r, partial = 0;
347 360
348 if (!authctxt->valid && authenticated) 361 if (!authctxt->valid && authenticated)
349 fatal("INTERNAL ERROR: authenticated invalid user %s", 362 fatal("INTERNAL ERROR: authenticated invalid user %s",
@@ -356,7 +369,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
356 !auth_root_allowed(ssh, method)) { 369 !auth_root_allowed(ssh, method)) {
357 authenticated = 0; 370 authenticated = 0;
358#ifdef SSH_AUDIT_EVENTS 371#ifdef SSH_AUDIT_EVENTS
359 PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 372 PRIVSEP(audit_event(ssh, SSH_LOGIN_ROOT_DENIED));
360#endif 373#endif
361 } 374 }
362 375
@@ -368,7 +381,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
368 } 381 }
369 382
370 /* Log before sending the reply */ 383 /* Log before sending the reply */
371 auth_log(authctxt, authenticated, partial, method, submethod); 384 auth_log(ssh, authenticated, partial, method, submethod);
372 385
373 /* Update information exposed to session */ 386 /* Update information exposed to session */
374 if (authenticated || partial) 387 if (authenticated || partial)
@@ -387,8 +400,11 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
387 if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0) 400 if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
388 fatal("%s: buffer error: %s", 401 fatal("%s: buffer error: %s",
389 __func__, ssh_err(r)); 402 __func__, ssh_err(r));
390 userauth_send_banner(sshbuf_ptr(loginmsg)); 403 userauth_send_banner(ssh, sshbuf_ptr(loginmsg));
391 packet_write_wait(); 404 if ((r = ssh_packet_write_wait(ssh)) != 0) {
405 sshpkt_fatal(ssh, r,
406 "%s: send PAM banner", __func__);
407 }
392 } 408 }
393 fatal("Access denied for user %s by PAM account " 409 fatal("Access denied for user %s by PAM account "
394 "configuration", authctxt->user); 410 "configuration", authctxt->user);
@@ -398,10 +414,12 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
398 414
399 if (authenticated == 1) { 415 if (authenticated == 1) {
400 /* turn off userauth */ 416 /* turn off userauth */
401 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); 417 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
402 packet_start(SSH2_MSG_USERAUTH_SUCCESS); 418 &dispatch_protocol_ignore);
403 packet_send(); 419 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 ||
404 packet_write_wait(); 420 (r = sshpkt_send(ssh)) != 0 ||
421 (r = ssh_packet_write_wait(ssh)) != 0)
422 fatal("%s: %s", __func__, ssh_err(r));
405 /* now we can break out */ 423 /* now we can break out */
406 authctxt->success = 1; 424 authctxt->success = 1;
407 ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); 425 ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
@@ -412,18 +430,19 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
412 authctxt->failures++; 430 authctxt->failures++;
413 if (authctxt->failures >= options.max_authtries) { 431 if (authctxt->failures >= options.max_authtries) {
414#ifdef SSH_AUDIT_EVENTS 432#ifdef SSH_AUDIT_EVENTS
415 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 433 PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES));
416#endif 434#endif
417 auth_maxtries_exceeded(authctxt); 435 auth_maxtries_exceeded(ssh);
418 } 436 }
419 methods = authmethods_get(authctxt); 437 methods = authmethods_get(authctxt);
420 debug3("%s: failure partial=%d next methods=\"%s\"", __func__, 438 debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
421 partial, methods); 439 partial, methods);
422 packet_start(SSH2_MSG_USERAUTH_FAILURE); 440 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 ||
423 packet_put_cstring(methods); 441 (r = sshpkt_put_cstring(ssh, methods)) != 0 ||
424 packet_put_char(partial); 442 (r = sshpkt_put_u8(ssh, partial)) != 0 ||
425 packet_send(); 443 (r = sshpkt_send(ssh)) != 0 ||
426 packet_write_wait(); 444 (r = ssh_packet_write_wait(ssh)) != 0)
445 fatal("%s: %s", __func__, ssh_err(r));
427 free(methods); 446 free(methods);
428 } 447 }
429} 448}
@@ -558,6 +577,14 @@ auth2_setup_methods_lists(Authctxt *authctxt)
558{ 577{
559 u_int i; 578 u_int i;
560 579
580 /* First, normalise away the "any" pseudo-method */
581 if (options.num_auth_methods == 1 &&
582 strcmp(options.auth_methods[0], "any") == 0) {
583 free(options.auth_methods[0]);
584 options.auth_methods[0] = NULL;
585 options.num_auth_methods = 0;
586 }
587
561 if (options.num_auth_methods == 0) 588 if (options.num_auth_methods == 0)
562 return 0; 589 return 0;
563 debug3("%s: checking methods", __func__); 590 debug3("%s: checking methods", __func__);