summaryrefslogtreecommitdiff
path: root/auth2.c
diff options
context:
space:
mode:
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 3035926ba..d60e7f1f2 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"
@@ -139,18 +140,21 @@ auth2_read_banner(void)
139 return (banner); 140 return (banner);
140} 141}
141 142
142void 143static void
143userauth_send_banner(const char *msg) 144userauth_send_banner(struct ssh *ssh, const char *msg)
144{ 145{
145 packet_start(SSH2_MSG_USERAUTH_BANNER); 146 int r;
146 packet_put_cstring(msg); 147
147 packet_put_cstring(""); /* language, unused */ 148 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
148 packet_send(); 149 (r = sshpkt_put_cstring(ssh, msg)) != 0 ||
150 (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */
151 (r = sshpkt_send(ssh)) != 0)
152 fatal("%s: %s", __func__, ssh_err(r));
149 debug("%s: sent", __func__); 153 debug("%s: sent", __func__);
150} 154}
151 155
152static void 156static void
153userauth_banner(void) 157userauth_banner(struct ssh *ssh)
154{ 158{
155 char *banner = NULL; 159 char *banner = NULL;
156 160
@@ -159,7 +163,7 @@ userauth_banner(void)
159 163
160 if ((banner = PRIVSEP(auth2_read_banner())) == NULL) 164 if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
161 goto done; 165 goto done;
162 userauth_send_banner(banner); 166 userauth_send_banner(ssh, banner);
163 167
164done: 168done:
165 free(banner); 169 free(banner);
@@ -169,10 +173,10 @@ done:
169 * loop until authctxt->success == TRUE 173 * loop until authctxt->success == TRUE
170 */ 174 */
171void 175void
172do_authentication2(Authctxt *authctxt) 176do_authentication2(struct ssh *ssh)
173{ 177{
174 struct ssh *ssh = active_state; /* XXX */ 178 Authctxt *authctxt = ssh->authctxt;
175 ssh->authctxt = authctxt; /* XXX move to caller */ 179
176 ssh_dispatch_init(ssh, &dispatch_protocol_error); 180 ssh_dispatch_init(ssh, &dispatch_protocol_error);
177 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); 181 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
178 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); 182 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
@@ -184,10 +188,12 @@ static int
184input_service_request(int type, u_int32_t seq, struct ssh *ssh) 188input_service_request(int type, u_int32_t seq, struct ssh *ssh)
185{ 189{
186 Authctxt *authctxt = ssh->authctxt; 190 Authctxt *authctxt = ssh->authctxt;
187 u_int len; 191 char *service = NULL;
188 int acceptit = 0; 192 int r, acceptit = 0;
189 char *service = packet_get_cstring(&len); 193
190 packet_check_eom(); 194 if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
195 (r = sshpkt_get_end(ssh)) != 0)
196 goto out;
191 197
192 if (authctxt == NULL) 198 if (authctxt == NULL)
193 fatal("input_service_request: no authctxt"); 199 fatal("input_service_request: no authctxt");
@@ -196,20 +202,24 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
196 if (!authctxt->success) { 202 if (!authctxt->success) {
197 acceptit = 1; 203 acceptit = 1;
198 /* now we can handle user-auth requests */ 204 /* now we can handle user-auth requests */
199 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); 205 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
206 &input_userauth_request);
200 } 207 }
201 } 208 }
202 /* XXX all other service requests are denied */ 209 /* XXX all other service requests are denied */
203 210
204 if (acceptit) { 211 if (acceptit) {
205 packet_start(SSH2_MSG_SERVICE_ACCEPT); 212 if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 ||
206 packet_put_cstring(service); 213 (r = sshpkt_put_cstring(ssh, service)) != 0 ||
207 packet_send(); 214 (r = sshpkt_send(ssh)) != 0 ||
208 packet_write_wait(); 215 (r = ssh_packet_write_wait(ssh)) != 0)
216 goto out;
209 } else { 217 } else {
210 debug("bad service request %s", service); 218 debug("bad service request %s", service);
211 packet_disconnect("bad service request %s", service); 219 ssh_packet_disconnect(ssh, "bad service request %s", service);
212 } 220 }
221 r = 0;
222 out:
213 free(service); 223 free(service);
214 return 0; 224 return 0;
215} 225}
@@ -257,16 +267,17 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
257{ 267{
258 Authctxt *authctxt = ssh->authctxt; 268 Authctxt *authctxt = ssh->authctxt;
259 Authmethod *m = NULL; 269 Authmethod *m = NULL;
260 char *user, *service, *method, *style = NULL, *role = NULL; 270 char *user = NULL, *service = NULL, *method = NULL, *style = NULL, *role = NULL;
261 int authenticated = 0; 271 int r, authenticated = 0;
262 double tstart = monotime_double(); 272 double tstart = monotime_double();
263 273
264 if (authctxt == NULL) 274 if (authctxt == NULL)
265 fatal("input_userauth_request: no authctxt"); 275 fatal("input_userauth_request: no authctxt");
266 276
267 user = packet_get_cstring(NULL); 277 if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 ||
268 service = packet_get_cstring(NULL); 278 (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
269 method = packet_get_cstring(NULL); 279 (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
280 goto out;
270 debug("userauth-request for user %s service %s method %s", user, service, method); 281 debug("userauth-request for user %s service %s method %s", user, service, method);
271 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); 282 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
272 283
@@ -280,7 +291,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
280 291
281 if (authctxt->attempt++ == 0) { 292 if (authctxt->attempt++ == 0) {
282 /* setup auth context */ 293 /* setup auth context */
283 authctxt->pw = PRIVSEP(getpwnamallow(user)); 294 authctxt->pw = PRIVSEP(getpwnamallow(ssh, user));
284 authctxt->user = xstrdup(user); 295 authctxt->user = xstrdup(user);
285 if (authctxt->pw && strcmp(service, "ssh-connection")==0) { 296 if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
286 authctxt->valid = 1; 297 authctxt->valid = 1;
@@ -290,12 +301,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
290 /* Invalid user, fake password information */ 301 /* Invalid user, fake password information */
291 authctxt->pw = fakepw(); 302 authctxt->pw = fakepw();
292#ifdef SSH_AUDIT_EVENTS 303#ifdef SSH_AUDIT_EVENTS
293 PRIVSEP(audit_event(SSH_INVALID_USER)); 304 PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
294#endif 305#endif
295 } 306 }
296#ifdef USE_PAM 307#ifdef USE_PAM
297 if (options.use_pam) 308 if (options.use_pam)
298 PRIVSEP(start_pam(authctxt)); 309 PRIVSEP(start_pam(ssh));
299#endif 310#endif
300 ssh_packet_set_log_preamble(ssh, "%suser %s", 311 ssh_packet_set_log_preamble(ssh, "%suser %s",
301 authctxt->valid ? "authenticating " : "invalid ", user); 312 authctxt->valid ? "authenticating " : "invalid ", user);
@@ -306,13 +317,14 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
306 authctxt->role = role ? xstrdup(role) : NULL; 317 authctxt->role = role ? xstrdup(role) : NULL;
307 if (use_privsep) 318 if (use_privsep)
308 mm_inform_authserv(service, style, role); 319 mm_inform_authserv(service, style, role);
309 userauth_banner(); 320 userauth_banner(ssh);
310 if (auth2_setup_methods_lists(authctxt) != 0) 321 if (auth2_setup_methods_lists(authctxt) != 0)
311 packet_disconnect("no authentication methods enabled"); 322 ssh_packet_disconnect(ssh,
323 "no authentication methods enabled");
312 } else if (strcmp(user, authctxt->user) != 0 || 324 } else if (strcmp(user, authctxt->user) != 0 ||
313 strcmp(service, authctxt->service) != 0) { 325 strcmp(service, authctxt->service) != 0) {
314 packet_disconnect("Change of username or service not allowed: " 326 ssh_packet_disconnect(ssh, "Change of username or service "
315 "(%s,%s) -> (%s,%s)", 327 "not allowed: (%s,%s) -> (%s,%s)",
316 authctxt->user, authctxt->service, user, service); 328 authctxt->user, authctxt->service, user, service);
317 } 329 }
318 /* reset state */ 330 /* reset state */
@@ -338,11 +350,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
338 ensure_minimum_time_since(tstart, 350 ensure_minimum_time_since(tstart,
339 user_specific_delay(authctxt->user)); 351 user_specific_delay(authctxt->user));
340 userauth_finish(ssh, authenticated, method, NULL); 352 userauth_finish(ssh, authenticated, method, NULL);
341 353 r = 0;
354 out:
342 free(service); 355 free(service);
343 free(user); 356 free(user);
344 free(method); 357 free(method);
345 return 0; 358 return r;
346} 359}
347 360
348void 361void
@@ -351,7 +364,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
351{ 364{
352 Authctxt *authctxt = ssh->authctxt; 365 Authctxt *authctxt = ssh->authctxt;
353 char *methods; 366 char *methods;
354 int partial = 0; 367 int r, partial = 0;
355 368
356 if (!authctxt->valid && authenticated) 369 if (!authctxt->valid && authenticated)
357 fatal("INTERNAL ERROR: authenticated invalid user %s", 370 fatal("INTERNAL ERROR: authenticated invalid user %s",
@@ -364,7 +377,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
364 !auth_root_allowed(ssh, method)) { 377 !auth_root_allowed(ssh, method)) {
365 authenticated = 0; 378 authenticated = 0;
366#ifdef SSH_AUDIT_EVENTS 379#ifdef SSH_AUDIT_EVENTS
367 PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); 380 PRIVSEP(audit_event(ssh, SSH_LOGIN_ROOT_DENIED));
368#endif 381#endif
369 } 382 }
370 383
@@ -376,7 +389,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
376 } 389 }
377 390
378 /* Log before sending the reply */ 391 /* Log before sending the reply */
379 auth_log(authctxt, authenticated, partial, method, submethod); 392 auth_log(ssh, authenticated, partial, method, submethod);
380 393
381 /* Update information exposed to session */ 394 /* Update information exposed to session */
382 if (authenticated || partial) 395 if (authenticated || partial)
@@ -395,8 +408,11 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
395 if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0) 408 if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
396 fatal("%s: buffer error: %s", 409 fatal("%s: buffer error: %s",
397 __func__, ssh_err(r)); 410 __func__, ssh_err(r));
398 userauth_send_banner(sshbuf_ptr(loginmsg)); 411 userauth_send_banner(ssh, sshbuf_ptr(loginmsg));
399 packet_write_wait(); 412 if ((r = ssh_packet_write_wait(ssh)) != 0) {
413 sshpkt_fatal(ssh, r,
414 "%s: send PAM banner", __func__);
415 }
400 } 416 }
401 fatal("Access denied for user %s by PAM account " 417 fatal("Access denied for user %s by PAM account "
402 "configuration", authctxt->user); 418 "configuration", authctxt->user);
@@ -406,10 +422,12 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
406 422
407 if (authenticated == 1) { 423 if (authenticated == 1) {
408 /* turn off userauth */ 424 /* turn off userauth */
409 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); 425 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
410 packet_start(SSH2_MSG_USERAUTH_SUCCESS); 426 &dispatch_protocol_ignore);
411 packet_send(); 427 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 ||
412 packet_write_wait(); 428 (r = sshpkt_send(ssh)) != 0 ||
429 (r = ssh_packet_write_wait(ssh)) != 0)
430 fatal("%s: %s", __func__, ssh_err(r));
413 /* now we can break out */ 431 /* now we can break out */
414 authctxt->success = 1; 432 authctxt->success = 1;
415 ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); 433 ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
@@ -420,18 +438,19 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method,
420 authctxt->failures++; 438 authctxt->failures++;
421 if (authctxt->failures >= options.max_authtries) { 439 if (authctxt->failures >= options.max_authtries) {
422#ifdef SSH_AUDIT_EVENTS 440#ifdef SSH_AUDIT_EVENTS
423 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); 441 PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES));
424#endif 442#endif
425 auth_maxtries_exceeded(authctxt); 443 auth_maxtries_exceeded(ssh);
426 } 444 }
427 methods = authmethods_get(authctxt); 445 methods = authmethods_get(authctxt);
428 debug3("%s: failure partial=%d next methods=\"%s\"", __func__, 446 debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
429 partial, methods); 447 partial, methods);
430 packet_start(SSH2_MSG_USERAUTH_FAILURE); 448 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 ||
431 packet_put_cstring(methods); 449 (r = sshpkt_put_cstring(ssh, methods)) != 0 ||
432 packet_put_char(partial); 450 (r = sshpkt_put_u8(ssh, partial)) != 0 ||
433 packet_send(); 451 (r = sshpkt_send(ssh)) != 0 ||
434 packet_write_wait(); 452 (r = ssh_packet_write_wait(ssh)) != 0)
453 fatal("%s: %s", __func__, ssh_err(r));
435 free(methods); 454 free(methods);
436 } 455 }
437} 456}
@@ -566,6 +585,14 @@ auth2_setup_methods_lists(Authctxt *authctxt)
566{ 585{
567 u_int i; 586 u_int i;
568 587
588 /* First, normalise away the "any" pseudo-method */
589 if (options.num_auth_methods == 1 &&
590 strcmp(options.auth_methods[0], "any") == 0) {
591 free(options.auth_methods[0]);
592 options.auth_methods[0] = NULL;
593 options.num_auth_methods = 0;
594 }
595
569 if (options.num_auth_methods == 0) 596 if (options.num_auth_methods == 0)
570 return 0; 597 return 0;
571 debug3("%s: checking methods", __func__); 598 debug3("%s: checking methods", __func__);