diff options
Diffstat (limited to 'auth2.c')
-rw-r--r-- | auth2.c | 106 |
1 files changed, 59 insertions, 47 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2.c,v 1.152 2019/01/19 21:31:32 djm Exp $ */ | 1 | /* $OpenBSD: auth2.c,v 1.153 2019/01/19 21:38:24 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -61,9 +61,6 @@ | |||
61 | #include "ssherr.h" | 61 | #include "ssherr.h" |
62 | #include "digest.h" | 62 | #include "digest.h" |
63 | 63 | ||
64 | #include "opacket.h" /* XXX */ | ||
65 | extern struct ssh *active_state; /* XXX */ | ||
66 | |||
67 | /* import */ | 64 | /* import */ |
68 | extern ServerOptions options; | 65 | extern ServerOptions options; |
69 | extern u_char *session_id2; | 66 | extern u_char *session_id2; |
@@ -141,18 +138,21 @@ auth2_read_banner(void) | |||
141 | return (banner); | 138 | return (banner); |
142 | } | 139 | } |
143 | 140 | ||
144 | void | 141 | static void |
145 | userauth_send_banner(const char *msg) | 142 | userauth_send_banner(struct ssh *ssh, const char *msg) |
146 | { | 143 | { |
147 | packet_start(SSH2_MSG_USERAUTH_BANNER); | 144 | int r; |
148 | packet_put_cstring(msg); | 145 | |
149 | packet_put_cstring(""); /* language, unused */ | 146 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 || |
150 | 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)); | ||
151 | debug("%s: sent", __func__); | 151 | debug("%s: sent", __func__); |
152 | } | 152 | } |
153 | 153 | ||
154 | static void | 154 | static void |
155 | userauth_banner(void) | 155 | userauth_banner(struct ssh *ssh) |
156 | { | 156 | { |
157 | char *banner = NULL; | 157 | char *banner = NULL; |
158 | 158 | ||
@@ -161,7 +161,7 @@ userauth_banner(void) | |||
161 | 161 | ||
162 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) | 162 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) |
163 | goto done; | 163 | goto done; |
164 | userauth_send_banner(banner); | 164 | userauth_send_banner(ssh, banner); |
165 | 165 | ||
166 | done: | 166 | done: |
167 | free(banner); | 167 | free(banner); |
@@ -171,10 +171,10 @@ done: | |||
171 | * loop until authctxt->success == TRUE | 171 | * loop until authctxt->success == TRUE |
172 | */ | 172 | */ |
173 | void | 173 | void |
174 | do_authentication2(Authctxt *authctxt) | 174 | do_authentication2(struct ssh *ssh) |
175 | { | 175 | { |
176 | struct ssh *ssh = active_state; /* XXX */ | 176 | Authctxt *authctxt = ssh->authctxt; |
177 | ssh->authctxt = authctxt; /* XXX move to caller */ | 177 | |
178 | ssh_dispatch_init(ssh, &dispatch_protocol_error); | 178 | ssh_dispatch_init(ssh, &dispatch_protocol_error); |
179 | ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); | 179 | ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); |
180 | ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); | 180 | ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); |
@@ -186,10 +186,12 @@ static int | |||
186 | input_service_request(int type, u_int32_t seq, struct ssh *ssh) | 186 | input_service_request(int type, u_int32_t seq, struct ssh *ssh) |
187 | { | 187 | { |
188 | Authctxt *authctxt = ssh->authctxt; | 188 | Authctxt *authctxt = ssh->authctxt; |
189 | u_int len; | 189 | char *service = NULL; |
190 | int acceptit = 0; | 190 | int r, acceptit = 0; |
191 | char *service = packet_get_cstring(&len); | 191 | |
192 | packet_check_eom(); | 192 | if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || |
193 | (r = sshpkt_get_end(ssh)) != 0) | ||
194 | goto out; | ||
193 | 195 | ||
194 | if (authctxt == NULL) | 196 | if (authctxt == NULL) |
195 | fatal("input_service_request: no authctxt"); | 197 | fatal("input_service_request: no authctxt"); |
@@ -198,20 +200,24 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh) | |||
198 | if (!authctxt->success) { | 200 | if (!authctxt->success) { |
199 | acceptit = 1; | 201 | acceptit = 1; |
200 | /* now we can handle user-auth requests */ | 202 | /* now we can handle user-auth requests */ |
201 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); | 203 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, |
204 | &input_userauth_request); | ||
202 | } | 205 | } |
203 | } | 206 | } |
204 | /* XXX all other service requests are denied */ | 207 | /* XXX all other service requests are denied */ |
205 | 208 | ||
206 | if (acceptit) { | 209 | if (acceptit) { |
207 | packet_start(SSH2_MSG_SERVICE_ACCEPT); | 210 | if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 || |
208 | packet_put_cstring(service); | 211 | (r = sshpkt_put_cstring(ssh, service)) != 0 || |
209 | packet_send(); | 212 | (r = sshpkt_send(ssh)) != 0 || |
210 | packet_write_wait(); | 213 | (r = ssh_packet_write_wait(ssh)) != 0) |
214 | goto out; | ||
211 | } else { | 215 | } else { |
212 | debug("bad service request %s", service); | 216 | debug("bad service request %s", service); |
213 | packet_disconnect("bad service request %s", service); | 217 | ssh_packet_disconnect(ssh, "bad service request %s", service); |
214 | } | 218 | } |
219 | r = 0; | ||
220 | out: | ||
215 | free(service); | 221 | free(service); |
216 | return 0; | 222 | return 0; |
217 | } | 223 | } |
@@ -259,16 +265,17 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
259 | { | 265 | { |
260 | Authctxt *authctxt = ssh->authctxt; | 266 | Authctxt *authctxt = ssh->authctxt; |
261 | Authmethod *m = NULL; | 267 | Authmethod *m = NULL; |
262 | char *user, *service, *method, *style = NULL; | 268 | char *user = NULL, *service = NULL, *method = NULL, *style = NULL; |
263 | int authenticated = 0; | 269 | int r, authenticated = 0; |
264 | double tstart = monotime_double(); | 270 | double tstart = monotime_double(); |
265 | 271 | ||
266 | if (authctxt == NULL) | 272 | if (authctxt == NULL) |
267 | fatal("input_userauth_request: no authctxt"); | 273 | fatal("input_userauth_request: no authctxt"); |
268 | 274 | ||
269 | user = packet_get_cstring(NULL); | 275 | if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 || |
270 | service = packet_get_cstring(NULL); | 276 | (r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || |
271 | method = packet_get_cstring(NULL); | 277 | (r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) |
278 | goto out; | ||
272 | 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); |
273 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); | 280 | debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
274 | 281 | ||
@@ -302,13 +309,14 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
302 | authctxt->style = style ? xstrdup(style) : NULL; | 309 | authctxt->style = style ? xstrdup(style) : NULL; |
303 | if (use_privsep) | 310 | if (use_privsep) |
304 | mm_inform_authserv(service, style); | 311 | mm_inform_authserv(service, style); |
305 | userauth_banner(); | 312 | userauth_banner(ssh); |
306 | if (auth2_setup_methods_lists(authctxt) != 0) | 313 | if (auth2_setup_methods_lists(authctxt) != 0) |
307 | packet_disconnect("no authentication methods enabled"); | 314 | ssh_packet_disconnect(ssh, |
315 | "no authentication methods enabled"); | ||
308 | } else if (strcmp(user, authctxt->user) != 0 || | 316 | } else if (strcmp(user, authctxt->user) != 0 || |
309 | strcmp(service, authctxt->service) != 0) { | 317 | strcmp(service, authctxt->service) != 0) { |
310 | packet_disconnect("Change of username or service not allowed: " | 318 | ssh_packet_disconnect(ssh, "Change of username or service " |
311 | "(%s,%s) -> (%s,%s)", | 319 | "not allowed: (%s,%s) -> (%s,%s)", |
312 | authctxt->user, authctxt->service, user, service); | 320 | authctxt->user, authctxt->service, user, service); |
313 | } | 321 | } |
314 | /* reset state */ | 322 | /* reset state */ |
@@ -334,11 +342,12 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) | |||
334 | ensure_minimum_time_since(tstart, | 342 | ensure_minimum_time_since(tstart, |
335 | user_specific_delay(authctxt->user)); | 343 | user_specific_delay(authctxt->user)); |
336 | userauth_finish(ssh, authenticated, method, NULL); | 344 | userauth_finish(ssh, authenticated, method, NULL); |
337 | 345 | r = 0; | |
346 | out: | ||
338 | free(service); | 347 | free(service); |
339 | free(user); | 348 | free(user); |
340 | free(method); | 349 | free(method); |
341 | return 0; | 350 | return r; |
342 | } | 351 | } |
343 | 352 | ||
344 | void | 353 | void |
@@ -347,7 +356,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, | |||
347 | { | 356 | { |
348 | Authctxt *authctxt = ssh->authctxt; | 357 | Authctxt *authctxt = ssh->authctxt; |
349 | char *methods; | 358 | char *methods; |
350 | int partial = 0; | 359 | int r, partial = 0; |
351 | 360 | ||
352 | if (!authctxt->valid && authenticated) | 361 | if (!authctxt->valid && authenticated) |
353 | fatal("INTERNAL ERROR: authenticated invalid user %s", | 362 | fatal("INTERNAL ERROR: authenticated invalid user %s", |
@@ -391,7 +400,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, | |||
391 | if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0) | 400 | if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0) |
392 | fatal("%s: buffer error: %s", | 401 | fatal("%s: buffer error: %s", |
393 | __func__, ssh_err(r)); | 402 | __func__, ssh_err(r)); |
394 | userauth_send_banner(sshbuf_ptr(loginmsg)); | 403 | userauth_send_banner(ssh, sshbuf_ptr(loginmsg)); |
395 | packet_write_wait(); | 404 | packet_write_wait(); |
396 | } | 405 | } |
397 | fatal("Access denied for user %s by PAM account " | 406 | fatal("Access denied for user %s by PAM account " |
@@ -402,10 +411,12 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, | |||
402 | 411 | ||
403 | if (authenticated == 1) { | 412 | if (authenticated == 1) { |
404 | /* turn off userauth */ | 413 | /* turn off userauth */ |
405 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); | 414 | ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, |
406 | packet_start(SSH2_MSG_USERAUTH_SUCCESS); | 415 | &dispatch_protocol_ignore); |
407 | packet_send(); | 416 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 || |
408 | packet_write_wait(); | 417 | (r = sshpkt_send(ssh)) != 0 || |
418 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
419 | fatal("%s: %s", __func__, ssh_err(r)); | ||
409 | /* now we can break out */ | 420 | /* now we can break out */ |
410 | authctxt->success = 1; | 421 | authctxt->success = 1; |
411 | ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); | 422 | ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
@@ -423,11 +434,12 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, | |||
423 | methods = authmethods_get(authctxt); | 434 | methods = authmethods_get(authctxt); |
424 | debug3("%s: failure partial=%d next methods=\"%s\"", __func__, | 435 | debug3("%s: failure partial=%d next methods=\"%s\"", __func__, |
425 | partial, methods); | 436 | partial, methods); |
426 | packet_start(SSH2_MSG_USERAUTH_FAILURE); | 437 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 || |
427 | packet_put_cstring(methods); | 438 | (r = sshpkt_put_cstring(ssh, methods)) != 0 || |
428 | packet_put_char(partial); | 439 | (r = sshpkt_put_u8(ssh, partial)) != 0 || |
429 | packet_send(); | 440 | (r = sshpkt_send(ssh)) != 0 || |
430 | packet_write_wait(); | 441 | (r = ssh_packet_write_wait(ssh)) != 0) |
442 | fatal("%s: %s", __func__, ssh_err(r)); | ||
431 | free(methods); | 443 | free(methods); |
432 | } | 444 | } |
433 | } | 445 | } |